From 689776275b8ef6d3e5046879ce0913515cb574f4 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Mon, 30 Sep 2024 23:51:24 +0000 Subject: [PATCH] Refactor GitClient for scope handling and add diff method with filters --- docs/genaisrc/genaiscript.d.ts | 19 +++++- genaisrc/genaiscript.d.ts | 19 +++++- packages/auto/genaiscript.d.ts | 19 +++++- packages/core/src/genaisrc/genaiscript.d.ts | 19 +++++- packages/core/src/git.ts | 64 ++++++++++++++++--- packages/core/src/types/prompt_template.d.ts | 19 +++++- .../sample/genaisrc/blog/genaiscript.d.ts | 19 +++++- packages/sample/genaisrc/genaiscript.d.ts | 19 +++++- .../sample/genaisrc/node/genaiscript.d.ts | 19 +++++- .../sample/genaisrc/python/genaiscript.d.ts | 19 +++++- .../sample/genaisrc/style/genaiscript.d.ts | 19 +++++- packages/sample/src/aici/genaiscript.d.ts | 19 +++++- packages/sample/src/errors/genaiscript.d.ts | 19 +++++- packages/sample/src/genaiscript.d.ts | 19 +++++- packages/sample/src/makecode/genaiscript.d.ts | 19 +++++- packages/sample/src/tla/genaiscript.d.ts | 19 +++++- packages/sample/src/vision/genaiscript.d.ts | 19 +++++- packages/vscode/genaisrc/gcm.genai.mts | 26 ++------ packages/vscode/genaisrc/genaiscript.d.ts | 19 +++++- slides/genaisrc/genaiscript.d.ts | 19 +++++- 20 files changed, 386 insertions(+), 46 deletions(-) diff --git a/docs/genaisrc/genaiscript.d.ts b/docs/genaisrc/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/docs/genaisrc/genaiscript.d.ts +++ b/docs/genaisrc/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/genaisrc/genaiscript.d.ts b/genaisrc/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/genaisrc/genaiscript.d.ts +++ b/genaisrc/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/auto/genaiscript.d.ts b/packages/auto/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/auto/genaiscript.d.ts +++ b/packages/auto/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/core/src/genaisrc/genaiscript.d.ts b/packages/core/src/genaisrc/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/core/src/genaisrc/genaiscript.d.ts +++ b/packages/core/src/genaisrc/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/core/src/git.ts b/packages/core/src/git.ts index 1109379616..c8c23a5add 100644 --- a/packages/core/src/git.ts +++ b/packages/core/src/git.ts @@ -37,7 +37,7 @@ export class GitClient implements Git { } async findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray @@ -49,18 +49,13 @@ export class GitClient implements Git { (f) => !!f ) let filenames: string[] - if (scope === "branch" || scope === "staged") { + if (scope === "base" || scope === "staged") { const args = ["diff", "--name-only", "--diff-filter=AM"] - if (scope === "branch") { + if (scope === "base") { const base = options?.base || (await this.defaultBranch()) args.push(base) } else args.push("--cached") - if (paths.length > 0 || excludedPaths.length > 0) { - if (!paths.length) paths.push(".") - args.push("--") - args.push(...paths) - args.push(...excludedPaths.map((p) => ":!" + p)) - } + GitClient.addFileFilters(paths, excludedPaths, args) const res = await this.exec(args, { label: `git list modified files in ${scope}`, }) @@ -88,4 +83,55 @@ export class GitClient implements Git { await resolveFileContents(files) return files } + + private static addFileFilters( + paths: string[], + excludedPaths: string[], + args: string[] + ) { + if (paths.length > 0 || excludedPaths.length > 0) { + if (!paths.length) paths.push(".") + args.push("--") + args.push(...paths) + args.push(...excludedPaths.map((p) => ":!" + p)) + } + } + + async diff(options?: { + staged?: boolean + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise { + const paths = arrayify(options?.paths).filter((f) => !!f) + const excludedPaths = arrayify(options?.excludedPaths).filter( + (f) => !!f + ) + let { staged, base, head, unified, askStageOnEmpty } = options || {} + const args = ["diff"] + if (staged) args.push("--staged") + args.push("--ignore-all-space") + if (unified > 0) args.push(`--unified=${unified}`) + if (base && !head) head = "head" + if (head && !base) base = head + "^" + if (base && head) args.push(`${base}..${head}`) + GitClient.addFileFilters(paths, excludedPaths, args) + let res = await this.exec(args) + if (!res && staged && askStageOnEmpty) { + const stage = await host.confirm( + "No staged changes. Stage all changes?", + { + default: true, + } + ) + if (stage) { + await this.exec(["add", "."]) + res = await this.diff(options) + } + } + return res + } } diff --git a/packages/core/src/types/prompt_template.d.ts b/packages/core/src/types/prompt_template.d.ts index fd1642537b..ffa66946e5 100644 --- a/packages/core/src/types/prompt_template.d.ts +++ b/packages/core/src/types/prompt_template.d.ts @@ -1291,13 +1291,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/genaisrc/blog/genaiscript.d.ts b/packages/sample/genaisrc/blog/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/genaisrc/blog/genaiscript.d.ts +++ b/packages/sample/genaisrc/blog/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/genaisrc/genaiscript.d.ts b/packages/sample/genaisrc/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/genaisrc/genaiscript.d.ts +++ b/packages/sample/genaisrc/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/genaisrc/node/genaiscript.d.ts b/packages/sample/genaisrc/node/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/genaisrc/node/genaiscript.d.ts +++ b/packages/sample/genaisrc/node/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/genaisrc/python/genaiscript.d.ts b/packages/sample/genaisrc/python/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/genaisrc/python/genaiscript.d.ts +++ b/packages/sample/genaisrc/python/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/genaisrc/style/genaiscript.d.ts b/packages/sample/genaisrc/style/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/genaisrc/style/genaiscript.d.ts +++ b/packages/sample/genaisrc/style/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/src/aici/genaiscript.d.ts b/packages/sample/src/aici/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/src/aici/genaiscript.d.ts +++ b/packages/sample/src/aici/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/src/errors/genaiscript.d.ts b/packages/sample/src/errors/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/src/errors/genaiscript.d.ts +++ b/packages/sample/src/errors/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/src/genaiscript.d.ts b/packages/sample/src/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/src/genaiscript.d.ts +++ b/packages/sample/src/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/src/makecode/genaiscript.d.ts b/packages/sample/src/makecode/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/src/makecode/genaiscript.d.ts +++ b/packages/sample/src/makecode/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/src/tla/genaiscript.d.ts b/packages/sample/src/tla/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/src/tla/genaiscript.d.ts +++ b/packages/sample/src/tla/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/sample/src/vision/genaiscript.d.ts b/packages/sample/src/vision/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/sample/src/vision/genaiscript.d.ts +++ b/packages/sample/src/vision/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/packages/vscode/genaisrc/gcm.genai.mts b/packages/vscode/genaisrc/gcm.genai.mts index e1ebd1197a..de8eb9f664 100644 --- a/packages/vscode/genaisrc/gcm.genai.mts +++ b/packages/vscode/genaisrc/gcm.genai.mts @@ -6,28 +6,16 @@ script({ description: "Generate a commit message for all staged changes", }) -// TODO: update this diff command to match your workspace -const diffCmd = "git diff --cached -- . :!**/genaiscript.d.ts" - // Check for staged changes and stage all changes if none are staged -let diff = await host.exec(diffCmd) -if (!diff.stdout) { - /** - * Ask user to stage all changes if none are staged - */ - const stage = await host.confirm("No staged changes. Stage all changes?", { - default: true, - }) - if (stage) { - // Stage all changes and recompute diff - await host.exec("git add .") - diff = await host.exec(diffCmd) - } - if (!diff.stdout) cancel("no staged changes") -} +const diff = await git.diff({ + staged: true, + excludedPaths: "**/genaiscript.d.ts", + askStageOnEmpty: true, +}) +if (!diff) cancel("no staged changes") // show diff in the console -console.log(diff.stdout) +console.log(diff) let choice let message diff --git a/packages/vscode/genaisrc/genaiscript.d.ts b/packages/vscode/genaisrc/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/packages/vscode/genaisrc/genaiscript.d.ts +++ b/packages/vscode/genaisrc/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions { diff --git a/slides/genaisrc/genaiscript.d.ts b/slides/genaisrc/genaiscript.d.ts index 4063c0cc95..d08a9fca47 100644 --- a/slides/genaisrc/genaiscript.d.ts +++ b/slides/genaisrc/genaiscript.d.ts @@ -1324,13 +1324,30 @@ interface Git { * @param options */ findModifiedFiles( - scope: "branch" | "staged" | "modified", + scope: "base" | "staged" | "modified", options?: { base?: string paths?: ElementOrArray excludedPaths?: ElementOrArray } ): Promise + + /** + * + * @param options + */ + diff(options?: { + staged?: boolean + /** + * Ask the user to stage the changes if the diff is empty. + */ + askStageOnEmpty?: boolean + base?: string + head?: string + paths?: ElementOrArray + excludedPaths?: ElementOrArray + unified?: number + }): Promise } interface GitHubOptions {