@catladder/cli 2.5.0 → 2.6.1
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/bundles/catenv/index.js +3 -3
- package/dist/bundles/cli/index.js +8 -8
- package/dist/cli/src/git/gitConfig.d.ts +9 -0
- package/dist/cli/src/git/gitConfig.js +16 -0
- package/dist/cli/src/git/gitConfig.js.map +1 -0
- package/dist/cli/src/git/gitProjectInformation.d.ts +16 -0
- package/dist/cli/src/git/gitProjectInformation.js +38 -0
- package/dist/cli/src/git/gitProjectInformation.js.map +1 -0
- package/dist/cli/src/git/index.d.ts +2 -0
- package/dist/cli/src/git/index.js +19 -0
- package/dist/cli/src/git/index.js.map +1 -0
- package/dist/cli/src/utils/gitlab.js +18 -13
- package/dist/cli/src/utils/gitlab.js.map +1 -1
- package/dist/cli/src/utils/preferences.js +56 -0
- package/dist/cli/src/utils/preferences.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/git/gitConfig.ts +32 -0
- package/src/git/gitProjectInformation.ts +40 -0
- package/src/git/index.ts +2 -0
- package/src/utils/gitlab.ts +19 -19
- package/src/utils/preferences.ts +56 -0
- package/dist/cli/src/utils/preferences/index.js +0 -35
- package/dist/cli/src/utils/preferences/index.js.map +0 -1
- package/src/utils/preferences/index.ts +0 -36
- /package/dist/cli/src/utils/{preferences/index.d.ts → preferences.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { exec } from "child-process-promise";
|
|
2
|
+
|
|
3
|
+
export type GitLocationScope = "global" | "local" | "system" | "worktree";
|
|
4
|
+
export type GitConfigOptions = {
|
|
5
|
+
location?: GitLocationScope;
|
|
6
|
+
comment?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const argsJoin = (args: (string | undefined)[]): string =>
|
|
10
|
+
args.filter(Boolean).join(" ");
|
|
11
|
+
|
|
12
|
+
export async function gitConfigGet(
|
|
13
|
+
key: string,
|
|
14
|
+
{ location }: Pick<GitConfigOptions, "location"> = {},
|
|
15
|
+
) {
|
|
16
|
+
const { stdout } = await exec(
|
|
17
|
+
`git config get ${argsJoin([location ? `--${location}` : undefined])} ${key}`,
|
|
18
|
+
);
|
|
19
|
+
return stdout.trim();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const gitConfigSet = (
|
|
23
|
+
key: string,
|
|
24
|
+
value: string,
|
|
25
|
+
{ location, comment }: GitConfigOptions = {},
|
|
26
|
+
) =>
|
|
27
|
+
exec(
|
|
28
|
+
`git config set ${argsJoin([
|
|
29
|
+
location ? `--${location}` : undefined,
|
|
30
|
+
comment ? `--comment=${comment}` : undefined,
|
|
31
|
+
])} ${key} ${value}`,
|
|
32
|
+
);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { gitConfigGet } from "./gitConfig";
|
|
2
|
+
import { exec } from "child-process-promise";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Find the absolute path of the current git project root.
|
|
6
|
+
*/
|
|
7
|
+
export const getProjectRootPath = async (): Promise<string> => {
|
|
8
|
+
const { stdout } = await exec(`git rev-parse --show-toplevel`);
|
|
9
|
+
return stdout.trim();
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Get the git remote hostname and project path from the git config.
|
|
14
|
+
*/
|
|
15
|
+
export const getGitRemoteHostAndPath = async (): Promise<{
|
|
16
|
+
gitRemoteHost: string;
|
|
17
|
+
gitRemotePath: string;
|
|
18
|
+
}> => {
|
|
19
|
+
const remoteUrl = await gitConfigGet("remote.origin.url");
|
|
20
|
+
const remoteReg = /(https:\/\/|git@)([^:/]+)[:/]([^.]*)(\.git)?/;
|
|
21
|
+
const match = remoteUrl.match(remoteReg) ?? [];
|
|
22
|
+
const [, , gitRemoteHost, gitRemotePath] = match;
|
|
23
|
+
if (!gitRemoteHost?.length || !gitRemotePath?.length) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Failed to parse git remote hostname and path from git configs remote.origin.url! ${remoteUrl}`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return { gitRemoteHost, gitRemotePath };
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const gitProjectInformation = async () => {
|
|
32
|
+
const [{ gitRemoteHost, gitRemotePath }, projectRootPath] = await Promise.all(
|
|
33
|
+
[getGitRemoteHostAndPath(), getProjectRootPath()],
|
|
34
|
+
);
|
|
35
|
+
return {
|
|
36
|
+
gitRemoteHost,
|
|
37
|
+
gitRemotePath,
|
|
38
|
+
projectRootPath,
|
|
39
|
+
};
|
|
40
|
+
};
|
package/src/git/index.ts
ADDED
package/src/utils/gitlab.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { getSecretVarName } from "@catladder/pipeline";
|
|
2
|
-
import { exec } from "child-process-promise";
|
|
3
2
|
import { has, isObject } from "lodash";
|
|
4
3
|
import memoizee from "memoizee";
|
|
5
4
|
import fetch from "node-fetch";
|
|
6
5
|
import open from "open";
|
|
7
6
|
import type { CommandInstance } from "vorpal";
|
|
8
7
|
import { getPreference, hasPreference, setPreference } from "./preferences";
|
|
8
|
+
import { getGitRemoteHostAndPath } from "../git/gitProjectInformation";
|
|
9
9
|
|
|
10
10
|
const TOKEN_KEY = "gitlab-personal-access-token";
|
|
11
11
|
|
|
@@ -17,14 +17,17 @@ export const setupGitlabToken = async (vorpal: CommandInstance) => {
|
|
|
17
17
|
vorpal.log("");
|
|
18
18
|
vorpal.log("☝ we open up the settings page for you!");
|
|
19
19
|
vorpal.log("");
|
|
20
|
-
const { shouldContinue } = await
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
const [{ shouldContinue }, { gitRemoteHost }] = await Promise.all([
|
|
21
|
+
vorpal.prompt({
|
|
22
|
+
default: true,
|
|
23
|
+
message: "Ok",
|
|
24
|
+
name: "shouldContinue",
|
|
25
|
+
type: "prompt",
|
|
26
|
+
}),
|
|
27
|
+
getGitRemoteHostAndPath(),
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
open(`https://${gitRemoteHost}/-/profile/personal_access_tokens`);
|
|
28
31
|
|
|
29
32
|
vorpal.log("Please type in gitlab's personal access token");
|
|
30
33
|
|
|
@@ -58,11 +61,14 @@ export const doGitlabRequest = async <T = any>(
|
|
|
58
61
|
data: any = undefined,
|
|
59
62
|
method: Method = "GET",
|
|
60
63
|
): Promise<T> => {
|
|
61
|
-
const rootToken = await
|
|
64
|
+
const [rootToken, { gitRemoteHost }] = await Promise.all([
|
|
65
|
+
getGitlabToken(vorpal),
|
|
66
|
+
getGitRemoteHostAndPath(),
|
|
67
|
+
]);
|
|
62
68
|
|
|
63
69
|
//const method = data ? (update ? "PUT" : "POST") : "GET";
|
|
64
70
|
|
|
65
|
-
const result = await fetch(`https
|
|
71
|
+
const result = await fetch(`https://${gitRemoteHost}/api/v4/${path}`, {
|
|
66
72
|
method,
|
|
67
73
|
headers: {
|
|
68
74
|
"Content-Type": "application/json",
|
|
@@ -91,16 +97,10 @@ export const doGitlabRequest = async <T = any>(
|
|
|
91
97
|
export const getProjectInfo = async (
|
|
92
98
|
vorpal: CommandInstance | null,
|
|
93
99
|
): Promise<{ id: string; web_url: string }> => {
|
|
94
|
-
const
|
|
95
|
-
await exec("git config --get remote.origin.url")
|
|
96
|
-
).stdout.trim();
|
|
97
|
-
const projectPath =
|
|
98
|
-
/(https:\/\/|git@)git\.panter\.ch[:/]([^.]*)(\.git)?/g.exec(
|
|
99
|
-
gitRemoteOriginUrl,
|
|
100
|
-
);
|
|
100
|
+
const { gitRemotePath } = await getGitRemoteHostAndPath();
|
|
101
101
|
const project = await doGitlabRequest(
|
|
102
102
|
vorpal,
|
|
103
|
-
`projects/${encodeURIComponent(
|
|
103
|
+
`projects/${encodeURIComponent(gitRemotePath)}`,
|
|
104
104
|
);
|
|
105
105
|
return project;
|
|
106
106
|
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { join, dirname } from "path";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { parse, stringify } from "yaml";
|
|
6
|
+
|
|
7
|
+
const legacyPreferencesPath = join(homedir(), ".catladder/preferences.yml");
|
|
8
|
+
const preferencesPath = join(homedir(), ".config/catladder/preferences.yml");
|
|
9
|
+
|
|
10
|
+
const ensurePreferencesFile = async () => {
|
|
11
|
+
if (existsSync(preferencesPath)) {
|
|
12
|
+
return preferencesPath;
|
|
13
|
+
}
|
|
14
|
+
await mkdir(dirname(preferencesPath), { recursive: true, mode: 0o700 });
|
|
15
|
+
await writeFile(preferencesPath, "---\n{}", {
|
|
16
|
+
encoding: "utf-8",
|
|
17
|
+
mode: 0o600,
|
|
18
|
+
});
|
|
19
|
+
if (existsSync(legacyPreferencesPath)) {
|
|
20
|
+
return legacyPreferencesPath;
|
|
21
|
+
}
|
|
22
|
+
return preferencesPath;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const loadPreferences = async () => {
|
|
26
|
+
const currentLoadPath = await ensurePreferencesFile();
|
|
27
|
+
return readFile(currentLoadPath, { encoding: "utf-8" });
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const getPreferences = async () => {
|
|
31
|
+
const yamlContent = await loadPreferences();
|
|
32
|
+
return (parse(yamlContent) ?? {}) as Record<string, string>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const hasPreference = async (key: string) => {
|
|
36
|
+
const preferences = await getPreferences();
|
|
37
|
+
return key in preferences;
|
|
38
|
+
};
|
|
39
|
+
export const getPreference = async (key: string) => {
|
|
40
|
+
const preferences = await getPreferences();
|
|
41
|
+
return preferences[key];
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const setPreference = async (key: string, value: string | number) => {
|
|
45
|
+
const preferences = await getPreferences();
|
|
46
|
+
|
|
47
|
+
const newPreferences = {
|
|
48
|
+
...preferences,
|
|
49
|
+
[key]: value,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
await writeFile(legacyPreferencesPath, stringify(newPreferences), {
|
|
53
|
+
encoding: "utf-8",
|
|
54
|
+
mode: 0o600,
|
|
55
|
+
});
|
|
56
|
+
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setPreference = exports.getPreference = exports.hasPreference = void 0;
|
|
4
|
-
const fs_extra_1 = require("fs-extra");
|
|
5
|
-
const os_1 = require("os");
|
|
6
|
-
const yaml_1 = require("yaml");
|
|
7
|
-
const directory = `${(0, os_1.homedir)()}/.catladder`;
|
|
8
|
-
const file = `${directory}/preferences.yml`;
|
|
9
|
-
const getPreferences = async () => {
|
|
10
|
-
var _a;
|
|
11
|
-
if (!(await (0, fs_extra_1.pathExists)(file))) {
|
|
12
|
-
await (0, fs_extra_1.createFile)(file);
|
|
13
|
-
}
|
|
14
|
-
return ((_a = (0, yaml_1.parse)(await (0, fs_extra_1.readFile)(file, { encoding: "utf-8" }))) !== null && _a !== void 0 ? _a : {});
|
|
15
|
-
};
|
|
16
|
-
const hasPreference = async (key) => {
|
|
17
|
-
const preferences = await getPreferences();
|
|
18
|
-
return key in preferences;
|
|
19
|
-
};
|
|
20
|
-
exports.hasPreference = hasPreference;
|
|
21
|
-
const getPreference = async (key) => {
|
|
22
|
-
const preferences = await getPreferences();
|
|
23
|
-
return preferences[key];
|
|
24
|
-
};
|
|
25
|
-
exports.getPreference = getPreference;
|
|
26
|
-
const setPreference = async (key, value) => {
|
|
27
|
-
const preferences = await getPreferences();
|
|
28
|
-
const newPreferences = {
|
|
29
|
-
...preferences,
|
|
30
|
-
[key]: value,
|
|
31
|
-
};
|
|
32
|
-
await (0, fs_extra_1.writeFile)(file, (0, yaml_1.stringify)(newPreferences));
|
|
33
|
-
};
|
|
34
|
-
exports.setPreference = setPreference;
|
|
35
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/utils/preferences/index.ts"],"names":[],"mappings":";;;AAAA,uCAAuE;AACvE,2BAA6B;AAE7B,+BAAwC;AACxC,MAAM,SAAS,GAAG,GAAG,IAAA,YAAO,GAAE,aAAa,CAAC;AAC5C,MAAM,IAAI,GAAG,GAAG,SAAS,kBAAkB,CAAC;AAE5C,MAAM,cAAc,GAAG,KAAK,IAAI,EAAE;;IAChC,IAAI,CAAC,CAAC,MAAM,IAAA,qBAAU,EAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAA,qBAAU,EAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,CAAC,MAAA,IAAA,YAAK,EAAC,MAAM,IAAA,mBAAQ,EAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,mCAAI,EAAE,CAG/D,CAAC;AACJ,CAAC,CAAC;AAEK,MAAM,aAAa,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;IACjD,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAC3C,OAAO,GAAG,IAAI,WAAW,CAAC;AAC5B,CAAC,CAAC;AAHW,QAAA,aAAa,iBAGxB;AACK,MAAM,aAAa,GAAG,KAAK,EAAE,GAAW,EAAE,EAAE;IACjD,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAC3C,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC,CAAC;AAHW,QAAA,aAAa,iBAGxB;AAEK,MAAM,aAAa,GAAG,KAAK,EAAE,GAAW,EAAE,KAAsB,EAAE,EAAE;IACzE,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAE3C,MAAM,cAAc,GAAG;QACrB,GAAG,WAAW;QACd,CAAC,GAAG,CAAC,EAAE,KAAK;KACb,CAAC;IAEF,MAAM,IAAA,oBAAS,EAAC,IAAI,EAAE,IAAA,gBAAS,EAAC,cAAc,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC;AATW,QAAA,aAAa,iBASxB"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createFile, pathExists, readFile, writeFile } from "fs-extra";
|
|
2
|
-
import { homedir } from "os";
|
|
3
|
-
|
|
4
|
-
import { parse, stringify } from "yaml";
|
|
5
|
-
const directory = `${homedir()}/.catladder`;
|
|
6
|
-
const file = `${directory}/preferences.yml`;
|
|
7
|
-
|
|
8
|
-
const getPreferences = async () => {
|
|
9
|
-
if (!(await pathExists(file))) {
|
|
10
|
-
await createFile(file);
|
|
11
|
-
}
|
|
12
|
-
return (parse(await readFile(file, { encoding: "utf-8" })) ?? {}) as Record<
|
|
13
|
-
string,
|
|
14
|
-
string
|
|
15
|
-
>;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const hasPreference = async (key: string) => {
|
|
19
|
-
const preferences = await getPreferences();
|
|
20
|
-
return key in preferences;
|
|
21
|
-
};
|
|
22
|
-
export const getPreference = async (key: string) => {
|
|
23
|
-
const preferences = await getPreferences();
|
|
24
|
-
return preferences[key];
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const setPreference = async (key: string, value: string | number) => {
|
|
28
|
-
const preferences = await getPreferences();
|
|
29
|
-
|
|
30
|
-
const newPreferences = {
|
|
31
|
-
...preferences,
|
|
32
|
-
[key]: value,
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
await writeFile(file, stringify(newPreferences));
|
|
36
|
-
};
|
|
File without changes
|