@smoothbricks/cli 0.1.0 → 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/README.md +338 -88
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +136 -22
- package/dist/devenv/index.d.ts +10 -0
- package/dist/devenv/index.d.ts.map +1 -0
- package/dist/devenv/index.js +27 -0
- package/dist/lib/cli-package.d.ts +4 -0
- package/dist/lib/cli-package.d.ts.map +1 -0
- package/dist/lib/cli-package.js +15 -0
- package/dist/lib/devenv.d.ts +6 -0
- package/dist/lib/devenv.d.ts.map +1 -0
- package/dist/lib/devenv.js +82 -0
- package/dist/lib/run.d.ts +5 -0
- package/dist/lib/run.d.ts.map +1 -1
- package/dist/lib/run.js +13 -0
- package/dist/lib/workspace.d.ts +20 -1
- package/dist/lib/workspace.d.ts.map +1 -1
- package/dist/lib/workspace.js +87 -7
- package/dist/monorepo/commit-msg.d.ts +8 -1
- package/dist/monorepo/commit-msg.d.ts.map +1 -1
- package/dist/monorepo/commit-msg.js +85 -7
- package/dist/monorepo/index.d.ts +24 -2
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +136 -15
- package/dist/monorepo/lockfile.d.ts +5 -1
- package/dist/monorepo/lockfile.d.ts.map +1 -1
- package/dist/monorepo/lockfile.js +45 -5
- package/dist/monorepo/managed-files.d.ts +1 -1
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +28 -11
- package/dist/monorepo/nx-sync.d.ts +2 -1
- package/dist/monorepo/nx-sync.d.ts.map +1 -1
- package/dist/monorepo/nx-sync.js +8 -2
- package/dist/monorepo/package-hygiene.d.ts +6 -2
- package/dist/monorepo/package-hygiene.d.ts.map +1 -1
- package/dist/monorepo/package-hygiene.js +12 -4
- package/dist/monorepo/package-policy.d.ts +25 -2
- package/dist/monorepo/package-policy.d.ts.map +1 -1
- package/dist/monorepo/package-policy.js +1289 -27
- package/dist/monorepo/packed-manifest.d.ts +4 -0
- package/dist/monorepo/packed-manifest.d.ts.map +1 -0
- package/dist/monorepo/packed-manifest.js +51 -0
- package/dist/monorepo/packed-package.d.ts +3 -0
- package/dist/monorepo/packed-package.d.ts.map +1 -1
- package/dist/monorepo/packed-package.js +69 -31
- package/dist/monorepo/packs/index.d.ts +20 -1
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +240 -18
- package/dist/monorepo/publish-workflow.d.ts +82 -0
- package/dist/monorepo/publish-workflow.d.ts.map +1 -0
- package/dist/monorepo/publish-workflow.js +336 -0
- package/dist/monorepo/tool-validation.d.ts +22 -0
- package/dist/monorepo/tool-validation.d.ts.map +1 -0
- package/dist/monorepo/tool-validation.js +399 -0
- package/dist/nx/index.d.ts +24 -0
- package/dist/nx/index.d.ts.map +1 -0
- package/dist/nx/index.js +94 -0
- package/dist/nx-version-actions.cjs +25 -0
- package/dist/nx-version-actions.d.cts +6 -0
- package/dist/nx-version-actions.d.cts.map +1 -0
- package/dist/release/bootstrap-npm-packages.d.ts +19 -0
- package/dist/release/bootstrap-npm-packages.d.ts.map +1 -0
- package/dist/release/bootstrap-npm-packages.js +58 -0
- package/dist/release/candidates.d.ts +11 -0
- package/dist/release/candidates.d.ts.map +1 -0
- package/dist/release/candidates.js +181 -0
- package/dist/release/core.d.ts +51 -0
- package/dist/release/core.d.ts.map +1 -0
- package/dist/release/core.js +97 -0
- package/dist/release/github-release.d.ts +46 -0
- package/dist/release/github-release.d.ts.map +1 -0
- package/dist/release/github-release.js +97 -0
- package/dist/release/index.d.ts +39 -5
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +763 -130
- package/dist/release/npm-auth.d.ts +16 -0
- package/dist/release/npm-auth.d.ts.map +1 -0
- package/dist/release/npm-auth.js +39 -0
- package/dist/release/orchestration.d.ts +49 -0
- package/dist/release/orchestration.d.ts.map +1 -0
- package/dist/release/orchestration.js +113 -0
- package/dist/release/publish-plan.d.ts +17 -0
- package/dist/release/publish-plan.d.ts.map +1 -0
- package/dist/release/publish-plan.js +15 -0
- package/dist/release/retag-unpublished.d.ts +34 -0
- package/dist/release/retag-unpublished.d.ts.map +1 -0
- package/dist/release/retag-unpublished.js +77 -0
- package/managed/raw/git-format-staged.yml +54 -0
- package/managed/raw/tooling/git-hooks/commit-msg.sh +1 -1
- package/managed/raw/tooling/git-hooks/pre-commit.sh +2 -7
- package/managed/templates/github/actions/setup-devenv/action.yml +1 -7
- package/managed/templates/github/workflows/ci.yml +3 -0
- package/package.json +37 -4
- package/src/cli.ts +193 -40
- package/src/devenv/index.test.ts +49 -0
- package/src/devenv/index.ts +38 -0
- package/src/lib/cli-package.ts +18 -0
- package/src/lib/devenv.test.ts +28 -0
- package/src/lib/devenv.ts +89 -0
- package/src/lib/run.ts +19 -0
- package/src/lib/workspace.ts +117 -7
- package/src/monorepo/__tests__/nx-version-actions.test.ts +75 -0
- package/src/monorepo/__tests__/publish-workflow.test.ts +322 -0
- package/src/monorepo/commit-msg.test.ts +45 -0
- package/src/monorepo/commit-msg.ts +107 -7
- package/src/monorepo/index.ts +181 -15
- package/src/monorepo/lockfile.ts +52 -7
- package/src/monorepo/managed-files.ts +43 -13
- package/src/monorepo/nx-sync.ts +9 -2
- package/src/monorepo/package-hygiene.test.ts +34 -0
- package/src/monorepo/package-hygiene.ts +26 -4
- package/src/monorepo/package-policy.test.ts +902 -0
- package/src/monorepo/package-policy.ts +1527 -25
- package/src/monorepo/packed-manifest.ts +67 -0
- package/src/monorepo/packed-package.ts +90 -31
- package/src/monorepo/packs/index.test.ts +189 -0
- package/src/monorepo/packs/index.ts +314 -19
- package/src/monorepo/publish-workflow.ts +422 -0
- package/src/monorepo/setup-test-tracing.test.ts +120 -0
- package/src/monorepo/tool-validation.test.ts +261 -0
- package/src/monorepo/tool-validation.ts +462 -0
- package/src/nx/index.test.ts +64 -0
- package/src/nx/index.ts +119 -0
- package/src/nx-version-actions.cts +36 -0
- package/src/release/__tests__/bootstrap-npm-packages.test.ts +127 -0
- package/src/release/__tests__/candidates.test.ts +217 -0
- package/src/release/__tests__/core-properties.test.ts +149 -0
- package/src/release/__tests__/core-scenarios.test.ts +187 -0
- package/src/release/__tests__/core.test.ts +73 -0
- package/src/release/__tests__/fixture-repo.test.ts +314 -0
- package/src/release/__tests__/github-release.test.ts +149 -0
- package/src/release/__tests__/helpers/fixture-repo.ts +114 -0
- package/src/release/__tests__/npm-auth.test.ts +120 -0
- package/src/release/__tests__/orchestration.test.ts +246 -0
- package/src/release/__tests__/publish-plan.test.ts +67 -0
- package/src/release/__tests__/retag-unpublished.test.ts +160 -0
- package/src/release/__tests__/trust-publisher.test.ts +133 -0
- package/src/release/bootstrap-npm-packages.ts +88 -0
- package/src/release/candidates.ts +225 -0
- package/src/release/core.ts +171 -0
- package/src/release/github-release.ts +134 -0
- package/src/release/index.ts +974 -138
- package/src/release/npm-auth.ts +93 -0
- package/src/release/orchestration.ts +196 -0
- package/src/release/publish-plan.ts +37 -0
- package/src/release/retag-unpublished.ts +122 -0
- package/managed/raw/.git-format-staged.yml +0 -47
- package/managed/templates/github/workflows/publish.yml +0 -136
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command, CommanderError } from 'commander';
|
|
2
|
+
import { cliPackageVersion } from './lib/cli-package.js';
|
|
2
3
|
import { findRepoRoot } from './lib/run.js';
|
|
3
4
|
export async function runCli(argv = process.argv.slice(2)) {
|
|
4
5
|
const program = buildProgram();
|
|
@@ -19,7 +20,12 @@ export async function runCli(argv = process.argv.slice(2)) {
|
|
|
19
20
|
}
|
|
20
21
|
function buildProgram() {
|
|
21
22
|
const program = new Command();
|
|
22
|
-
program
|
|
23
|
+
program
|
|
24
|
+
.name('smoo')
|
|
25
|
+
.description('SmoothBricks monorepo tooling')
|
|
26
|
+
.version(cliPackageVersion, '-v, --version', 'print smoo version')
|
|
27
|
+
.exitOverride()
|
|
28
|
+
.showHelpAfterError();
|
|
23
29
|
const monorepo = program.command('monorepo').description('Manage SmoothBricks-style monorepos');
|
|
24
30
|
monorepo
|
|
25
31
|
.command('init')
|
|
@@ -31,7 +37,10 @@ function buildProgram() {
|
|
|
31
37
|
});
|
|
32
38
|
monorepo
|
|
33
39
|
.command('validate')
|
|
40
|
+
.option('--fix', 'apply safe monorepo policy fixes before validation')
|
|
34
41
|
.option('--fail-fast', 'stop after the first failing validation pack')
|
|
42
|
+
.option('--only-if-new-workspace-package', 'skip validation unless a new workspace package manifest is staged')
|
|
43
|
+
.option('--verbose', 'print validation progress and successful checks')
|
|
35
44
|
.action(async (options) => {
|
|
36
45
|
const { validateMonorepo } = await import('./monorepo/index.js');
|
|
37
46
|
await validateMonorepo(await findRepoRoot(), options);
|
|
@@ -48,70 +57,175 @@ function buildProgram() {
|
|
|
48
57
|
const { diffManagedFiles } = await import('./monorepo/index.js');
|
|
49
58
|
diffManagedFiles(await findRepoRoot());
|
|
50
59
|
});
|
|
51
|
-
monorepo
|
|
60
|
+
monorepo
|
|
61
|
+
.command('validate-commit-msg <commitMsgFile>')
|
|
62
|
+
.option('--fix', 'format the commit message before validation')
|
|
63
|
+
.action(async (commitMsgFile, options) => {
|
|
52
64
|
const { validateCommitMessageFile } = await import('./monorepo/index.js');
|
|
53
|
-
validateCommitMessageFile(commitMsgFile);
|
|
65
|
+
validateCommitMessageFile(commitMsgFile, options, await findRepoRoot());
|
|
54
66
|
});
|
|
55
67
|
monorepo.command('sync-bun-lockfile-versions').action(async () => {
|
|
56
68
|
const { syncBunLockfileVersions } = await import('./monorepo/index.js');
|
|
57
69
|
syncBunLockfileVersions(await findRepoRoot());
|
|
58
70
|
});
|
|
59
|
-
monorepo
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
monorepo
|
|
72
|
+
.command('list-release-packages')
|
|
73
|
+
.option('--fail-empty', 'fail when no owned release packages are found')
|
|
74
|
+
.option('--github-output <path>', 'append projects=<nx-projects> to a GitHub Actions output file')
|
|
75
|
+
.action(async (options) => {
|
|
76
|
+
const { listReleaseProjectNamesForNx } = await import('./monorepo/index.js');
|
|
77
|
+
const packages = listReleaseProjectNamesForNx(await findRepoRoot(), options);
|
|
78
|
+
if (!options.githubOutput) {
|
|
79
|
+
console.log(packages);
|
|
80
|
+
}
|
|
62
81
|
});
|
|
63
82
|
monorepo.command('validate-public-tags').action(async () => {
|
|
64
83
|
const { validatePublicPackageTags } = await import('./monorepo/index.js');
|
|
65
84
|
validatePublicPackageTags(await findRepoRoot());
|
|
66
85
|
});
|
|
67
|
-
monorepo
|
|
86
|
+
monorepo
|
|
87
|
+
.command('setup-test-tracing')
|
|
88
|
+
.description('Configure LMAO Bun test tracing for workspace packages')
|
|
89
|
+
.option('--all', 'configure every workspace package')
|
|
90
|
+
.option('--projects <projects>', 'comma-separated Nx project names, package names, or package roots')
|
|
91
|
+
.option('--op-context-export <exportName>', 'named op context export imported by test-suite-tracer', 'opContext')
|
|
92
|
+
.option('--tracer-module <module>', 'module specifier that exports defineTestTracer', '@smoothbricks/lmao/testing/bun')
|
|
93
|
+
.option('--dry-run', 'print generator invocations without writing files')
|
|
94
|
+
.action(async (options) => {
|
|
95
|
+
const { setupTestTracing } = await import('./monorepo/index.js');
|
|
96
|
+
await setupTestTracing(await findRepoRoot(), options);
|
|
97
|
+
});
|
|
98
|
+
const release = program.command('release').description('Version, publish, and create GitHub Releases');
|
|
99
|
+
release.command('npm-status').action(async () => {
|
|
68
100
|
const { printReleaseState } = await import('./release/index.js');
|
|
69
101
|
await printReleaseState(await findRepoRoot());
|
|
70
102
|
});
|
|
71
|
-
|
|
103
|
+
release
|
|
104
|
+
.command('repair-pending')
|
|
105
|
+
.description('Repair incomplete older release commits before releasing the current HEAD')
|
|
106
|
+
.option('--dry-run [dryRun]', 'run without pushing, publishing, or writing GitHub Releases')
|
|
107
|
+
.action(async (options) => {
|
|
108
|
+
const { releaseRepairPending } = await import('./release/index.js');
|
|
109
|
+
await releaseRepairPending(await findRepoRoot(), { ...options, dryRun: booleanOption(options.dryRun) });
|
|
110
|
+
});
|
|
72
111
|
release
|
|
73
112
|
.command('version')
|
|
74
113
|
.option('--bump <bump>', 'auto, patch, minor, major, or prerelease', 'auto')
|
|
75
|
-
.option('--dry-run [dryRun]', 'run without writing versions
|
|
114
|
+
.option('--dry-run [dryRun]', 'run without writing versions or tags')
|
|
115
|
+
.option('--github-output <path>', 'append mode=<mode> and projects=<nx-projects> to a GitHub Actions output file')
|
|
76
116
|
.action(async (options) => {
|
|
77
117
|
const { releaseVersion } = await import('./release/index.js');
|
|
78
|
-
await releaseVersion(await findRepoRoot(), {
|
|
118
|
+
await releaseVersion(await findRepoRoot(), {
|
|
119
|
+
bump: options.bump,
|
|
120
|
+
dryRun: booleanOption(options.dryRun),
|
|
121
|
+
githubOutput: options.githubOutput,
|
|
122
|
+
});
|
|
79
123
|
});
|
|
80
124
|
release
|
|
81
125
|
.command('publish')
|
|
82
126
|
.option('--bump <bump>', 'auto, patch, minor, major, or prerelease', 'auto')
|
|
83
|
-
.option('--
|
|
84
|
-
.option('--npm-tag <npmTag>', 'explicit npm dist-tag; must match bump-derived tag')
|
|
85
|
-
.option('--dry-run [dryRun]', 'run without publishing')
|
|
127
|
+
.option('--dry-run [dryRun]', 'run without pushing, publishing, or writing GitHub Releases')
|
|
86
128
|
.action(async (options) => {
|
|
87
129
|
const { releasePublish } = await import('./release/index.js');
|
|
88
130
|
await releasePublish(await findRepoRoot(), { ...options, dryRun: booleanOption(options.dryRun) });
|
|
89
131
|
});
|
|
90
132
|
release
|
|
91
|
-
.command('
|
|
92
|
-
.
|
|
93
|
-
.
|
|
94
|
-
.option('--
|
|
95
|
-
.option('--
|
|
96
|
-
.option('--
|
|
133
|
+
.command('retag-unpublished')
|
|
134
|
+
.description('Move unpublished owned release tags to a later commit without bumping versions')
|
|
135
|
+
.argument('<tag...>', 'owned release tags to move, for example @scope/pkg@1.2.3')
|
|
136
|
+
.option('--to <ref>', 'commit or ref to move tags to', 'HEAD')
|
|
137
|
+
.option('--push', 'push moved tags with force-with-lease')
|
|
138
|
+
.option('--dispatch', 'push moved tags and start publish.yml with bump=auto')
|
|
139
|
+
.option('--remote <remote>', 'git remote used for pushed tags')
|
|
140
|
+
.option('--branch <branch>', 'branch used for publish workflow dispatch')
|
|
141
|
+
.option('--dry-run [dryRun]', 'validate and print the retag operation without mutating refs')
|
|
142
|
+
.action(async (tags, options) => {
|
|
143
|
+
const { releaseRetagUnpublished } = await import('./release/index.js');
|
|
144
|
+
await releaseRetagUnpublished(await findRepoRoot(), {
|
|
145
|
+
tags,
|
|
146
|
+
to: options.to,
|
|
147
|
+
push: options.push === true,
|
|
148
|
+
dispatch: options.dispatch === true,
|
|
149
|
+
remote: options.remote,
|
|
150
|
+
branch: options.branch,
|
|
151
|
+
dryRun: booleanOption(options.dryRun),
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
release
|
|
155
|
+
.command('bootstrap-npm-packages')
|
|
156
|
+
.alias('bootstrap')
|
|
157
|
+
.description('Publish minimal npm placeholder packages so trusted publishing can be configured')
|
|
158
|
+
.option('--dry-run [dryRun]', 'show placeholder publishes without logging in or publishing')
|
|
159
|
+
.option('--skip-login', 'skip npm browser login before publishing placeholders')
|
|
160
|
+
.option('--otp <otp>', 'npm one-time password for placeholder publish operations')
|
|
161
|
+
.option('--package <name...>', 'only bootstrap the selected owned release package names')
|
|
97
162
|
.action(async (options) => {
|
|
98
|
-
const {
|
|
99
|
-
await
|
|
163
|
+
const { releaseBootstrapNpmPackages } = await import('./release/index.js');
|
|
164
|
+
await releaseBootstrapNpmPackages(await findRepoRoot(), {
|
|
165
|
+
dryRun: booleanOption(options.dryRun),
|
|
166
|
+
skipLogin: options.skipLogin === true,
|
|
167
|
+
otp: options.otp,
|
|
168
|
+
packages: options.package ?? [],
|
|
169
|
+
});
|
|
100
170
|
});
|
|
101
171
|
release
|
|
102
172
|
.command('trust-publisher')
|
|
103
|
-
.description('Configure npm trusted publishing for
|
|
173
|
+
.description('Configure npm trusted publishing for owned release packages')
|
|
104
174
|
.option('--dry-run [dryRun]', 'show npm trust changes without saving them')
|
|
175
|
+
.option('--bootstrap', 'publish missing npm placeholder packages before configuring trust')
|
|
105
176
|
.option('--otp <otp>', 'npm one-time password for trust operations')
|
|
177
|
+
.option('--bootstrap-otp <otp>', 'npm one-time password for placeholder publishes during --bootstrap')
|
|
106
178
|
.option('--skip-login', 'skip npm browser login before configuring trust')
|
|
107
179
|
.action(async (options) => {
|
|
108
180
|
const { releaseTrustPublisher } = await import('./release/index.js');
|
|
109
181
|
await releaseTrustPublisher(await findRepoRoot(), {
|
|
110
182
|
dryRun: booleanOption(options.dryRun),
|
|
183
|
+
bootstrap: options.bootstrap === true,
|
|
111
184
|
otp: options.otp,
|
|
185
|
+
bootstrapOtp: options.bootstrapOtp,
|
|
112
186
|
skipLogin: options.skipLogin === true,
|
|
113
187
|
});
|
|
114
188
|
});
|
|
189
|
+
const devenv = program.command('devenv').description('Manage the repository devenv shell');
|
|
190
|
+
devenv.command('update').action(async () => {
|
|
191
|
+
const { updateDevenv } = await import('./devenv/index.js');
|
|
192
|
+
await updateDevenv(await findRepoRoot());
|
|
193
|
+
});
|
|
194
|
+
devenv.command('reload').action(async () => {
|
|
195
|
+
const { reloadDevenv } = await import('./devenv/index.js');
|
|
196
|
+
await reloadDevenv(await findRepoRoot());
|
|
197
|
+
});
|
|
198
|
+
const nixpkgsOverlay = program.command('nixpkgs-overlay').description('Manage the repository nixpkgs overlay');
|
|
199
|
+
nixpkgsOverlay.command('update').action(async () => {
|
|
200
|
+
const { updateNixpkgsOverlay } = await import('./devenv/index.js');
|
|
201
|
+
await updateNixpkgsOverlay(await findRepoRoot());
|
|
202
|
+
});
|
|
203
|
+
const nx = program.command('nx').description('Nx workspace helpers');
|
|
204
|
+
nx.command('list-targets')
|
|
205
|
+
.description('List project:target entries for every Nx project')
|
|
206
|
+
.action(async () => {
|
|
207
|
+
const { listTargets } = await import('./nx/index.js');
|
|
208
|
+
await listTargets(await findRepoRoot());
|
|
209
|
+
});
|
|
210
|
+
nx.command('list-projects')
|
|
211
|
+
.description('List Nx projects matching filters')
|
|
212
|
+
.requiredOption('--with-target <target>', 'only include projects defining this target')
|
|
213
|
+
.action(async (options) => {
|
|
214
|
+
const { listProjects } = await import('./nx/index.js');
|
|
215
|
+
await listProjects(await findRepoRoot(), options);
|
|
216
|
+
});
|
|
217
|
+
nx.command('reset-cache')
|
|
218
|
+
.description('Run nx reset to clear Nx daemon and cache state')
|
|
219
|
+
.action(async () => {
|
|
220
|
+
const { resetCache } = await import('./nx/index.js');
|
|
221
|
+
await resetCache(await findRepoRoot());
|
|
222
|
+
});
|
|
223
|
+
nx.command('clean-cache')
|
|
224
|
+
.description('Remove local Nx cache directories when present')
|
|
225
|
+
.action(async () => {
|
|
226
|
+
const { cleanCache } = await import('./nx/index.js');
|
|
227
|
+
await cleanCache(await findRepoRoot());
|
|
228
|
+
});
|
|
115
229
|
const githubCi = program.command('github-ci').description('GitHub Actions helpers');
|
|
116
230
|
githubCi.command('cleanup-cache').action(async () => {
|
|
117
231
|
const { cleanupGithubCiCache } = await import('./github-ci/index.js');
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface DevenvCommandShell {
|
|
2
|
+
run(command: string, args: string[], cwd: string): Promise<void>;
|
|
3
|
+
remove(path: string): Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
export declare function updateDevenv(root: string, shell?: DevenvCommandShell): Promise<void>;
|
|
6
|
+
export declare function reloadDevenv(root: string, shell?: DevenvCommandShell): Promise<void>;
|
|
7
|
+
export declare function updateNixpkgsOverlay(root: string, shell?: DevenvCommandShell): Promise<void>;
|
|
8
|
+
export declare function direnvRoot(root: string): string;
|
|
9
|
+
export declare function nixpkgsOverlayRoot(root: string): string;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/devenv/index.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AASD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,kBAAiC,GAAG,OAAO,CAAC,IAAI,CAAC,CAExG;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,kBAAiC,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxG;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,kBAAiC,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhH;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { rm } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { run } from '../lib/run.js';
|
|
4
|
+
const defaultShell = {
|
|
5
|
+
run,
|
|
6
|
+
async remove(path) {
|
|
7
|
+
await rm(path, { recursive: true, force: true });
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
export async function updateDevenv(root, shell = defaultShell) {
|
|
11
|
+
await shell.run('devenv', ['update'], direnvRoot(root));
|
|
12
|
+
}
|
|
13
|
+
export async function reloadDevenv(root, shell = defaultShell) {
|
|
14
|
+
const cwd = direnvRoot(root);
|
|
15
|
+
await shell.remove(join(cwd, '.direnv'));
|
|
16
|
+
await shell.remove(join(cwd, '.devenv'));
|
|
17
|
+
await shell.run('direnv', ['reload'], cwd);
|
|
18
|
+
}
|
|
19
|
+
export async function updateNixpkgsOverlay(root, shell = defaultShell) {
|
|
20
|
+
await shell.run('nix', ['shell', 'nixpkgs#nvfetcher', '-c', 'nvfetcher', '-o', '_sources'], nixpkgsOverlayRoot(root));
|
|
21
|
+
}
|
|
22
|
+
export function direnvRoot(root) {
|
|
23
|
+
return join(root, 'tooling', 'direnv');
|
|
24
|
+
}
|
|
25
|
+
export function nixpkgsOverlayRoot(root) {
|
|
26
|
+
return join(direnvRoot(root), 'nixpkgs-overlay');
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-package.d.ts","sourceRoot":"","sources":["../../src/lib/cli-package.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AACxE,eAAO,MAAM,iBAAiB,QAA0B,CAAC;AAWzD,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEnF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import { readJsonObject, stringProperty } from './json.js';
|
|
3
|
+
export const smoothBricksCodebasePackageName = '@smoothbricks/codebase';
|
|
4
|
+
export const cliPackageVersion = readCliPackageVersion();
|
|
5
|
+
function readCliPackageVersion() {
|
|
6
|
+
const pkg = readJsonObject(fileURLToPath(new URL('../../package.json', import.meta.url)));
|
|
7
|
+
const version = pkg ? stringProperty(pkg, 'version') : null;
|
|
8
|
+
if (!version) {
|
|
9
|
+
throw new Error('Unable to read @smoothbricks/cli package version.');
|
|
10
|
+
}
|
|
11
|
+
return version;
|
|
12
|
+
}
|
|
13
|
+
export function isSmoothBricksCodebasePackageName(name) {
|
|
14
|
+
return name === smoothBricksCodebasePackageName;
|
|
15
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type EnvSnapshot = Record<string, string>;
|
|
2
|
+
export declare function withDevenvEnv<T>(root: string, runWithEnv: () => Promise<T>): Promise<T>;
|
|
3
|
+
export declare function parseNulEnv(bytes: Uint8Array): EnvSnapshot;
|
|
4
|
+
export declare function mergeDevenvEnv(baseEnv: EnvSnapshot, devenvEnv: EnvSnapshot): EnvSnapshot;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=devenv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devenv.d.ts","sourceRoot":"","sources":["../../src/lib/devenv.ts"],"names":[],"mappings":"AAMA,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C,wBAAsB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAS7F;AAmBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAoB1D;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,GAAG,WAAW,CAExF"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { $ } from 'bun';
|
|
5
|
+
import { decode } from './run.js';
|
|
6
|
+
export async function withDevenvEnv(root, runWithEnv) {
|
|
7
|
+
const snapshot = snapshotProcessEnv();
|
|
8
|
+
const env = await loadDevenvEnv(root);
|
|
9
|
+
replaceProcessEnv(mergeDevenvEnv(snapshot, env));
|
|
10
|
+
try {
|
|
11
|
+
return await runWithEnv();
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
restoreProcessEnv(snapshot);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function loadDevenvEnv(root) {
|
|
18
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'smoo-devenv-env-'));
|
|
19
|
+
const envPath = join(tempDir, 'env');
|
|
20
|
+
try {
|
|
21
|
+
const result = await $ `devenv shell -- bash -lc ${'env -0 > "$1"'} bash ${envPath}`
|
|
22
|
+
.cwd(join(root, 'tooling', 'direnv'))
|
|
23
|
+
.quiet()
|
|
24
|
+
.nothrow();
|
|
25
|
+
if (result.exitCode !== 0) {
|
|
26
|
+
throw new Error('devenv shell failed. Ensure devenv is installed and the tooling/direnv shell is valid.');
|
|
27
|
+
}
|
|
28
|
+
return parseNulEnv(await readFile(envPath));
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function parseNulEnv(bytes) {
|
|
35
|
+
const env = {};
|
|
36
|
+
let entryStart = 0;
|
|
37
|
+
for (let index = 0; index <= bytes.length; index += 1) {
|
|
38
|
+
if (index !== bytes.length && bytes[index] !== 0) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (index === entryStart) {
|
|
42
|
+
entryStart = index + 1;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const entry = decode(bytes.subarray(entryStart, index));
|
|
46
|
+
const separator = entry.indexOf('=');
|
|
47
|
+
if (separator <= 0) {
|
|
48
|
+
throw new Error('devenv shell produced an invalid environment entry.');
|
|
49
|
+
}
|
|
50
|
+
env[entry.slice(0, separator)] = entry.slice(separator + 1);
|
|
51
|
+
entryStart = index + 1;
|
|
52
|
+
}
|
|
53
|
+
return env;
|
|
54
|
+
}
|
|
55
|
+
export function mergeDevenvEnv(baseEnv, devenvEnv) {
|
|
56
|
+
return { ...baseEnv, ...devenvEnv };
|
|
57
|
+
}
|
|
58
|
+
function snapshotProcessEnv() {
|
|
59
|
+
const snapshot = {};
|
|
60
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
61
|
+
if (value !== undefined) {
|
|
62
|
+
snapshot[key] = value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return snapshot;
|
|
66
|
+
}
|
|
67
|
+
function replaceProcessEnv(env) {
|
|
68
|
+
for (const key of Object.keys(process.env)) {
|
|
69
|
+
delete process.env[key];
|
|
70
|
+
}
|
|
71
|
+
for (const [key, value] of Object.entries(env)) {
|
|
72
|
+
process.env[key] = value;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function restoreProcessEnv(snapshot) {
|
|
76
|
+
for (const key of Object.keys(process.env)) {
|
|
77
|
+
delete process.env[key];
|
|
78
|
+
}
|
|
79
|
+
for (const [key, value] of Object.entries(snapshot)) {
|
|
80
|
+
process.env[key] = value;
|
|
81
|
+
}
|
|
82
|
+
}
|
package/dist/lib/run.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export declare function run(command: string, args: string[], cwd: string, env?: Record<string, string>): Promise<void>;
|
|
2
2
|
export declare function runStatus(command: string, args: string[], cwd: string, quiet?: boolean, env?: Record<string, string>): Promise<number>;
|
|
3
|
+
export declare function runResult(command: string, args: string[], cwd: string, env?: Record<string, string>): Promise<{
|
|
4
|
+
exitCode: number;
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
}>;
|
|
3
8
|
export declare function findRepoRoot(): Promise<string>;
|
|
4
9
|
export declare function decode(bytes: Uint8Array): string;
|
|
5
10
|
//# sourceMappingURL=run.d.ts.map
|
package/dist/lib/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/lib/run.ts"],"names":[],"mappings":"AAKA,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnH;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,KAAK,UAAQ,EACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC,MAAM,CAAC,CAQjB;AAuCD,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAMpD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEhD"}
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/lib/run.ts"],"names":[],"mappings":"AAKA,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnH;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,KAAK,UAAQ,EACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAY/D;AAuCD,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAMpD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEhD"}
|
package/dist/lib/run.js
CHANGED
|
@@ -17,6 +17,19 @@ export async function runStatus(command, args, cwd, quiet = false, env) {
|
|
|
17
17
|
const result = quiet ? await shell.quiet() : await shell;
|
|
18
18
|
return result.exitCode;
|
|
19
19
|
}
|
|
20
|
+
export async function runResult(command, args, cwd, env) {
|
|
21
|
+
const invocation = resolveCommandInvocation(cwd, command, args);
|
|
22
|
+
let shell = $ `${invocation.command} ${invocation.args}`.cwd(cwd).nothrow().quiet();
|
|
23
|
+
if (env) {
|
|
24
|
+
shell = shell.env(mergeEnv(env));
|
|
25
|
+
}
|
|
26
|
+
const result = await shell;
|
|
27
|
+
return {
|
|
28
|
+
exitCode: result.exitCode,
|
|
29
|
+
stdout: decode(result.stdout),
|
|
30
|
+
stderr: decode(result.stderr),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
20
33
|
function mergeEnv(env) {
|
|
21
34
|
const merged = {};
|
|
22
35
|
for (const [key, value] of Object.entries(process.env)) {
|
package/dist/lib/workspace.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export interface PackageInfo {
|
|
2
2
|
name: string;
|
|
3
|
+
projectName: string;
|
|
3
4
|
version: string;
|
|
4
5
|
private: boolean;
|
|
5
6
|
tags: string[];
|
|
@@ -7,17 +8,35 @@ export interface PackageInfo {
|
|
|
7
8
|
packageJsonPath: string;
|
|
8
9
|
json: Record<string, unknown>;
|
|
9
10
|
}
|
|
11
|
+
export interface PackageJson extends Record<string, unknown> {
|
|
12
|
+
name?: string;
|
|
13
|
+
version?: string;
|
|
14
|
+
private?: boolean;
|
|
15
|
+
workspaces?: unknown;
|
|
16
|
+
devDependencies?: unknown;
|
|
17
|
+
dependencies?: unknown;
|
|
18
|
+
nx?: unknown;
|
|
19
|
+
repository?: unknown;
|
|
20
|
+
}
|
|
10
21
|
export interface RepositoryInfo {
|
|
11
22
|
type: string;
|
|
12
23
|
url: string;
|
|
13
24
|
}
|
|
14
|
-
export declare const workspaceDependencyFields: readonly ["dependencies", "devDependencies", "optionalDependencies"];
|
|
25
|
+
export declare const workspaceDependencyFields: readonly ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
15
26
|
export declare function listPublicPackages(root: string): PackageInfo[];
|
|
27
|
+
export declare function listReleasePackages(root: string, rootPackage?: PackageInfo | null): PackageInfo[];
|
|
28
|
+
export declare function rootRepositoryInfo(root: string): RepositoryInfo | null;
|
|
29
|
+
export declare function rootPackageName(root: string): string | null;
|
|
30
|
+
export declare function isSmoothBricksCodebase(root: string): boolean;
|
|
31
|
+
export declare function packageRepositoryInfo(pkg: PackageInfo): RepositoryInfo | null;
|
|
32
|
+
export declare function isOwnedPackage(rootRepository: RepositoryInfo, pkg: PackageInfo): boolean;
|
|
16
33
|
export declare function getWorkspacePackages(root: string): PackageInfo[];
|
|
17
34
|
export declare function listPackageJsonRecords(root: string): PackageInfo[];
|
|
18
35
|
export declare function getWorkspacePatterns(root: string): string[];
|
|
19
36
|
export declare function readPackageJson(path: string): PackageInfo | null;
|
|
37
|
+
export declare function readPackageJsonObject(path: string): PackageJson | null;
|
|
20
38
|
export declare function getNxTags(pkg: Record<string, unknown>): string[];
|
|
21
39
|
export declare function repositoryInfo(pkg: Record<string, unknown>): RepositoryInfo | null;
|
|
40
|
+
export declare function sameRepositoryAfterNormalization(left: string, right: string): boolean;
|
|
22
41
|
export declare function escapeRegex(value: string): string;
|
|
23
42
|
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/lib/workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/lib/workspace.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,yBAAyB,0FAK5B,CAAC;AAEX,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAE9D;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,qBAA8C,GACxD,WAAW,EAAE,CAWf;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAGtE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG3D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,WAAW,GAAG,cAAc,GAAG,IAAI,CAE7E;AAED,wBAAgB,cAAc,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAGxF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAMhE;AAiCD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CASlE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAG3D;AAgBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAiBhE;AAOD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAGtE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAKhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,GAAG,IAAI,CAalF;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAErF;AA4BD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
package/dist/lib/workspace.js
CHANGED
|
@@ -1,15 +1,52 @@
|
|
|
1
1
|
import { readdirSync, statSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, relative } from 'node:path';
|
|
3
|
+
import { isSmoothBricksCodebasePackageName } from './cli-package.js';
|
|
3
4
|
import { hasOwn, hasOwnString, isRecord, readJson, readJsonObject, stringProperty } from './json.js';
|
|
4
|
-
export const workspaceDependencyFields = [
|
|
5
|
+
export const workspaceDependencyFields = [
|
|
6
|
+
'dependencies',
|
|
7
|
+
'devDependencies',
|
|
8
|
+
'peerDependencies',
|
|
9
|
+
'optionalDependencies',
|
|
10
|
+
];
|
|
5
11
|
export function listPublicPackages(root) {
|
|
6
12
|
return getWorkspacePackages(root).filter((pkg) => !pkg.private && pkg.tags.includes('npm:public'));
|
|
7
13
|
}
|
|
14
|
+
export function listReleasePackages(root, rootPackage = readPackageJson(join(root, 'package.json'))) {
|
|
15
|
+
if (!rootPackage) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const rootRepository = repositoryInfo(rootPackage.json);
|
|
19
|
+
if (!rootRepository) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
return getWorkspacePackagesForPatterns(root, getWorkspacePatternsFromPackageJson(rootPackage.json)).filter((pkg) => !pkg.private && pkg.tags.includes('npm:public') && isOwnedPackage(rootRepository, pkg));
|
|
23
|
+
}
|
|
24
|
+
export function rootRepositoryInfo(root) {
|
|
25
|
+
const rootPackage = readJsonObject(join(root, 'package.json'));
|
|
26
|
+
return rootPackage ? repositoryInfo(rootPackage) : null;
|
|
27
|
+
}
|
|
28
|
+
export function rootPackageName(root) {
|
|
29
|
+
const rootPackage = readPackageJsonObject(join(root, 'package.json'));
|
|
30
|
+
return rootPackage ? stringProperty(rootPackage, 'name') : null;
|
|
31
|
+
}
|
|
32
|
+
export function isSmoothBricksCodebase(root) {
|
|
33
|
+
return isSmoothBricksCodebasePackageName(rootPackageName(root) ?? undefined);
|
|
34
|
+
}
|
|
35
|
+
export function packageRepositoryInfo(pkg) {
|
|
36
|
+
return repositoryInfo(pkg.json);
|
|
37
|
+
}
|
|
38
|
+
export function isOwnedPackage(rootRepository, pkg) {
|
|
39
|
+
const packageRepository = packageRepositoryInfo(pkg);
|
|
40
|
+
return packageRepository !== null && packageRepository.url === rootRepository.url;
|
|
41
|
+
}
|
|
8
42
|
export function getWorkspacePackages(root) {
|
|
9
|
-
|
|
43
|
+
const rootPackage = readPackageJson(join(root, 'package.json'));
|
|
44
|
+
if (!rootPackage) {
|
|
10
45
|
throw new Error('package.json not found or invalid');
|
|
11
46
|
}
|
|
12
|
-
|
|
47
|
+
return getWorkspacePackagesForPatterns(root, getWorkspacePatternsFromPackageJson(rootPackage.json));
|
|
48
|
+
}
|
|
49
|
+
function getWorkspacePackagesForPatterns(root, workspacePatterns) {
|
|
13
50
|
const packages = [];
|
|
14
51
|
for (const pattern of workspacePatterns) {
|
|
15
52
|
if (!pattern.endsWith('/*')) {
|
|
@@ -27,6 +64,7 @@ export function getWorkspacePackages(root) {
|
|
|
27
64
|
}
|
|
28
65
|
packages.push({
|
|
29
66
|
name: pkg.name,
|
|
67
|
+
projectName: pkg.projectName,
|
|
30
68
|
version: pkg.version,
|
|
31
69
|
private: pkg.private,
|
|
32
70
|
tags: pkg.tags,
|
|
@@ -43,14 +81,20 @@ export function listPackageJsonRecords(root) {
|
|
|
43
81
|
if (!rootPackage) {
|
|
44
82
|
throw new Error('package.json not found or invalid');
|
|
45
83
|
}
|
|
46
|
-
return [
|
|
84
|
+
return [
|
|
85
|
+
{ ...rootPackage, path: '.' },
|
|
86
|
+
...getWorkspacePackagesForPatterns(root, getWorkspacePatternsFromPackageJson(rootPackage.json)),
|
|
87
|
+
];
|
|
47
88
|
}
|
|
48
89
|
export function getWorkspacePatterns(root) {
|
|
49
90
|
const raw = readJson(join(root, 'package.json'));
|
|
50
|
-
|
|
91
|
+
return isRecord(raw) ? getWorkspacePatternsFromPackageJson(raw) : ['packages/*'];
|
|
92
|
+
}
|
|
93
|
+
function getWorkspacePatternsFromPackageJson(pkg) {
|
|
94
|
+
if (!hasOwn(pkg, 'workspaces')) {
|
|
51
95
|
return ['packages/*'];
|
|
52
96
|
}
|
|
53
|
-
const workspaces =
|
|
97
|
+
const workspaces = pkg.workspaces;
|
|
54
98
|
if (Array.isArray(workspaces)) {
|
|
55
99
|
return workspaces.filter((entry) => typeof entry === 'string');
|
|
56
100
|
}
|
|
@@ -60,7 +104,7 @@ export function getWorkspacePatterns(root) {
|
|
|
60
104
|
return ['packages/*'];
|
|
61
105
|
}
|
|
62
106
|
export function readPackageJson(path) {
|
|
63
|
-
const parsed =
|
|
107
|
+
const parsed = readPackageJsonObject(path);
|
|
64
108
|
if (!isRecord(parsed) || !hasOwnString(parsed, 'name') || !hasOwnString(parsed, 'version')) {
|
|
65
109
|
return null;
|
|
66
110
|
}
|
|
@@ -68,6 +112,7 @@ export function readPackageJson(path) {
|
|
|
68
112
|
const tags = getNxTags(parsed);
|
|
69
113
|
return {
|
|
70
114
|
name: parsed.name,
|
|
115
|
+
projectName: packageNxProjectName(parsed),
|
|
71
116
|
version: parsed.version,
|
|
72
117
|
private: privateValue,
|
|
73
118
|
tags,
|
|
@@ -76,6 +121,14 @@ export function readPackageJson(path) {
|
|
|
76
121
|
json: parsed,
|
|
77
122
|
};
|
|
78
123
|
}
|
|
124
|
+
function packageNxProjectName(pkg) {
|
|
125
|
+
const nx = isRecord(pkg.nx) ? pkg.nx : null;
|
|
126
|
+
return (nx ? stringProperty(nx, 'name') : null) ?? stringProperty(pkg, 'name') ?? '';
|
|
127
|
+
}
|
|
128
|
+
export function readPackageJsonObject(path) {
|
|
129
|
+
const parsed = readJsonObject(path);
|
|
130
|
+
return parsed;
|
|
131
|
+
}
|
|
79
132
|
export function getNxTags(pkg) {
|
|
80
133
|
if (!hasOwn(pkg, 'nx') || !isRecord(pkg.nx) || !hasOwn(pkg.nx, 'tags') || !Array.isArray(pkg.nx.tags)) {
|
|
81
134
|
return [];
|
|
@@ -96,6 +149,33 @@ export function repositoryInfo(pkg) {
|
|
|
96
149
|
}
|
|
97
150
|
return { type: stringProperty(repository, 'type') ?? 'git', url };
|
|
98
151
|
}
|
|
152
|
+
export function sameRepositoryAfterNormalization(left, right) {
|
|
153
|
+
return normalizedRepositoryUrl(left) === normalizedRepositoryUrl(right);
|
|
154
|
+
}
|
|
155
|
+
function normalizedRepositoryUrl(url) {
|
|
156
|
+
const trimmed = url
|
|
157
|
+
.trim()
|
|
158
|
+
.replace(/^git\+/, '')
|
|
159
|
+
.replace(/#.*$/, '')
|
|
160
|
+
.replace(/\/$/, '')
|
|
161
|
+
.replace(/\.git$/, '');
|
|
162
|
+
const https = /^https:\/\/github\.com\/([^/]+)\/([^/]+)$/i.exec(trimmed);
|
|
163
|
+
if (https?.[1] && https[2]) {
|
|
164
|
+
return githubRepositoryKey(https[1], https[2]);
|
|
165
|
+
}
|
|
166
|
+
const ssh = /^git@github\.com:([^/]+)\/([^/]+)$/i.exec(trimmed);
|
|
167
|
+
if (ssh?.[1] && ssh[2]) {
|
|
168
|
+
return githubRepositoryKey(ssh[1], ssh[2]);
|
|
169
|
+
}
|
|
170
|
+
const shorthand = /^github:([^/]+)\/([^/]+)$/i.exec(trimmed);
|
|
171
|
+
if (shorthand?.[1] && shorthand[2]) {
|
|
172
|
+
return githubRepositoryKey(shorthand[1], shorthand[2]);
|
|
173
|
+
}
|
|
174
|
+
return trimmed;
|
|
175
|
+
}
|
|
176
|
+
function githubRepositoryKey(owner, repo) {
|
|
177
|
+
return `github:${owner.toLowerCase()}/${repo.toLowerCase()}`;
|
|
178
|
+
}
|
|
99
179
|
export function escapeRegex(value) {
|
|
100
180
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
101
181
|
}
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface FormatCommitMessageOptions {
|
|
2
|
+
wrapBody?: (paragraph: string) => string;
|
|
3
|
+
}
|
|
4
|
+
export interface ValidateCommitMessageOptions {
|
|
5
|
+
validScopes?: ReadonlySet<string>;
|
|
6
|
+
}
|
|
7
|
+
export declare function validateCommitMessage(message: string, options?: ValidateCommitMessageOptions): string | null;
|
|
8
|
+
export declare function formatCommitMessage(message: string, options?: FormatCommitMessageOptions): string;
|
|
2
9
|
//# sourceMappingURL=commit-msg.d.ts.map
|