@mxpicture/gcp-functions-code 0.2.0
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/changelog/ChangeDetector.d.ts +25 -0
- package/dist/changelog/ChangeDetector.js +47 -0
- package/dist/changelog/Changelog.d.ts +15 -0
- package/dist/changelog/Changelog.js +98 -0
- package/dist/changelog/changelog.util.d.ts +94 -0
- package/dist/changelog/changelog.util.js +228 -0
- package/dist/changelog/index.d.ts +3 -0
- package/dist/changelog/index.js +4 -0
- package/dist/common/code.common.d.ts +17 -0
- package/dist/common/code.common.js +65 -0
- package/dist/common/hash.common.d.ts +1 -0
- package/dist/common/hash.common.js +2 -0
- package/dist/common/index.d.ts +4 -0
- package/dist/common/index.js +5 -0
- package/dist/common/string.common.d.ts +4 -0
- package/dist/common/string.common.js +8 -0
- package/dist/common/types.common.d.ts +20 -0
- package/dist/common/types.common.js +1 -0
- package/dist/deps/IFixWorkspaceDeps.d.ts +21 -0
- package/dist/deps/IFixWorkspaceDeps.js +76 -0
- package/dist/deps/fixWorkspaceDeps.d.ts +12 -0
- package/dist/deps/fixWorkspaceDeps.js +43 -0
- package/dist/deps/index.d.ts +2 -0
- package/dist/deps/index.js +3 -0
- package/dist/git/GitChanges.d.ts +33 -0
- package/dist/git/GitChanges.js +85 -0
- package/dist/git/git.util.d.ts +9 -0
- package/dist/git/git.util.js +33 -0
- package/dist/git/index.d.ts +3 -0
- package/dist/git/index.js +4 -0
- package/dist/git/types.git.d.ts +22 -0
- package/dist/git/types.git.js +1 -0
- package/dist/scripts/fix-workspace-deps.d.ts +2 -0
- package/dist/scripts/fix-workspace-deps.js +14 -0
- package/dist/scripts/generate-barrels.d.ts +1 -0
- package/dist/scripts/generate-barrels.js +81 -0
- package/dist/scripts/generate-changelog.d.ts +1 -0
- package/dist/scripts/generate-changelog.js +13 -0
- package/dist/scripts/index.d.ts +3 -0
- package/dist/scripts/index.js +4 -0
- package/dist/vscode/OSUser.d.ts +15 -0
- package/dist/vscode/OSUser.js +62 -0
- package/dist/vscode/VSCodeSettings.d.ts +10 -0
- package/dist/vscode/VSCodeSettings.js +41 -0
- package/dist/vscode/VSCodeWorkspace.d.ts +20 -0
- package/dist/vscode/VSCodeWorkspace.js +44 -0
- package/dist/vscode/common.vscode.d.ts +4 -0
- package/dist/vscode/common.vscode.js +17 -0
- package/dist/vscode/config.vscode.d.ts +2 -0
- package/dist/vscode/config.vscode.js +4 -0
- package/dist/vscode/index.d.ts +10 -0
- package/dist/vscode/index.js +11 -0
- package/dist/vscode/profiles.vscode.d.ts +5 -0
- package/dist/vscode/profiles.vscode.js +29 -0
- package/dist/vscode/storage.vscode.d.ts +3 -0
- package/dist/vscode/storage.vscode.js +15 -0
- package/dist/vscode/types.vscode.d.ts +36 -0
- package/dist/vscode/types.vscode.js +6 -0
- package/dist/vscode/workspaceAsync.vscode.d.ts +2 -0
- package/dist/vscode/workspaceAsync.vscode.js +54 -0
- package/dist/vscode/workspaceSync.vscode.d.ts +4 -0
- package/dist/vscode/workspaceSync.vscode.js +73 -0
- package/package.json +53 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MapEntry, ProcessMode, PackageEntry } from "../changelog/changelog.util.js";
|
|
2
|
+
export interface FixWorkspaceDepsMain {
|
|
3
|
+
mapEntries: MapEntry[];
|
|
4
|
+
consumingPkg: PackageEntry;
|
|
5
|
+
versionMap: Map<string, string>;
|
|
6
|
+
workspacePackages: Set<string>;
|
|
7
|
+
}
|
|
8
|
+
export interface FixWorkspaceDepsParams extends FixWorkspaceDepsMain {
|
|
9
|
+
pkg: string;
|
|
10
|
+
version: string;
|
|
11
|
+
}
|
|
12
|
+
export declare abstract class IFixWorkspaceDeps {
|
|
13
|
+
readonly repoRoot: string;
|
|
14
|
+
readonly mode: ProcessMode;
|
|
15
|
+
constructor(repoRoot: string, mode: ProcessMode);
|
|
16
|
+
protected abstract fixVersion(p: FixWorkspaceDepsParams): string | null;
|
|
17
|
+
protected abstract restoreVersion(p: FixWorkspaceDepsParams): string | null;
|
|
18
|
+
run(): Promise<void>;
|
|
19
|
+
protected handleDependencies(deps: Record<string, string> | undefined, p: FixWorkspaceDepsMain): boolean;
|
|
20
|
+
protected runSingle(p: FixWorkspaceDepsMain): boolean;
|
|
21
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { buildMapEntries, readPackageJsons, writePackageJsons, } from "../changelog/changelog.util.js";
|
|
2
|
+
export class IFixWorkspaceDeps {
|
|
3
|
+
repoRoot;
|
|
4
|
+
mode;
|
|
5
|
+
constructor(repoRoot, mode) {
|
|
6
|
+
this.repoRoot = repoRoot;
|
|
7
|
+
this.mode = mode;
|
|
8
|
+
}
|
|
9
|
+
async run() {
|
|
10
|
+
if (this.mode === "fix")
|
|
11
|
+
console.log("🔧 Fixing workspace dependencies...\n");
|
|
12
|
+
else
|
|
13
|
+
console.log("🔧 Restoring workspace dependencies...\n");
|
|
14
|
+
const pkgs = await readPackageJsons(this.repoRoot);
|
|
15
|
+
const mapEntries = buildMapEntries(pkgs);
|
|
16
|
+
const versionMap = new Map();
|
|
17
|
+
const workspacePackages = new Set();
|
|
18
|
+
for (const pkg of pkgs) {
|
|
19
|
+
versionMap.set(pkg.content.name, pkg.content.version);
|
|
20
|
+
workspacePackages.add(pkg.content.name);
|
|
21
|
+
}
|
|
22
|
+
console.log("📋 Version map:");
|
|
23
|
+
for (const map of mapEntries)
|
|
24
|
+
console.log(` ${map.fromPkg.content.name} --> ${map.toPkg.content.name}: ${map.relPath}`);
|
|
25
|
+
console.log();
|
|
26
|
+
for (const consumingPkg of pkgs) {
|
|
27
|
+
console.log(`📦 Processing ${consumingPkg.content.name}...`);
|
|
28
|
+
try {
|
|
29
|
+
consumingPkg.modified = this.runSingle({
|
|
30
|
+
consumingPkg,
|
|
31
|
+
mapEntries,
|
|
32
|
+
versionMap,
|
|
33
|
+
workspacePackages,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
console.error(`\nError processing ${consumingPkg.content.name}:`, err);
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
await writePackageJsons(pkgs);
|
|
42
|
+
if (this.mode === "fix")
|
|
43
|
+
console.log("✅ Done fixing workspace dependencies!");
|
|
44
|
+
else
|
|
45
|
+
console.log("✅ Done restoring workspace dependencies!");
|
|
46
|
+
}
|
|
47
|
+
// Replace workspace:* with file:...
|
|
48
|
+
handleDependencies(deps, p) {
|
|
49
|
+
if (!deps)
|
|
50
|
+
return false;
|
|
51
|
+
const handler = this.mode === "fix" ? this.fixVersion : this.restoreVersion;
|
|
52
|
+
let modified = false;
|
|
53
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
54
|
+
const newVersion = handler({ ...p, pkg: name, version });
|
|
55
|
+
if (!newVersion)
|
|
56
|
+
continue;
|
|
57
|
+
console.log(` ✓ Replaced ${name}: ${version} → ${newVersion}`);
|
|
58
|
+
deps[name] = newVersion;
|
|
59
|
+
modified = true;
|
|
60
|
+
}
|
|
61
|
+
return modified;
|
|
62
|
+
}
|
|
63
|
+
runSingle(p) {
|
|
64
|
+
let modified = false;
|
|
65
|
+
modified =
|
|
66
|
+
this.handleDependencies(p.consumingPkg.content.dependencies, p) ||
|
|
67
|
+
modified;
|
|
68
|
+
modified =
|
|
69
|
+
this.handleDependencies(p.consumingPkg.content.devDependencies, p) ||
|
|
70
|
+
modified;
|
|
71
|
+
modified =
|
|
72
|
+
this.handleDependencies(p.consumingPkg.content.peerDependencies, p) ||
|
|
73
|
+
modified;
|
|
74
|
+
return modified;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ProcessMode } from "../changelog/changelog.util.js";
|
|
2
|
+
import { FixWorkspaceDepsParams, IFixWorkspaceDeps } from "./IFixWorkspaceDeps.js";
|
|
3
|
+
export declare const runFixDepsByVersion: (repoRoot: string, mode: ProcessMode) => Promise<void>;
|
|
4
|
+
export declare const runFixDepsByFile: (repoRoot: string, mode: ProcessMode) => Promise<void>;
|
|
5
|
+
export declare class FixWorkspaceDepsVersion extends IFixWorkspaceDeps {
|
|
6
|
+
protected fixVersion(p: FixWorkspaceDepsParams): string | null;
|
|
7
|
+
protected restoreVersion(p: FixWorkspaceDepsParams): string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare class FixWorkspaceDepsFile extends IFixWorkspaceDeps {
|
|
10
|
+
protected fixVersion(p: FixWorkspaceDepsParams): string | null;
|
|
11
|
+
protected restoreVersion(p: FixWorkspaceDepsParams): string | null;
|
|
12
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { IFixWorkspaceDeps, } from "./IFixWorkspaceDeps.js";
|
|
2
|
+
export const runFixDepsByVersion = async (repoRoot, mode) => new FixWorkspaceDepsVersion(repoRoot, mode).run();
|
|
3
|
+
export const runFixDepsByFile = async (repoRoot, mode) => new FixWorkspaceDepsFile(repoRoot, mode).run();
|
|
4
|
+
export class FixWorkspaceDepsVersion extends IFixWorkspaceDeps {
|
|
5
|
+
fixVersion(p) {
|
|
6
|
+
if (p.version !== "workspace:*")
|
|
7
|
+
return null;
|
|
8
|
+
const actualVersion = p.versionMap.get(p.pkg);
|
|
9
|
+
if (!actualVersion) {
|
|
10
|
+
console.error(` ERROR: Could not find version for workspace dependency ${p.pkg}`);
|
|
11
|
+
throw new Error(`Cannot resolve workspace dependency: ${p.pkg}`);
|
|
12
|
+
}
|
|
13
|
+
return `^${actualVersion}`;
|
|
14
|
+
}
|
|
15
|
+
restoreVersion(p) {
|
|
16
|
+
if (p.workspacePackages.has(p.pkg) && p.version.startsWith("^")) {
|
|
17
|
+
// Verify the version matches what fix script would have created
|
|
18
|
+
const actualVersion = p.versionMap.get(p.pkg);
|
|
19
|
+
if (actualVersion && p.version === `^${actualVersion}`) {
|
|
20
|
+
return "workspace:*";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class FixWorkspaceDepsFile extends IFixWorkspaceDeps {
|
|
27
|
+
fixVersion(p) {
|
|
28
|
+
if (p.version !== "workspace:*")
|
|
29
|
+
return null;
|
|
30
|
+
const mapEntry = p.mapEntries.find((mapEntry) => mapEntry.fromPkg.content.name === p.consumingPkg.content.name &&
|
|
31
|
+
mapEntry.toPkg.content.name === p.pkg);
|
|
32
|
+
if (!mapEntry) {
|
|
33
|
+
console.error(` ERROR: Could not find version for workspace dependency ${p.pkg}`);
|
|
34
|
+
throw new Error(`Cannot resolve workspace dependency: ${p.pkg}`);
|
|
35
|
+
}
|
|
36
|
+
return `file:${mapEntry.relPath}`;
|
|
37
|
+
}
|
|
38
|
+
restoreVersion(p) {
|
|
39
|
+
if (!p.version.startsWith("file:"))
|
|
40
|
+
return null;
|
|
41
|
+
return "workspace:*";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { GitChangedResult, GitChangedContentsResult } from "./types.git.js";
|
|
2
|
+
export declare class GitChanges {
|
|
3
|
+
readonly rootDir: string;
|
|
4
|
+
protected _sinceCommit: string | null;
|
|
5
|
+
constructor(rootDir: string);
|
|
6
|
+
set sinceCommit(sinceCommit: string);
|
|
7
|
+
get sinceCommit(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Checks if a specific file or directory has been changed since a given git commit.
|
|
10
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
11
|
+
*
|
|
12
|
+
* @param target - Relative path to the file or directory to check.
|
|
13
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
14
|
+
* @returns A result object indicating whether changes were detected.
|
|
15
|
+
*/
|
|
16
|
+
hasChanged(path: string): Promise<GitChangedResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Reads the current content of all files that have changed since a given git commit
|
|
19
|
+
* within a specific file or directory scope.
|
|
20
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
21
|
+
*
|
|
22
|
+
* Deleted files are excluded from the result since they no longer exist on disk.
|
|
23
|
+
*
|
|
24
|
+
* @param target - Relative path to the file or directory to check.
|
|
25
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
26
|
+
* @param cwd - The working directory of the git repository (defaults to process.cwd()).
|
|
27
|
+
* @returns A result object containing the current content of each changed file.
|
|
28
|
+
*/
|
|
29
|
+
readChangedFiles(readContent?: boolean): Promise<GitChangedContentsResult>;
|
|
30
|
+
}
|
|
31
|
+
export declare class GitChangesCommit extends GitChanges {
|
|
32
|
+
constructor(rootDir: string, sinceCommit: string);
|
|
33
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { verifiedGit } from "./git.util.js";
|
|
5
|
+
export class GitChanges {
|
|
6
|
+
rootDir;
|
|
7
|
+
_sinceCommit = null;
|
|
8
|
+
constructor(rootDir) {
|
|
9
|
+
this.rootDir = rootDir;
|
|
10
|
+
}
|
|
11
|
+
set sinceCommit(sinceCommit) {
|
|
12
|
+
this._sinceCommit = sinceCommit;
|
|
13
|
+
}
|
|
14
|
+
get sinceCommit() {
|
|
15
|
+
if (!this._sinceCommit)
|
|
16
|
+
throw new Error("SinceCommit missing");
|
|
17
|
+
return this._sinceCommit;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Checks if a specific file or directory has been changed since a given git commit.
|
|
21
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
22
|
+
*
|
|
23
|
+
* @param target - Relative path to the file or directory to check.
|
|
24
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
25
|
+
* @returns A result object indicating whether changes were detected.
|
|
26
|
+
*/
|
|
27
|
+
async hasChanged(path) {
|
|
28
|
+
const sinceCommit = this.sinceCommit;
|
|
29
|
+
const resolvedTarget = resolve(this.rootDir, path);
|
|
30
|
+
if (!existsSync(resolvedTarget)) {
|
|
31
|
+
throw new Error(`Target path does not exist: ${resolvedTarget}`);
|
|
32
|
+
}
|
|
33
|
+
const git = await verifiedGit(this.rootDir, sinceCommit);
|
|
34
|
+
// Compare commit to working directory (includes uncommitted changes)
|
|
35
|
+
const diff = await git.diffSummary([sinceCommit, "--", path]);
|
|
36
|
+
const changedFiles = diff.files.map((file) => file.file);
|
|
37
|
+
return {
|
|
38
|
+
path,
|
|
39
|
+
sinceCommit,
|
|
40
|
+
hasChanged: changedFiles.length > 0,
|
|
41
|
+
changedFiles,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reads the current content of all files that have changed since a given git commit
|
|
46
|
+
* within a specific file or directory scope.
|
|
47
|
+
* Includes both committed and uncommitted changes (staged + unstaged).
|
|
48
|
+
*
|
|
49
|
+
* Deleted files are excluded from the result since they no longer exist on disk.
|
|
50
|
+
*
|
|
51
|
+
* @param target - Relative path to the file or directory to check.
|
|
52
|
+
* @param sinceCommit - The git commit hash (or ref like a tag/branch) to compare against.
|
|
53
|
+
* @param cwd - The working directory of the git repository (defaults to process.cwd()).
|
|
54
|
+
* @returns A result object containing the current content of each changed file.
|
|
55
|
+
*/
|
|
56
|
+
async readChangedFiles(readContent) {
|
|
57
|
+
const sinceCommit = this.sinceCommit;
|
|
58
|
+
const git = await verifiedGit(this.rootDir, sinceCommit);
|
|
59
|
+
// Compare commit to working directory (includes uncommitted changes)
|
|
60
|
+
const diff = await git.diffSummary([sinceCommit, "--", this.rootDir]);
|
|
61
|
+
const files = [];
|
|
62
|
+
for (const entry of diff.files) {
|
|
63
|
+
const repoFilePath = entry.file;
|
|
64
|
+
const absFilePath = resolve(this.rootDir, repoFilePath);
|
|
65
|
+
// Skip deleted files — they no longer exist on disk
|
|
66
|
+
if (!existsSync(absFilePath)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// Read from the file system to capture uncommitted changes
|
|
70
|
+
const content = readContent ? await readFile(absFilePath, "utf-8") : null;
|
|
71
|
+
files.push({ absFilePath, content, repoFilePath });
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
path: this.rootDir,
|
|
75
|
+
sinceCommit,
|
|
76
|
+
files,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export class GitChangesCommit extends GitChanges {
|
|
81
|
+
constructor(rootDir, sinceCommit) {
|
|
82
|
+
super(rootDir);
|
|
83
|
+
this.sinceCommit = sinceCommit;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SimpleGit } from "simple-git";
|
|
2
|
+
import { GitCommitHash } from "./types.git.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a SimpleGit instance and verifies the cwd is a repo
|
|
5
|
+
* and the commit ref is valid.
|
|
6
|
+
*/
|
|
7
|
+
export declare const verifiedGit: (rootDir: string, commitRef?: string) => Promise<SimpleGit>;
|
|
8
|
+
export declare const lastCommitHash: (rootDir: string) => Promise<string | null>;
|
|
9
|
+
export declare const commitHashs: (rootDir: string) => Promise<GitCommitHash[]>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { simpleGit } from "simple-git";
|
|
2
|
+
const __entries = [];
|
|
3
|
+
/**
|
|
4
|
+
* Creates a SimpleGit instance and verifies the cwd is a repo
|
|
5
|
+
* and the commit ref is valid.
|
|
6
|
+
*/
|
|
7
|
+
export const verifiedGit = async (rootDir, commitRef) => {
|
|
8
|
+
let found = __entries.find((entry) => entry.rootDir === rootDir && entry.commitRef === commitRef);
|
|
9
|
+
if (!found) {
|
|
10
|
+
found = await verifyGit(simpleGit(rootDir), rootDir, commitRef);
|
|
11
|
+
__entries.push(found);
|
|
12
|
+
}
|
|
13
|
+
return found.git;
|
|
14
|
+
};
|
|
15
|
+
const verifyGit = async (git, rootDir, commitRef) => {
|
|
16
|
+
if (!(await git.checkIsRepo()))
|
|
17
|
+
throw new Error(`Not a git repository: ${rootDir}`);
|
|
18
|
+
if (!commitRef)
|
|
19
|
+
return { git, rootDir, commitRef };
|
|
20
|
+
try {
|
|
21
|
+
await git.revparse(["--verify", commitRef]);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
throw new Error(`Invalid git commit reference: "${commitRef}"`);
|
|
25
|
+
}
|
|
26
|
+
return { git, rootDir, commitRef };
|
|
27
|
+
};
|
|
28
|
+
export const lastCommitHash = async (rootDir) => (await (await verifiedGit(rootDir)).log()).latest?.hash ?? null;
|
|
29
|
+
export const commitHashs = async (rootDir) => (await (await verifiedGit(rootDir)).log()).all.map((a) => ({
|
|
30
|
+
date: a.date,
|
|
31
|
+
hash: a.hash,
|
|
32
|
+
diff: a.diff,
|
|
33
|
+
}));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DiffResult } from "simple-git";
|
|
2
|
+
export interface GitChangedResult {
|
|
3
|
+
path: string;
|
|
4
|
+
sinceCommit: string;
|
|
5
|
+
hasChanged: boolean;
|
|
6
|
+
changedFiles: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface GitChangedContent {
|
|
9
|
+
absFilePath: string;
|
|
10
|
+
repoFilePath: string;
|
|
11
|
+
content: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface GitChangedContentsResult {
|
|
14
|
+
path: string;
|
|
15
|
+
sinceCommit: string;
|
|
16
|
+
files: GitChangedContent[];
|
|
17
|
+
}
|
|
18
|
+
export interface GitCommitHash {
|
|
19
|
+
hash: string;
|
|
20
|
+
date: string;
|
|
21
|
+
diff?: DiffResult;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
import { Argument, program } from "@commander-js/extra-typings";
|
|
3
|
+
import { argv } from "node:process";
|
|
4
|
+
import { runFixDepsByVersion } from "../deps/fixWorkspaceDeps.js";
|
|
5
|
+
import { VSCodeWorkspace } from "../vscode/VSCodeWorkspace.js";
|
|
6
|
+
program
|
|
7
|
+
.version("1.0.0")
|
|
8
|
+
.description("Fix/restore workspace dependencies CLI")
|
|
9
|
+
.addArgument(new Argument("<mode>", "fix / restore").choices(["fix", "restore"]))
|
|
10
|
+
.action(async (mode) => {
|
|
11
|
+
const repoRoot = (await VSCodeWorkspace.loadAsync()).root;
|
|
12
|
+
await runFixDepsByVersion(repoRoot, mode);
|
|
13
|
+
});
|
|
14
|
+
program.parse(argv);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { basename, dirname, join } from "node:path";
|
|
2
|
+
import { readdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { VSCodeWorkspace } from "../vscode/VSCodeWorkspace.js";
|
|
4
|
+
// ─── Configuration ───────────────────────────────────────────────────────────
|
|
5
|
+
// /** File patterns to exclude from barrel exports */
|
|
6
|
+
const EXCLUDED_PATTERNS = [
|
|
7
|
+
/\.test\.ts$/,
|
|
8
|
+
/\.spec\.ts$/,
|
|
9
|
+
/\.d\.ts$/,
|
|
10
|
+
/index\.ts$/,
|
|
11
|
+
];
|
|
12
|
+
// /** Header comment added to every generated barrel file */
|
|
13
|
+
const HEADER = "// This file is auto-generated. Do not edit manually.\n";
|
|
14
|
+
const isExcluded = (fileName) => EXCLUDED_PATTERNS.some((pattern) => pattern.test(fileName));
|
|
15
|
+
// ─── Generator ───────────────────────────────────────────────────────────────
|
|
16
|
+
const createBarrels = async () => {
|
|
17
|
+
const rootDir = (await VSCodeWorkspace.loadAsync()).root;
|
|
18
|
+
const packagesDir = join(rootDir, "packages");
|
|
19
|
+
const packages = (await readdir(packagesDir)).map((p) => join(packagesDir, p));
|
|
20
|
+
const promises = [];
|
|
21
|
+
for (const pkg of packages) {
|
|
22
|
+
try {
|
|
23
|
+
const baseDirPath = join(pkg, "src");
|
|
24
|
+
const items = (await readdir(baseDirPath, { recursive: true })).sort();
|
|
25
|
+
let currentGroup;
|
|
26
|
+
for (const item of items) {
|
|
27
|
+
const filename = basename(item);
|
|
28
|
+
if (isExcluded(filename) || !filename.endsWith(".ts"))
|
|
29
|
+
continue;
|
|
30
|
+
const dirPath = join(baseDirPath, dirname(item));
|
|
31
|
+
if (dirPath !== currentGroup?.dirPath) {
|
|
32
|
+
if (currentGroup)
|
|
33
|
+
promises.push(persistBarrel({ ...currentGroup }));
|
|
34
|
+
currentGroup = { dirPath, files: [] };
|
|
35
|
+
}
|
|
36
|
+
currentGroup.files.push(filename);
|
|
37
|
+
}
|
|
38
|
+
if (currentGroup)
|
|
39
|
+
promises.push(persistBarrel({ ...currentGroup }));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
await Promise.all(promises);
|
|
46
|
+
};
|
|
47
|
+
const persistBarrel = async (group) => {
|
|
48
|
+
if (group.files.length === 0)
|
|
49
|
+
return;
|
|
50
|
+
const content = `${HEADER}${group.files
|
|
51
|
+
.sort()
|
|
52
|
+
.map((f) => `export * from "./${basename(f, ".ts")}.js";`)
|
|
53
|
+
.join("\n")}\n`;
|
|
54
|
+
const barrelPath = join(group.dirPath, "index.ts");
|
|
55
|
+
return writeFile(barrelPath, content);
|
|
56
|
+
};
|
|
57
|
+
// ─── Entry Point ─────────────────────────────────────────────────────────────
|
|
58
|
+
const run = async () => {
|
|
59
|
+
await createBarrels();
|
|
60
|
+
// // Allow overriding paths via CLI arguments:
|
|
61
|
+
// // npx tsx scripts/generate-barrels.ts ./src/hooks ./src/types
|
|
62
|
+
// const cliPaths = process.argv.slice(2);
|
|
63
|
+
// const paths = cliPaths.length > 0 ? cliPaths : BARREL_PATHS;
|
|
64
|
+
// console.log("🛢️ Generating barrel files...\n");
|
|
65
|
+
// console.log(
|
|
66
|
+
// `📂 Target directories:\n${paths
|
|
67
|
+
// .map((p) => ` - ${resolve(p)}`)
|
|
68
|
+
// .join("\n")}\n`,
|
|
69
|
+
// );
|
|
70
|
+
// let generated = 0;
|
|
71
|
+
// for (const targetPath of paths) {
|
|
72
|
+
// const resolved = resolve(targetPath);
|
|
73
|
+
// if (await generateBarrel(resolved)) {
|
|
74
|
+
// generated++;
|
|
75
|
+
// }
|
|
76
|
+
// }
|
|
77
|
+
// console.log(
|
|
78
|
+
// `\n🎉 Done! Barrels generated for ${generated}/${paths.length} directories.`,
|
|
79
|
+
// );
|
|
80
|
+
};
|
|
81
|
+
run().catch(console.error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const runGenerateChangelog: () => Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Changelog } from "../changelog/Changelog.js";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { VSCodeWorkspace } from "../vscode/VSCodeWorkspace.js";
|
|
5
|
+
import { GitChanges } from "../git/GitChanges.js";
|
|
6
|
+
export const runGenerateChangelog = async () => {
|
|
7
|
+
const generator = new Changelog(new GitChanges((await VSCodeWorkspace.loadAsync()).root));
|
|
8
|
+
await generator.run();
|
|
9
|
+
};
|
|
10
|
+
const entryPath = process.argv[1] ? resolve(process.argv[1]) : "";
|
|
11
|
+
const selfPath = fileURLToPath(import.meta.url);
|
|
12
|
+
if (entryPath === selfPath)
|
|
13
|
+
await runGenerateChangelog();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface OSInfo {
|
|
2
|
+
homedir: string;
|
|
3
|
+
username: string;
|
|
4
|
+
platform: NodeJS.Platform;
|
|
5
|
+
configDir: string;
|
|
6
|
+
isWSL?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare class OSUser {
|
|
9
|
+
protected static info?: OSInfo;
|
|
10
|
+
static getInfo(): OSInfo;
|
|
11
|
+
protected constructor();
|
|
12
|
+
protected static load(): void;
|
|
13
|
+
protected static getWSL(): OSInfo;
|
|
14
|
+
protected static getDefault(): OSInfo;
|
|
15
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import * as os from "os";
|
|
3
|
+
import { join, sep } from "path";
|
|
4
|
+
export class OSUser {
|
|
5
|
+
static info;
|
|
6
|
+
static getInfo() {
|
|
7
|
+
this.load();
|
|
8
|
+
if (!this.info)
|
|
9
|
+
throw new Error("Load OS info failed");
|
|
10
|
+
return this.info;
|
|
11
|
+
}
|
|
12
|
+
constructor() { }
|
|
13
|
+
static load() {
|
|
14
|
+
if (this.info)
|
|
15
|
+
return;
|
|
16
|
+
const isWSL = os.release().toLowerCase().includes("microsoft");
|
|
17
|
+
this.info = isWSL ? this.getWSL() : this.getDefault();
|
|
18
|
+
}
|
|
19
|
+
static getWSL() {
|
|
20
|
+
const whoamiParts = execSync("whoami.exe").toString().split(sep);
|
|
21
|
+
if (whoamiParts.length === 0)
|
|
22
|
+
throw new Error("Windows user could not be determined");
|
|
23
|
+
// const winUser = process.env["WINUSER"] || process.env["USER"];
|
|
24
|
+
const platform = process.platform;
|
|
25
|
+
let username = whoamiParts[whoamiParts.length - 1];
|
|
26
|
+
// remove AD group
|
|
27
|
+
const userParts = username.split("\\");
|
|
28
|
+
username = userParts[userParts.length - 1];
|
|
29
|
+
username = username.replace("\r", "").replace("\n", "");
|
|
30
|
+
const parts = ["/mnt", "c", "Users", username];
|
|
31
|
+
const homedir = join(...parts);
|
|
32
|
+
const configDir = join(homedir, "AppData", "Roaming");
|
|
33
|
+
return {
|
|
34
|
+
username,
|
|
35
|
+
homedir,
|
|
36
|
+
configDir,
|
|
37
|
+
platform,
|
|
38
|
+
isWSL: true,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
static getDefault() {
|
|
42
|
+
const platform = process.platform;
|
|
43
|
+
const homedir = os.homedir();
|
|
44
|
+
const configDirParts = [];
|
|
45
|
+
if (platform === "win32") {
|
|
46
|
+
if (process.env.APPDATA)
|
|
47
|
+
configDirParts.push(process.env.APPDATA);
|
|
48
|
+
}
|
|
49
|
+
else if (platform === "darwin") {
|
|
50
|
+
configDirParts.push(homedir, "Library", "Application Support");
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
configDirParts.push(homedir, ".config");
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
username: os.userInfo().username,
|
|
57
|
+
homedir,
|
|
58
|
+
platform,
|
|
59
|
+
configDir: join(...configDirParts),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type VSCodeSettingsContent = Record<string, unknown>;
|
|
2
|
+
export declare class VSCodeSettings {
|
|
3
|
+
protected static instance: VSCodeSettings | undefined;
|
|
4
|
+
protected content: VSCodeSettingsContent;
|
|
5
|
+
static load(): VSCodeSettings;
|
|
6
|
+
protected constructor(content: VSCodeSettingsContent);
|
|
7
|
+
getProperty(name: string): unknown;
|
|
8
|
+
getContent(): VSCodeSettingsContent;
|
|
9
|
+
getClangFormatStyle(): string | undefined;
|
|
10
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import pkg from "json5";
|
|
3
|
+
import { activeProfile, defaultSettingsPath } from "./profiles.vscode.js";
|
|
4
|
+
export class VSCodeSettings {
|
|
5
|
+
static instance;
|
|
6
|
+
content;
|
|
7
|
+
static load() {
|
|
8
|
+
if (this.instance)
|
|
9
|
+
return this.instance;
|
|
10
|
+
let settingsPath;
|
|
11
|
+
try {
|
|
12
|
+
// check profile
|
|
13
|
+
settingsPath = activeProfile().settingsPath;
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
// check default
|
|
18
|
+
settingsPath = defaultSettingsPath();
|
|
19
|
+
}
|
|
20
|
+
if (!settingsPath)
|
|
21
|
+
throw new Error("No settings path found");
|
|
22
|
+
const raw = fs.readFileSync(settingsPath, "utf-8");
|
|
23
|
+
this.instance = new VSCodeSettings(pkg.parse(raw));
|
|
24
|
+
return this.instance;
|
|
25
|
+
}
|
|
26
|
+
constructor(content) {
|
|
27
|
+
this.content = content;
|
|
28
|
+
}
|
|
29
|
+
getProperty(name) {
|
|
30
|
+
return this.getContent()[name];
|
|
31
|
+
}
|
|
32
|
+
getContent() {
|
|
33
|
+
return { ...this.content };
|
|
34
|
+
}
|
|
35
|
+
getClangFormatStyle() {
|
|
36
|
+
const value = this.getProperty("C_Cpp.clang_format_style");
|
|
37
|
+
if (typeof value !== "string")
|
|
38
|
+
throw new Error("C_Cpp.clang_format_style not found in settings.json");
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface VSCodeWorkspaceFolder {
|
|
2
|
+
path: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
uri?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface VSCodeWorkspaceContent {
|
|
7
|
+
folders: VSCodeWorkspaceFolder[];
|
|
8
|
+
settings?: Record<string, unknown>;
|
|
9
|
+
launch?: Record<string, unknown>;
|
|
10
|
+
extensions?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare class VSCodeWorkspace {
|
|
13
|
+
readonly workspaceFile: string;
|
|
14
|
+
readonly content: VSCodeWorkspaceContent;
|
|
15
|
+
protected static instances: VSCodeWorkspace[];
|
|
16
|
+
static load(workspaceFile?: string): VSCodeWorkspace;
|
|
17
|
+
static loadAsync(workspaceFile?: string): Promise<VSCodeWorkspace>;
|
|
18
|
+
protected constructor(workspaceFile: string, content: VSCodeWorkspaceContent);
|
|
19
|
+
get root(): string;
|
|
20
|
+
}
|