diff --git a/README.md b/README.md index 5e9d11a..f3a38eb 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,11 @@ List files. Useful as a dry run and with fzf. Does not download. Will show show conflicts for the current working directory if -d / --dest is not specified. +### -p, --prefix + +Append the owner/repo prefix to the path in list output. +This is useful for feeding back into ghex. + ### -c, --conflicts-only Only show conflicts when listing. diff --git a/package-lock.json b/package-lock.json index 99eee88..4dd0cb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "chalk": "^5.3.0", - "github-extractor": "^0.0.28", + "github-extractor": "^0.0.29", "indent-string": "^5.0.0", "meow": "^13.2.0", "ora": "^8.0.1", @@ -4147,9 +4147,9 @@ } }, "node_modules/github-extractor": { - "version": "0.0.28", - "resolved": "https://registry.npmjs.org/github-extractor/-/github-extractor-0.0.28.tgz", - "integrity": "sha512-Q7dZrB8fMD0gKEzkvyQaya7G8UOJ+xkB4dR97Da2lyHAALo9BqDBtFGLqnFfRbvlt7K0kn4f+v6MG/jv+GSgZg==", + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/github-extractor/-/github-extractor-0.0.29.tgz", + "integrity": "sha512-XAe/voWzc9p/rB+htin40UfPgtsPpuuC5E3v9H8/RcUqFP9ALU0WLWX3hCpl+OruyLvEC+SQCzZHB8fZBNcpcA==", "dependencies": { "chalk": "^5.3.0", "fastest-levenshtein": "^1.0.16", diff --git a/package.json b/package.json index 6db8316..e2dbc0c 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ }, "dependencies": { "chalk": "^5.3.0", - "github-extractor": "^0.0.28", + "github-extractor": "^0.0.29", "indent-string": "^5.0.0", "meow": "^13.2.0", "ora": "^8.0.1", diff --git a/source/cli.mts b/source/cli.mts index 9957ce2..96d4457 100644 --- a/source/cli.mts +++ b/source/cli.mts @@ -26,6 +26,7 @@ const { name, docsUrl } = meow({ importMeta: import.meta }).pkg as { name: strin export enum Option { dest = "dest", list = "list", + prefix = "prefix", colors = "colors", caseInsensitive = "caseInsensitive", conflictsOnly = "conflictsOnly", @@ -47,6 +48,8 @@ export const helpText = ` -l, --list List files. Useful as a dry run and with fzf. Does not download. Will show show conflicts for the current working directory if -d / --dest is not specified. + -p, --prefix Append the owner/repo prefix to the path in list output + Useful for feeding back into ${ name }. -c, --conflicts-only Only show conflicts when listing. -d, --dest Destination folder. Defaults to the current directory. -i, --case-insensitive Ignores case when checking for conflicts. Default is @@ -82,6 +85,10 @@ export function getCli(argv?: string[]) { type: "boolean", shortFlag: "l", }, + [Option.prefix]: { + type: "boolean", + shortFlag: "p", + }, [Option.colors]: { type: "boolean", default: !noColor(), diff --git a/source/index.mts b/source/index.mts index 25c406e..da8820f 100644 --- a/source/index.mts +++ b/source/index.mts @@ -15,6 +15,12 @@ import wrapAnsi from "wrap-ansi"; // copied to the README. // Todo: +// - list with or without owner/repo prefix +// - Quick SVG based video. +// - Longer playable .cast for website. + +// - Include example of getting the fzf install script with ghex in the main video or +// an alt. // - create video demo and add to readme // - Show usages with fzf--upload ascii svg recording to docs/cli/ (by way of the README) @@ -27,14 +33,14 @@ try { const { input: paths, flags } = getCli(); c.showColor = flags.colors; - let { list: listMode = false, quiet = false, dest, keepIf, caseInsensitive = false, conflictsOnly = false } = flags; + let { list: listMode = false, quiet = false, dest, keepIf, caseInsensitive = false, conflictsOnly = false, prefix = false } = flags; const ownerGrouping: OwnerGroup = groupByOwner({ paths }); const parsedGroups: ParsedGroup[] = parseOwnerGroups({ ownerGrouping, listMode, caseInsensitive }); if (!listMode && !quiet) spinner = ora("Downloading...").start(); - await executeParsedGroups({ conflictsOnly, listMode, parsedGroups, dest, keepIf, quiet }); + await executeParsedGroups({ conflictsOnly, listMode, parsedGroups, dest, keepIf, quiet, prefix }); if (spinner) { spinner.succeed(`Successfully downloaded to file://${ pathe.resolve(dest) }`); diff --git a/source/main.mts b/source/main.mts index e6ec2a5..9388b9e 100644 --- a/source/main.mts +++ b/source/main.mts @@ -2,7 +2,7 @@ import { c } from "./cli.mjs"; import pico from "picomatch"; -import GithubExtractor, { Typo } from "github-extractor"; +import GithubExtractor, { Typo, ListOptions } from "github-extractor"; import indentString from "indent-string"; @@ -133,15 +133,17 @@ function handleTypos(typos: Typo[], quiet: boolean) { } export async function executeParsedGroups( - { listMode, conflictsOnly, parsedGroups, dest, keepIf, quiet }: - { listMode: boolean; conflictsOnly: boolean; parsedGroups: ParsedGroup[]; dest: string; keepIf: string | undefined; quiet: boolean } + { listMode, conflictsOnly, parsedGroups, dest, keepIf, quiet, prefix }: + { listMode: boolean; conflictsOnly: boolean; parsedGroups: ParsedGroup[]; dest: string; keepIf: string | undefined; quiet: boolean; prefix?: boolean } ): Promise { for (const group of parsedGroups) { if (listMode) { - - const opts = { conflictsOnly, dest, match: group.regex! }; + const outPrefix = prefix ? + `${ group.gheInstance.owner }/${ group.gheInstance.repo }/` : + ""; + const opts: ListOptions = { conflictsOnly, dest, match: group.regex!, streamOptions: { prefix: outPrefix } }; await group.gheInstance.list(opts); continue; } diff --git a/test/main.mocked.test.mts b/test/main.mocked.test.mts index 15ecae3..b8d0912 100644 --- a/test/main.mocked.test.mts +++ b/test/main.mocked.test.mts @@ -147,4 +147,24 @@ describe("Correct selected files given to GithubExtractor.downloadTo", async () expect(stubbedDownloadTo.callCount).toBe(2); }); + it("It correctly supplies prefix args with owner/repo when prefix is true", async () => { + + const prefix = true; + listMode = true; + + ownerGrouping = ownerGrouping = { + owner1: { repo1: [ "path1.txt", "path2.txt" ], repo2: [ "path1.txt", "path2.txt" ] }, + }; + + const parsedGroups = parseOwnerGroups({ ownerGrouping, listMode, caseInsensitive }); + const stubbedList = sinon.stub(GithubExtractor.prototype, "list").resolves([]); + + await executeParsedGroups({conflictsOnly, quiet, listMode, parsedGroups, dest: TEMP_DIR, keepIf, prefix }); + + expect(stubbedList.callCount).toBe(2); + expect(stubbedList.firstCall.args?.[0]?.streamOptions?.prefix).toBe("owner1/repo1/"); + expect(stubbedList.secondCall.args?.[0]?.streamOptions?.prefix).toBe("owner1/repo2/"); + + }); + }); \ No newline at end of file