@altano/repository-tools 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/exec.d.ts +3 -3
- package/dist/findRoot.d.ts +1 -2
- package/dist/findRoot.js +1 -1
- package/dist/findRoot.js.map +1 -1
- package/dist/findRootSync.d.ts +1 -2
- package/dist/findRootSync.js +1 -1
- package/dist/findRootSync.js.map +1 -1
- package/dist/repositoryCommand.d.ts +3 -4
- package/dist/repositoryCommand.js +6 -1
- package/dist/repositoryCommand.js.map +1 -1
- package/dist/types.d.ts +2 -3
- package/package.json +13 -13
package/dist/exec.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { exec, execFile, execFileSync, execSync } from "child_process";
|
|
2
2
|
//#region src/exec.d.ts
|
|
3
|
-
declare const execAsync: typeof exec.__promisify__;
|
|
4
|
-
declare const execFileAsync: typeof execFile.__promisify__;
|
|
3
|
+
export declare const execAsync: typeof exec.__promisify__;
|
|
4
|
+
export declare const execFileAsync: typeof execFile.__promisify__;
|
|
5
5
|
//#endregion
|
|
6
|
-
export {
|
|
6
|
+
export { execFileSync, execSync };
|
|
7
7
|
//# sourceMappingURL=exec.d.ts.map
|
package/dist/findRoot.d.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @returns null if not found or the path of the repository root as a string
|
|
6
6
|
*/
|
|
7
|
-
declare function findRoot(directory: string): Promise<string | null>;
|
|
7
|
+
export declare function findRoot(directory: string): Promise<string | null>;
|
|
8
8
|
//#endregion
|
|
9
|
-
export { findRoot };
|
|
10
9
|
//# sourceMappingURL=findRoot.d.ts.map
|
package/dist/findRoot.js
CHANGED
|
@@ -51,7 +51,7 @@ async function findRoot(directory) {
|
|
|
51
51
|
/* v8 ignore if */
|
|
52
52
|
if (result != null && result !== "") return result;
|
|
53
53
|
} catch (e) {
|
|
54
|
-
if (e instanceof Error && "code" in e && e.code === "ENOTDIR") throw new Error(`Given path isn't a directory: ${directory}
|
|
54
|
+
if (e instanceof Error && "code" in e && e.code === "ENOTDIR") throw new Error(`Given path isn't a directory: ${directory}`, { cause: e });
|
|
55
55
|
}
|
|
56
56
|
return null;
|
|
57
57
|
}
|
package/dist/findRoot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findRoot.js","names":[],"sources":["../src/findRoot.ts"],"sourcesContent":["import { repositoryExec } from \"./repositoryCommand.js\";\n\nasync function findGitRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"git\", [\n \"rev-parse\",\n \"--quiet\",\n \"--show-toplevel\",\n ]);\n}\n\n/**\n * `--ignore-working-copy` keeps this a read-only operation. Every other jj\n * command snapshots the working copy first, which takes the working-copy lock\n * and writes a new operation to the repository we were only asked to locate.\n */\nasync function findJujutsuRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"jj\", [\n \"--ignore-working-copy\",\n \"--quiet\",\n \"root\",\n ]);\n}\n\nasync function findSaplingRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"sl\", [\"--quiet\", \"root\"]);\n}\n\nasync function findMercurialRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"hg\", [\"--quiet\", \"root\"]);\n}\n\nasync function findSubversionRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"svn\", [\"info\", \"--show-item\", \"wc-root\"]);\n}\n\n// Version control systems to check for. Highest-precedence checks go first.\nconst findMethods = [\n findGitRoot, // most used and fastest check\n // Runs almost as fast as git's check. A colocated jj repo (jj's default) has\n // a .git too and never reaches this, so this only works for non-colocated\n // repos and jj workspace directories, which git can't see at all.\n findJujutsuRoot,\n findSubversionRoot, // next highest market share\n findSaplingRoot, // much smaller market share, but much faster\n findMercurialRoot, // slow af\n] as const;\n\n/**\n * Find the root path of the repository containing the given directory.\n *\n * @returns null if not found or the path of the repository root as a string\n */\nexport async function findRoot(\n /**\n * The directory path of anything in a version-controlled repository\n */\n directory: string,\n): Promise<string | null> {\n for (const method of findMethods) {\n try {\n const result = await method(directory);\n /* v8 ignore if */\n if (result != null && result !== \"\") {\n return result;\n }\n } catch (e: unknown) {\n if (e instanceof Error && \"code\" in e && e.code === \"ENOTDIR\") {\n // rethrow error when given directory path isn't a directory\n throw new Error(`Given path isn't a directory: ${directory}
|
|
1
|
+
{"version":3,"file":"findRoot.js","names":[],"sources":["../src/findRoot.ts"],"sourcesContent":["import { repositoryExec } from \"./repositoryCommand.js\";\n\nasync function findGitRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"git\", [\n \"rev-parse\",\n \"--quiet\",\n \"--show-toplevel\",\n ]);\n}\n\n/**\n * `--ignore-working-copy` keeps this a read-only operation. Every other jj\n * command snapshots the working copy first, which takes the working-copy lock\n * and writes a new operation to the repository we were only asked to locate.\n */\nasync function findJujutsuRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"jj\", [\n \"--ignore-working-copy\",\n \"--quiet\",\n \"root\",\n ]);\n}\n\nasync function findSaplingRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"sl\", [\"--quiet\", \"root\"]);\n}\n\nasync function findMercurialRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"hg\", [\"--quiet\", \"root\"]);\n}\n\nasync function findSubversionRoot(directory: string): Promise<string> {\n return repositoryExec(directory, \"svn\", [\"info\", \"--show-item\", \"wc-root\"]);\n}\n\n// Version control systems to check for. Highest-precedence checks go first.\nconst findMethods = [\n findGitRoot, // most used and fastest check\n // Runs almost as fast as git's check. A colocated jj repo (jj's default) has\n // a .git too and never reaches this, so this only works for non-colocated\n // repos and jj workspace directories, which git can't see at all.\n findJujutsuRoot,\n findSubversionRoot, // next highest market share\n findSaplingRoot, // much smaller market share, but much faster\n findMercurialRoot, // slow af\n] as const;\n\n/**\n * Find the root path of the repository containing the given directory.\n *\n * @returns null if not found or the path of the repository root as a string\n */\nexport async function findRoot(\n /**\n * The directory path of anything in a version-controlled repository\n */\n directory: string,\n): Promise<string | null> {\n for (const method of findMethods) {\n try {\n const result = await method(directory);\n /* v8 ignore if */\n if (result != null && result !== \"\") {\n return result;\n }\n } catch (e: unknown) {\n if (e instanceof Error && \"code\" in e && e.code === \"ENOTDIR\") {\n // rethrow error when given directory path isn't a directory\n throw new Error(`Given path isn't a directory: ${directory}`, {\n cause: e,\n });\n }\n }\n }\n return null;\n}\n"],"mappings":";;;AAEA,eAAe,YAAY,WAAoC;CAC7D,OAAO,eAAe,WAAW,OAAO;EACtC;EACA;EACA;CACF,CAAC;AACH;;;;;;AAOA,eAAe,gBAAgB,WAAoC;CACjE,OAAO,eAAe,WAAW,MAAM;EACrC;EACA;EACA;CACF,CAAC;AACH;AAEA,eAAe,gBAAgB,WAAoC;CACjE,OAAO,eAAe,WAAW,MAAM,CAAC,WAAW,MAAM,CAAC;AAC5D;AAEA,eAAe,kBAAkB,WAAoC;CACnE,OAAO,eAAe,WAAW,MAAM,CAAC,WAAW,MAAM,CAAC;AAC5D;AAEA,eAAe,mBAAmB,WAAoC;CACpE,OAAO,eAAe,WAAW,OAAO;EAAC;EAAQ;EAAe;CAAS,CAAC;AAC5E;AAGA,MAAM,cAAc;CAClB;CAIA;CACA;CACA;CACA;AACF;;;;;;AAOA,eAAsB,SAIpB,WACwB;CACxB,KAAK,MAAM,UAAU,aACnB,IAAI;EACF,MAAM,SAAS,MAAM,OAAO,SAAS;;EAErC,IAAI,UAAU,QAAQ,WAAW,IAC/B,OAAO;CAEX,SAAS,GAAY;EACnB,IAAI,aAAa,SAAS,UAAU,KAAK,EAAE,SAAS,WAElD,MAAM,IAAI,MAAM,iCAAiC,aAAa,EAC5D,OAAO,EACT,CAAC;CAEL;CAEF,OAAO;AACT"}
|
package/dist/findRootSync.d.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @returns null if not found or the path of the repository root as a string
|
|
6
6
|
*/
|
|
7
|
-
declare function findRootSync(directory: string): string | null;
|
|
7
|
+
export declare function findRootSync(directory: string): string | null;
|
|
8
8
|
//#endregion
|
|
9
|
-
export { findRootSync };
|
|
10
9
|
//# sourceMappingURL=findRootSync.d.ts.map
|
package/dist/findRootSync.js
CHANGED
|
@@ -50,7 +50,7 @@ function findRootSync(directory) {
|
|
|
50
50
|
const result = method(directory);
|
|
51
51
|
if (result != null && result !== "") return result;
|
|
52
52
|
} catch (e) {
|
|
53
|
-
if (e instanceof Error && "code" in e && e.code === "ENOTDIR") throw new Error(`Given path isn't a directory: ${directory}
|
|
53
|
+
if (e instanceof Error && "code" in e && e.code === "ENOTDIR") throw new Error(`Given path isn't a directory: ${directory}`, { cause: e });
|
|
54
54
|
}
|
|
55
55
|
return null;
|
|
56
56
|
}
|
package/dist/findRootSync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findRootSync.js","names":[],"sources":["../src/findRootSync.ts"],"sourcesContent":["import { repositoryExecSync } from \"./repositoryCommand.js\";\n\nfunction findGitRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"git\", [\n \"rev-parse\",\n \"--quiet\",\n \"--show-toplevel\",\n ]);\n}\n\n/**\n * `--ignore-working-copy` keeps this a read-only operation. Every other jj\n * command snapshots the working copy first, which takes the working-copy lock\n * and writes a new operation to the repository we were only asked to locate.\n */\nfunction findJujutsuRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"jj\", [\n \"--ignore-working-copy\",\n \"--quiet\",\n \"root\",\n ]);\n}\n\nfunction findSaplingRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"sl\", [\"--quiet\", \"root\"]);\n}\n\nfunction findMercurialRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"hg\", [\"--quiet\", \"root\"]);\n}\n\nfunction findSubversionRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"svn\", [\"info\", \"--show-item\", \"wc-root\"]);\n}\n\n// Version control systems to check for. Highest-precedence checks go first.\nconst findMethods = [\n findGitRoot, // most used and fastest check\n // Runs almost as fast as git's check. A colocated jj repo (jj's default) has\n // a .git too and never reaches this, so this only works for non-colocated\n // repos and jj workspace directories, which git can't see at all.\n findJujutsuRoot,\n findSubversionRoot, // next highest market share\n findSaplingRoot, // much smaller market share, but much faster\n findMercurialRoot, // slow af\n] as const;\n\n/**\n * Find the root path of the repository containing the given directory.\n *\n * @returns null if not found or the path of the repository root as a string\n */\nexport function findRootSync(\n /**\n * The directory path of anything in a version-controlled repository\n */\n directory: string,\n): string | null {\n for (const method of findMethods) {\n try {\n const result = method(directory);\n if (result != null && result !== \"\") {\n return result;\n }\n } catch (e: unknown) {\n if (e instanceof Error && \"code\" in e && e.code === \"ENOTDIR\") {\n // rethrow error when given directory path isn't a directory\n throw new Error(`Given path isn't a directory: ${directory}
|
|
1
|
+
{"version":3,"file":"findRootSync.js","names":[],"sources":["../src/findRootSync.ts"],"sourcesContent":["import { repositoryExecSync } from \"./repositoryCommand.js\";\n\nfunction findGitRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"git\", [\n \"rev-parse\",\n \"--quiet\",\n \"--show-toplevel\",\n ]);\n}\n\n/**\n * `--ignore-working-copy` keeps this a read-only operation. Every other jj\n * command snapshots the working copy first, which takes the working-copy lock\n * and writes a new operation to the repository we were only asked to locate.\n */\nfunction findJujutsuRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"jj\", [\n \"--ignore-working-copy\",\n \"--quiet\",\n \"root\",\n ]);\n}\n\nfunction findSaplingRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"sl\", [\"--quiet\", \"root\"]);\n}\n\nfunction findMercurialRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"hg\", [\"--quiet\", \"root\"]);\n}\n\nfunction findSubversionRoot(cwd: string): string {\n return repositoryExecSync(cwd, \"svn\", [\"info\", \"--show-item\", \"wc-root\"]);\n}\n\n// Version control systems to check for. Highest-precedence checks go first.\nconst findMethods = [\n findGitRoot, // most used and fastest check\n // Runs almost as fast as git's check. A colocated jj repo (jj's default) has\n // a .git too and never reaches this, so this only works for non-colocated\n // repos and jj workspace directories, which git can't see at all.\n findJujutsuRoot,\n findSubversionRoot, // next highest market share\n findSaplingRoot, // much smaller market share, but much faster\n findMercurialRoot, // slow af\n] as const;\n\n/**\n * Find the root path of the repository containing the given directory.\n *\n * @returns null if not found or the path of the repository root as a string\n */\nexport function findRootSync(\n /**\n * The directory path of anything in a version-controlled repository\n */\n directory: string,\n): string | null {\n for (const method of findMethods) {\n try {\n const result = method(directory);\n if (result != null && result !== \"\") {\n return result;\n }\n } catch (e: unknown) {\n if (e instanceof Error && \"code\" in e && e.code === \"ENOTDIR\") {\n // rethrow error when given directory path isn't a directory\n throw new Error(`Given path isn't a directory: ${directory}`, {\n cause: e,\n });\n }\n }\n }\n return null;\n}\n"],"mappings":";;;AAEA,SAAS,YAAY,KAAqB;CACxC,OAAO,mBAAmB,KAAK,OAAO;EACpC;EACA;EACA;CACF,CAAC;AACH;;;;;;AAOA,SAAS,gBAAgB,KAAqB;CAC5C,OAAO,mBAAmB,KAAK,MAAM;EACnC;EACA;EACA;CACF,CAAC;AACH;AAEA,SAAS,gBAAgB,KAAqB;CAC5C,OAAO,mBAAmB,KAAK,MAAM,CAAC,WAAW,MAAM,CAAC;AAC1D;AAEA,SAAS,kBAAkB,KAAqB;CAC9C,OAAO,mBAAmB,KAAK,MAAM,CAAC,WAAW,MAAM,CAAC;AAC1D;AAEA,SAAS,mBAAmB,KAAqB;CAC/C,OAAO,mBAAmB,KAAK,OAAO;EAAC;EAAQ;EAAe;CAAS,CAAC;AAC1E;AAGA,MAAM,cAAc;CAClB;CAIA;CACA;CACA;CACA;AACF;;;;;;AAOA,SAAgB,aAId,WACe;CACf,KAAK,MAAM,UAAU,aACnB,IAAI;EACF,MAAM,SAAS,OAAO,SAAS;EAC/B,IAAI,UAAU,QAAQ,WAAW,IAC/B,OAAO;CAEX,SAAS,GAAY;EACnB,IAAI,aAAa,SAAS,UAAU,KAAK,EAAE,SAAS,WAElD,MAAM,IAAI,MAAM,iCAAiC,aAAa,EAC5D,OAAO,EACT,CAAC;CAEL;CAEF,OAAO;AACT"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
//#region src/repositoryCommand.d.ts
|
|
2
2
|
type RepositoryCommand = "git" | "hg" | "jj" | "sl" | "svn" | "svnadmin" | "svnrdump";
|
|
3
|
-
declare function repositoryExec(cwd: string, command: RepositoryCommand, args: readonly string[]): Promise<string>;
|
|
4
|
-
declare function repositoryExecSync(cwd: string, command: RepositoryCommand, args: readonly string[]): string;
|
|
5
|
-
declare const createExecForDirectory: (cwd: string) => ((command: RepositoryCommand, args: readonly string[]) => Promise<string>);
|
|
3
|
+
export declare function repositoryExec(cwd: string, command: RepositoryCommand, args: readonly string[]): Promise<string>;
|
|
4
|
+
export declare function repositoryExecSync(cwd: string, command: RepositoryCommand, args: readonly string[]): string;
|
|
5
|
+
export declare const createExecForDirectory: (cwd: string) => ((command: RepositoryCommand, args: readonly string[]) => Promise<string>);
|
|
6
6
|
//#endregion
|
|
7
|
-
export { createExecForDirectory, repositoryExec, repositoryExecSync };
|
|
8
7
|
//# sourceMappingURL=repositoryCommand.d.ts.map
|
|
@@ -76,7 +76,12 @@ function repositoryExecSync(cwd, command, args) {
|
|
|
76
76
|
return execFileSync(command, args, {
|
|
77
77
|
cwd,
|
|
78
78
|
encoding: "utf8",
|
|
79
|
-
env: getEnvironment(command)
|
|
79
|
+
env: getEnvironment(command),
|
|
80
|
+
stdio: [
|
|
81
|
+
"ignore",
|
|
82
|
+
"pipe",
|
|
83
|
+
"pipe"
|
|
84
|
+
]
|
|
80
85
|
}).trim();
|
|
81
86
|
}
|
|
82
87
|
const createExecForDirectory = (cwd) => repositoryExec.bind(null, cwd);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repositoryCommand.js","names":[],"sources":["../src/repositoryCommand.ts"],"sourcesContent":["import { execFileAsync, execFileSync } from \"./exec.js\";\nimport {} from \"child_process\";\n\ntype RepositoryCommand =\n \"git\" | \"hg\" | \"jj\" | \"sl\" | \"svn\" | \"svnadmin\" | \"svnrdump\";\n\nconst environment = {\n git: {\n // non-interactive\n GIT_TERMINAL_PROMPT: \"0\",\n // don't use global config\n GIT_CONFIG_GLOBAL: \"/dev/null\",\n GIT_CONFIG_SYSTEM: \"/dev/null\",\n // user config\n GIT_COMMITTER_NAME: \"alan\",\n GIT_COMMITTER_EMAIL: \"alan@example.com\",\n GIT_AUTHOR_NAME: \"alan\",\n GIT_AUTHOR_EMAIL: \"alan@example.com\",\n },\n jj: {\n // don't use global config\n JJ_CONFIG: \"/dev/null\",\n // user config. Without an identity jj warns on stderr, which we treat as a\n // failed command.\n JJ_USER: \"alan\",\n JJ_EMAIL: \"alan@example.com\",\n },\n hg: {\n // don't use global config\n HGRCPATH: \"/dev/null\",\n // don't use global config\n HGUSER: \"alan\",\n EMAIL: \"alan@example.com\",\n },\n sl: {\n // don't use global config\n HGRCPATH: \"/dev/null\",\n // don't use global config\n HGUSER: \"alan\",\n EMAIL: \"alan@example.com\",\n },\n svn: {},\n svnadmin: {},\n svnrdump: {},\n} as const satisfies Record<RepositoryCommand, NodeJS.ProcessEnv>;\n\n/**\n * Environment variables that pin git to one particular repository, work tree,\n * index, or object store.\n *\n * Git exports several of these before running a hook, so every process a hook\n * spawns inherits them. We always point git at a directory of our choosing\n * (via cwd) and want an answer about *that* directory, so they have to go.\n *\n * GIT_DIR is the worst offender: when it is set and GIT_WORK_TREE isn't, git\n * skips repository discovery entirely and \"tells Git that you are at the top\n * level of the working tree\", so `git rev-parse --show-toplevel` echoes back\n * the directory we asked about instead of the root containing it.\n *\n * https://github.com/altano/npm-packages/issues/299\n *\n * Variables that only tune discovery, and that a user has to opt into\n * deliberately (GIT_CEILING_DIRECTORIES, GIT_DISCOVERY_ACROSS_FILESYSTEM), are\n * intentionally left alone.\n */\nconst gitRepositoryVariables = [\n \"GIT_DIR\",\n \"GIT_WORK_TREE\",\n \"GIT_COMMON_DIR\",\n \"GIT_INDEX_FILE\",\n \"GIT_INDEX_VERSION\",\n \"GIT_OBJECT_DIRECTORY\",\n \"GIT_ALTERNATE_OBJECT_DIRECTORIES\",\n \"GIT_NAMESPACE\",\n \"GIT_PREFIX\",\n \"GIT_QUARANTINE_PATH\",\n] as const;\n\n/**\n * Inherited environment variables to drop, per command. The other version\n * control systems have no equivalent of GIT_DIR: they're told which repository\n * to use with a flag, never with the environment.\n */\nconst removedEnvironment = {\n git: gitRepositoryVariables,\n // jj takes a repository with -R/--repository and finds one by walking up to\n // the closest .jj, a search git's variables have no say in. Verified: from a\n // subdirectory of a colocated repo, `jj root` answers correctly with GIT_DIR\n // set to a value that makes git itself bail out.\n jj: [],\n hg: [],\n sl: [],\n svn: [],\n svnadmin: [],\n svnrdump: [],\n} as const satisfies Record<RepositoryCommand, readonly string[]>;\n\nfunction getEnvironment(command: RepositoryCommand): NodeJS.ProcessEnv {\n const result: NodeJS.ProcessEnv = {\n ...process.env,\n ...environment[command],\n };\n for (const variable of removedEnvironment[command]) {\n delete result[variable];\n }\n return result;\n}\n\nexport async function repositoryExec(\n cwd: string,\n command: RepositoryCommand,\n args: readonly string[],\n): Promise<string> {\n // const msg = `Executing command: ${command} ${args.join(\" \")}`;\n // console.time(msg);\n return execFileAsync(command, args, {\n cwd: cwd,\n encoding: \"utf8\",\n env: getEnvironment(command),\n }).then(({ stdout, stderr }) => {\n // console.timeEnd(msg);\n return stderr ? Promise.reject(new Error(stderr.trim())) : stdout.trim();\n });\n}\n\nexport function repositoryExecSync(\n cwd: string,\n command: RepositoryCommand,\n args: readonly string[],\n): string {\n // const msg = `Executing command: ${command} ${args.join(\" \")}`;\n // console.time(msg);\n const result = execFileSync(command, args, {\n cwd: cwd,\n encoding: \"utf8\",\n env: getEnvironment(command),\n }).trim();\n // console.timeEnd(msg);\n return result;\n}\n\nexport const createExecForDirectory = (\n cwd: string,\n): ((command: RepositoryCommand, args: readonly string[]) => Promise<string>) =>\n repositoryExec.bind(null, cwd);\n\n// Not being used.\n// export const createExecSyncForDirectory = (\n// cwd: string,\n// ): ((command: RepositoryCommand, args: readonly string[]) => string) =>\n// repositoryExecSync.bind(null, cwd);\n"],"mappings":";;;AAMA,MAAM,cAAc;CAClB,KAAK;EAEH,qBAAqB;EAErB,mBAAmB;EACnB,mBAAmB;EAEnB,oBAAoB;EACpB,qBAAqB;EACrB,iBAAiB;EACjB,kBAAkB;CACpB;CACA,IAAI;EAEF,WAAW;EAGX,SAAS;EACT,UAAU;CACZ;CACA,IAAI;EAEF,UAAU;EAEV,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EAEF,UAAU;EAEV,QAAQ;EACR,OAAO;CACT;CACA,KAAK,CAAC;CACN,UAAU,CAAC;CACX,UAAU,CAAC;AACb;;;;;;AAuCA,MAAM,qBAAqB;CACzB,KAAK;EAlBL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAS0B;CAK1B,IAAI,CAAC;CACL,IAAI,CAAC;CACL,IAAI,CAAC;CACL,KAAK,CAAC;CACN,UAAU,CAAC;CACX,UAAU,CAAC;AACb;AAEA,SAAS,eAAe,SAA+C;CACrE,MAAM,SAA4B;EAChC,GAAG,QAAQ;EACX,GAAG,YAAY;CACjB;CACA,KAAK,MAAM,YAAY,mBAAmB,UACxC,OAAO,OAAO;CAEhB,OAAO;AACT;AAEA,eAAsB,eACpB,KACA,SACA,MACiB;CAGjB,OAAO,cAAc,SAAS,MAAM;EAC7B;EACL,UAAU;EACV,KAAK,eAAe,OAAO;CAC7B,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,aAAa;EAE9B,OAAO,SAAS,QAAQ,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK;CACzE,CAAC;AACH;AAEA,SAAgB,mBACd,KACA,SACA,MACQ;
|
|
1
|
+
{"version":3,"file":"repositoryCommand.js","names":[],"sources":["../src/repositoryCommand.ts"],"sourcesContent":["import { execFileAsync, execFileSync } from \"./exec.js\";\nimport {} from \"child_process\";\n\ntype RepositoryCommand =\n \"git\" | \"hg\" | \"jj\" | \"sl\" | \"svn\" | \"svnadmin\" | \"svnrdump\";\n\nconst environment = {\n git: {\n // non-interactive\n GIT_TERMINAL_PROMPT: \"0\",\n // don't use global config\n GIT_CONFIG_GLOBAL: \"/dev/null\",\n GIT_CONFIG_SYSTEM: \"/dev/null\",\n // user config\n GIT_COMMITTER_NAME: \"alan\",\n GIT_COMMITTER_EMAIL: \"alan@example.com\",\n GIT_AUTHOR_NAME: \"alan\",\n GIT_AUTHOR_EMAIL: \"alan@example.com\",\n },\n jj: {\n // don't use global config\n JJ_CONFIG: \"/dev/null\",\n // user config. Without an identity jj warns on stderr, which we treat as a\n // failed command.\n JJ_USER: \"alan\",\n JJ_EMAIL: \"alan@example.com\",\n },\n hg: {\n // don't use global config\n HGRCPATH: \"/dev/null\",\n // don't use global config\n HGUSER: \"alan\",\n EMAIL: \"alan@example.com\",\n },\n sl: {\n // don't use global config\n HGRCPATH: \"/dev/null\",\n // don't use global config\n HGUSER: \"alan\",\n EMAIL: \"alan@example.com\",\n },\n svn: {},\n svnadmin: {},\n svnrdump: {},\n} as const satisfies Record<RepositoryCommand, NodeJS.ProcessEnv>;\n\n/**\n * Environment variables that pin git to one particular repository, work tree,\n * index, or object store.\n *\n * Git exports several of these before running a hook, so every process a hook\n * spawns inherits them. We always point git at a directory of our choosing\n * (via cwd) and want an answer about *that* directory, so they have to go.\n *\n * GIT_DIR is the worst offender: when it is set and GIT_WORK_TREE isn't, git\n * skips repository discovery entirely and \"tells Git that you are at the top\n * level of the working tree\", so `git rev-parse --show-toplevel` echoes back\n * the directory we asked about instead of the root containing it.\n *\n * https://github.com/altano/npm-packages/issues/299\n *\n * Variables that only tune discovery, and that a user has to opt into\n * deliberately (GIT_CEILING_DIRECTORIES, GIT_DISCOVERY_ACROSS_FILESYSTEM), are\n * intentionally left alone.\n */\nconst gitRepositoryVariables = [\n \"GIT_DIR\",\n \"GIT_WORK_TREE\",\n \"GIT_COMMON_DIR\",\n \"GIT_INDEX_FILE\",\n \"GIT_INDEX_VERSION\",\n \"GIT_OBJECT_DIRECTORY\",\n \"GIT_ALTERNATE_OBJECT_DIRECTORIES\",\n \"GIT_NAMESPACE\",\n \"GIT_PREFIX\",\n \"GIT_QUARANTINE_PATH\",\n] as const;\n\n/**\n * Inherited environment variables to drop, per command. The other version\n * control systems have no equivalent of GIT_DIR: they're told which repository\n * to use with a flag, never with the environment.\n */\nconst removedEnvironment = {\n git: gitRepositoryVariables,\n // jj takes a repository with -R/--repository and finds one by walking up to\n // the closest .jj, a search git's variables have no say in. Verified: from a\n // subdirectory of a colocated repo, `jj root` answers correctly with GIT_DIR\n // set to a value that makes git itself bail out.\n jj: [],\n hg: [],\n sl: [],\n svn: [],\n svnadmin: [],\n svnrdump: [],\n} as const satisfies Record<RepositoryCommand, readonly string[]>;\n\nfunction getEnvironment(command: RepositoryCommand): NodeJS.ProcessEnv {\n const result: NodeJS.ProcessEnv = {\n ...process.env,\n ...environment[command],\n };\n for (const variable of removedEnvironment[command]) {\n delete result[variable];\n }\n return result;\n}\n\nexport async function repositoryExec(\n cwd: string,\n command: RepositoryCommand,\n args: readonly string[],\n): Promise<string> {\n // const msg = `Executing command: ${command} ${args.join(\" \")}`;\n // console.time(msg);\n return execFileAsync(command, args, {\n cwd: cwd,\n encoding: \"utf8\",\n env: getEnvironment(command),\n }).then(({ stdout, stderr }) => {\n // console.timeEnd(msg);\n return stderr ? Promise.reject(new Error(stderr.trim())) : stdout.trim();\n });\n}\n\nexport function repositoryExecSync(\n cwd: string,\n command: RepositoryCommand,\n args: readonly string[],\n): string {\n // const msg = `Executing command: ${command} ${args.join(\" \")}`;\n // console.time(msg);\n const result = execFileSync(command, args, {\n cwd: cwd,\n encoding: \"utf8\",\n env: getEnvironment(command),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n }).trim();\n // console.timeEnd(msg);\n return result;\n}\n\nexport const createExecForDirectory = (\n cwd: string,\n): ((command: RepositoryCommand, args: readonly string[]) => Promise<string>) =>\n repositoryExec.bind(null, cwd);\n\n// Not being used.\n// export const createExecSyncForDirectory = (\n// cwd: string,\n// ): ((command: RepositoryCommand, args: readonly string[]) => string) =>\n// repositoryExecSync.bind(null, cwd);\n"],"mappings":";;;AAMA,MAAM,cAAc;CAClB,KAAK;EAEH,qBAAqB;EAErB,mBAAmB;EACnB,mBAAmB;EAEnB,oBAAoB;EACpB,qBAAqB;EACrB,iBAAiB;EACjB,kBAAkB;CACpB;CACA,IAAI;EAEF,WAAW;EAGX,SAAS;EACT,UAAU;CACZ;CACA,IAAI;EAEF,UAAU;EAEV,QAAQ;EACR,OAAO;CACT;CACA,IAAI;EAEF,UAAU;EAEV,QAAQ;EACR,OAAO;CACT;CACA,KAAK,CAAC;CACN,UAAU,CAAC;CACX,UAAU,CAAC;AACb;;;;;;AAuCA,MAAM,qBAAqB;CACzB,KAAK;EAlBL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAS0B;CAK1B,IAAI,CAAC;CACL,IAAI,CAAC;CACL,IAAI,CAAC;CACL,KAAK,CAAC;CACN,UAAU,CAAC;CACX,UAAU,CAAC;AACb;AAEA,SAAS,eAAe,SAA+C;CACrE,MAAM,SAA4B;EAChC,GAAG,QAAQ;EACX,GAAG,YAAY;CACjB;CACA,KAAK,MAAM,YAAY,mBAAmB,UACxC,OAAO,OAAO;CAEhB,OAAO;AACT;AAEA,eAAsB,eACpB,KACA,SACA,MACiB;CAGjB,OAAO,cAAc,SAAS,MAAM;EAC7B;EACL,UAAU;EACV,KAAK,eAAe,OAAO;CAC7B,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,aAAa;EAE9B,OAAO,SAAS,QAAQ,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK;CACzE,CAAC;AACH;AAEA,SAAgB,mBACd,KACA,SACA,MACQ;CAUR,OAPe,aAAa,SAAS,MAAM;EACpC;EACL,UAAU;EACV,KAAK,eAAe,OAAO;EAC3B,OAAO;GAAC;GAAU;GAAQ;EAAM;CAClC,CAAC,CAAC,CAAC,KAES;AACd;AAEA,MAAa,0BACX,QAEA,eAAe,KAAK,MAAM,GAAG"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
//#region src/types.d.ts
|
|
2
|
-
declare const repositoryTypes: readonly ["git", "jujutsu", "mercurial", "sapling", "subversion"];
|
|
3
|
-
type RepositoryType = (typeof repositoryTypes)[number];
|
|
2
|
+
export declare const repositoryTypes: readonly ["git", "jujutsu", "mercurial", "sapling", "subversion"];
|
|
3
|
+
export type RepositoryType = (typeof repositoryTypes)[number];
|
|
4
4
|
//#endregion
|
|
5
|
-
export { RepositoryType, repositoryTypes };
|
|
6
5
|
//# sourceMappingURL=types.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@altano/repository-tools",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Misc tools for dealing with repositories of multiple version control systems (git, svn, etc)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"repository",
|
|
@@ -39,23 +39,23 @@
|
|
|
39
39
|
],
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
42
|
-
"@types/node": "^26.
|
|
43
|
-
"@vitest/coverage-v8": "^
|
|
44
|
-
"@vitest/expect": "^
|
|
42
|
+
"@types/node": "^26.6.4",
|
|
43
|
+
"@vitest/coverage-v8": "^5.0.3",
|
|
44
|
+
"@vitest/expect": "^5.0.3",
|
|
45
45
|
"depcheck": "^1.4.7",
|
|
46
|
-
"eslint": "^
|
|
46
|
+
"eslint": "^10.12.0",
|
|
47
47
|
"find-cache-directory": "^6.0.0",
|
|
48
48
|
"memize": "^2.1.1",
|
|
49
|
-
"prettier": "3.9.
|
|
49
|
+
"prettier": "3.9.9",
|
|
50
50
|
"ts-assert-unreachable": "^0.0.9",
|
|
51
|
-
"tsdown": "^0.
|
|
51
|
+
"tsdown": "^0.23.0",
|
|
52
52
|
"typescript": "^6.0.3",
|
|
53
|
-
"vite": "^8.
|
|
54
|
-
"vitest": "^
|
|
55
|
-
"@altano/disposable-directory": "0.0.3",
|
|
53
|
+
"vite": "^8.3.2",
|
|
54
|
+
"vitest": "^5.0.3",
|
|
56
55
|
"@altano/build-config": "0.0.1",
|
|
57
|
-
"@altano/
|
|
58
|
-
"@altano/testing": "0.0.1"
|
|
56
|
+
"@altano/disposable-directory": "0.0.3",
|
|
57
|
+
"@altano/testing": "0.0.1",
|
|
58
|
+
"@altano/tsconfig": "0.0.1"
|
|
59
59
|
},
|
|
60
60
|
"publishConfig": {
|
|
61
61
|
"access": "public"
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"lint:timing": "TIMING=1 pnpm lint",
|
|
76
76
|
"test:build": "./tests/scripts/createRepositoryBundles.ts",
|
|
77
77
|
"test:unit": "vitest --run",
|
|
78
|
-
"test:unit:benchmark": "vitest --run
|
|
78
|
+
"test:unit:benchmark": "vitest bench --run",
|
|
79
79
|
"test:unit:watch": "vitest"
|
|
80
80
|
}
|
|
81
81
|
}
|