@catladder/cli 0.0.0-refactor-cli-add-improved-git-utilities-224e6ee7 → 0.0.0-refactor-cli-add-improved-git-utilities-583a3a54

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/package.json CHANGED
@@ -53,7 +53,7 @@
53
53
  }
54
54
  ],
55
55
  "license": "MIT",
56
- "version": "0.0.0-refactor-cli-add-improved-git-utilities-224e6ee7",
56
+ "version": "0.0.0-refactor-cli-add-improved-git-utilities-583a3a54",
57
57
  "scripts": {
58
58
  "lint": "eslint \"src/**/*.ts\"",
59
59
  "lint:fix": "eslint \"src/**/*.ts\" --fix",
@@ -15,6 +15,6 @@ export const gitlabApiClient = async ({
15
15
  }
16
16
  return new Gitlab({
17
17
  token,
18
- host: gitRemoteHost,
18
+ host: `https://${gitRemoteHost}`,
19
19
  });
20
20
  };
@@ -0,0 +1,25 @@
1
+ import type { ProjectSchema } from "@gitbeaker/rest";
2
+ import { getGitRemoteHostAndPath } from "../git/getGitRemoteHostAndPath";
3
+ import { gitlabApiClient } from "./apiClient";
4
+ import {
5
+ upsertProjectPerferences,
6
+ getProjectPreferences,
7
+ } from "../utils/projectPreferences";
8
+
9
+ export const getGitlabProjectInfo = async (): Promise<ProjectSchema> => {
10
+ const api = await gitlabApiClient();
11
+ const { gitRemotePath } = await getGitRemoteHostAndPath();
12
+ const projectInfo = await api.Projects.show(gitRemotePath);
13
+ // write unawaited intentionally
14
+ upsertProjectPerferences({ gitlabProjectId: projectInfo.id });
15
+ return projectInfo;
16
+ };
17
+
18
+ export const getGitlabProjectId = async (): Promise<number> => {
19
+ const { gitlabProjectId } = await getProjectPreferences();
20
+ if (gitlabProjectId) {
21
+ return gitlabProjectId;
22
+ }
23
+ const projectInfo = await getGitlabProjectInfo();
24
+ return projectInfo.id;
25
+ };
@@ -1,9 +1,11 @@
1
- import { createFile, pathExists, readFile, writeFile } from "fs-extra";
1
+ import { writeFile, readFile, mkdir } from "fs/promises";
2
+ import { existsSync } from "fs";
2
3
  import { homedir } from "os";
3
-
4
4
  import { parse, stringify } from "yaml";
5
- const directory = `${homedir()}/.catladder`;
6
- const file = `${directory}/preferences.yml`;
5
+ import { join } from "path";
6
+
7
+ const directory = join(homedir(), ".catladder");
8
+ const file = join(directory, "preferences.yml");
7
9
 
8
10
  export type CatladderCliPreferences = {
9
11
  "gitlab-personal-access-token": string | null;
@@ -15,7 +17,7 @@ const perfKeys = [
15
17
  "gitlab-personal-access-token",
16
18
  "googleAuthUserNumber",
17
19
  "gitlabTokens",
18
- ] as const;
20
+ ] as const satisfies readonly PreferenceKey[];
19
21
 
20
22
  const fallbackValues = {
21
23
  "gitlab-personal-access-token": null,
@@ -23,23 +25,47 @@ const fallbackValues = {
23
25
  googleAuthUserNumber: null,
24
26
  } satisfies CatladderCliPreferences;
25
27
 
26
- export const getPreferences = async (): Promise<CatladderCliPreferences> => {
27
- if (!(await pathExists(file))) {
28
- await createFile(file);
29
- }
30
- const fileString = await readFile(file, { encoding: "utf-8" });
31
- const fileParsed = parse(fileString || "---\nnull") ?? {};
32
- return perfKeys.reduce(
28
+ const perferencesWithParsed = (
29
+ parsed: Partial<CatladderCliPreferences>,
30
+ ): CatladderCliPreferences =>
31
+ perfKeys.reduce(
33
32
  (acc, key) =>
34
- Object.assign(acc, { [key]: fileParsed[key] ?? fallbackValues[key] }),
33
+ Object.assign(acc, { [key]: parsed[key] ?? fallbackValues[key] }),
35
34
  {} as CatladderCliPreferences,
36
35
  );
36
+
37
+ const encoding = "utf-8";
38
+
39
+ const readPreferences = () => readFile(file, { encoding });
40
+
41
+ const writePreferences = (preferences: CatladderCliPreferences) =>
42
+ writeFile(file, stringify(preferences), { encoding, mode: 0o600 });
43
+
44
+ const ensureDir = async () =>
45
+ existsSync(directory)
46
+ ? directory
47
+ : mkdir(directory, { recursive: true, mode: 0o700 });
48
+
49
+ const ensureFile = async () => {
50
+ if (existsSync(file)) {
51
+ return file;
52
+ }
53
+ await ensureDir();
54
+ return writePreferences(perferencesWithParsed({}));
55
+ };
56
+
57
+ export const getPreferences = async (): Promise<CatladderCliPreferences> => {
58
+ await ensureFile();
59
+ const fileString = await readPreferences();
60
+ const fileParsed = parse(fileString || "---\nnull") ?? {};
61
+ return perferencesWithParsed(fileParsed);
37
62
  };
38
63
 
39
64
  export const hasPreference = async (key: PreferenceKey) => {
40
65
  const preferences = await getPreferences();
41
66
  return preferences[key] !== null && preferences[key] !== undefined;
42
67
  };
68
+
43
69
  export const getPreference = async <K extends PreferenceKey>(
44
70
  key: K,
45
71
  ): Promise<CatladderCliPreferences[K] | null> => {
@@ -55,11 +81,5 @@ export const setPreference = async (
55
81
  value: CatladderCliPreferences[typeof key],
56
82
  ) => {
57
83
  const preferences = await getPreferences();
58
-
59
- const newPreferences = {
60
- ...preferences,
61
- [key]: value,
62
- };
63
-
64
- await writeFile(file, stringify(newPreferences));
84
+ return writePreferences({ ...preferences, [key]: value });
65
85
  };
@@ -0,0 +1,81 @@
1
+ import { writeFile, readFile, mkdir } from "fs/promises";
2
+ import { existsSync } from "fs";
3
+ import { join } from "path";
4
+ import { getProjectRootPath } from "../git";
5
+
6
+ const directory = ".catladder";
7
+ const file = "preferences.json";
8
+
9
+ export type CatladderCliProjectPreferences = {
10
+ gitlabProjectId?: number | null;
11
+ gitlabHttpUrlToRepo?: string | null;
12
+ };
13
+ type ProjectPreferenceKey = keyof CatladderCliProjectPreferences;
14
+ const perfKeys = [
15
+ "gitlabProjectId",
16
+ "gitlabHttpUrlToRepo",
17
+ ] as const satisfies readonly ProjectPreferenceKey[];
18
+ const fallbackValues = {
19
+ gitlabProjectId: null,
20
+ gitlabHttpUrlToRepo: null,
21
+ } satisfies CatladderCliProjectPreferences;
22
+
23
+ const perferencesWithParsed = (
24
+ parsed: Partial<CatladderCliProjectPreferences>,
25
+ ): CatladderCliProjectPreferences =>
26
+ perfKeys.reduce(
27
+ (acc, key) =>
28
+ Object.assign(acc, { [key]: parsed[key] ?? fallbackValues[key] ?? null }),
29
+ {} as CatladderCliProjectPreferences,
30
+ );
31
+
32
+ const encoding = "utf-8";
33
+
34
+ const readPreferences = (filePath: string) => readFile(filePath, { encoding });
35
+
36
+ const writePreferences = (
37
+ filePath: string,
38
+ preferences: CatladderCliProjectPreferences,
39
+ ) =>
40
+ writeFile(filePath, JSON.stringify(preferences, null, 2), {
41
+ encoding,
42
+ mode: 0o600,
43
+ });
44
+
45
+ const ensureDir = async (dirPath: string) =>
46
+ existsSync(dirPath)
47
+ ? dirPath
48
+ : mkdir(dirPath, { recursive: true, mode: 0o700 });
49
+
50
+ const ensureFile = async (givenFilePath?: string) => {
51
+ if (givenFilePath?.length && existsSync(givenFilePath)) {
52
+ return givenFilePath;
53
+ }
54
+ const rootPath = await getProjectRootPath();
55
+ const dirPath = join(rootPath, directory);
56
+ const filePath = join(dirPath, file);
57
+ if (existsSync(filePath)) {
58
+ return filePath;
59
+ }
60
+ await ensureDir(dirPath);
61
+ await writePreferences(filePath, perferencesWithParsed({}));
62
+ return filePath;
63
+ };
64
+
65
+ export const getProjectPreferences = async (
66
+ givenFilePath?: string,
67
+ ): Promise<CatladderCliProjectPreferences> => {
68
+ const filePath = await ensureFile(givenFilePath);
69
+ const fileString = await readPreferences(filePath);
70
+ const fileParsed = JSON.parse(fileString || "null") ?? {};
71
+ return perferencesWithParsed(fileParsed);
72
+ };
73
+
74
+ export const upsertProjectPerferences = async (
75
+ newPerfs: Partial<CatladderCliProjectPreferences> = {},
76
+ givenFilePath?: string,
77
+ ) => {
78
+ const filePath = await ensureFile(givenFilePath);
79
+ const currentPerfs = await getProjectPreferences(filePath);
80
+ return writePreferences(filePath, { ...currentPerfs, ...newPerfs });
81
+ };