@smoothbricks/cli 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +5 -2
- package/dist/github-ci/index.js +4 -3
- package/dist/lib/conflict-markers.d.ts.map +1 -1
- package/dist/lib/workspace.d.ts +1 -1
- package/dist/lib/workspace.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.js +1 -0
- package/dist/monorepo/lockfile.d.ts +2 -0
- package/dist/monorepo/lockfile.d.ts.map +1 -1
- package/dist/monorepo/lockfile.js +13 -2
- package/dist/monorepo/managed-files.d.ts +1 -0
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +12 -5
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +1 -0
- package/dist/monorepo/tool-validation.d.ts.map +1 -1
- package/dist/monorepo/tool-validation.js +20 -7
- package/dist/release/github-release.d.ts +2 -2
- package/dist/wrangler/prepare-env.d.ts.map +1 -1
- package/dist/wrangler/prepare-env.js +1 -1
- package/dist/wrangler/scaffold.d.ts.map +1 -1
- package/dist/wrangler/scaffold.js +1 -1
- package/managed/raw/tooling/direnv/setup-environment.ts +2 -8
- package/managed/raw/tooling/git-hooks/pre-commit.sh +6 -0
- package/package.json +3 -13
- package/src/cli.ts +7 -4
- package/src/github-ci/index.ts +5 -3
- package/src/monorepo/__tests__/ci-workflow.test.ts +2 -0
- package/src/monorepo/__tests__/publish-workflow.test.ts +12 -4
- package/src/monorepo/ci-workflow.ts +2 -0
- package/src/monorepo/lockfile.test.ts +157 -0
- package/src/monorepo/lockfile.ts +15 -2
- package/src/monorepo/managed-files.test.ts +13 -0
- package/src/monorepo/managed-files.ts +20 -5
- package/src/monorepo/package-policy.test.ts +7 -37
- package/src/monorepo/publish-workflow.ts +2 -0
- package/src/monorepo/tool-validation.test.ts +59 -24
- package/src/monorepo/tool-validation.ts +21 -7
- package/src/monorepo/wrangler.test.ts +9 -2
- package/src/release/__tests__/fixture-repo.test.ts +8 -0
- package/src/release/__tests__/helpers/fixture-repo.ts +28 -8
- package/src/wrangler/prepare-env.ts +14 -4
- package/src/wrangler/scaffold.ts +8 -3
|
@@ -82,9 +82,14 @@ export async function writeBuildablePackage(
|
|
|
82
82
|
);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
export async function git(
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
export async function git(
|
|
86
|
+
root: string,
|
|
87
|
+
args: string[],
|
|
88
|
+
env?: Record<string, string>,
|
|
89
|
+
timeoutMs = GIT_TIMEOUT_MS,
|
|
90
|
+
): Promise<void> {
|
|
91
|
+
const result = await gitResult(root, args, env, timeoutMs);
|
|
92
|
+
if (result.timedOut || result.exitCode !== 0) {
|
|
88
93
|
throw new Error(gitErrorMessage(root, args, result));
|
|
89
94
|
}
|
|
90
95
|
}
|
|
@@ -101,9 +106,15 @@ export async function gitSucceeds(root: string, args: string[]): Promise<boolean
|
|
|
101
106
|
return (await gitResult(root, args)).exitCode === 0;
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
async function gitResult(
|
|
109
|
+
async function gitResult(
|
|
110
|
+
root: string,
|
|
111
|
+
args: string[],
|
|
112
|
+
env?: Record<string, string>,
|
|
113
|
+
timeoutMs = GIT_TIMEOUT_MS,
|
|
114
|
+
): Promise<GitResult> {
|
|
105
115
|
const proc = Bun.spawn(['git', ...args], {
|
|
106
116
|
cwd: root,
|
|
117
|
+
detached: true,
|
|
107
118
|
env: { ...process.env, ...GIT_FIXTURE_ENV, ...env },
|
|
108
119
|
stdout: 'pipe',
|
|
109
120
|
stderr: 'pipe',
|
|
@@ -111,15 +122,23 @@ async function gitResult(root: string, args: string[], env?: Record<string, stri
|
|
|
111
122
|
let timedOut = false;
|
|
112
123
|
const timeout = setTimeout(() => {
|
|
113
124
|
timedOut = true;
|
|
114
|
-
|
|
115
|
-
|
|
125
|
+
try {
|
|
126
|
+
// `git` may exit after spawning a transport or hook which still owns its
|
|
127
|
+
// pipes. Killing the detached process group closes every inherited pipe.
|
|
128
|
+
process.kill(-proc.pid, 'SIGKILL');
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (!(error instanceof Error && 'code' in error && error.code === 'ESRCH')) {
|
|
131
|
+
proc.kill('SIGKILL');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}, timeoutMs);
|
|
116
135
|
try {
|
|
117
136
|
const [exitCode, stdout, stderr] = await Promise.all([
|
|
118
137
|
proc.exited,
|
|
119
138
|
streamBytes(proc.stdout),
|
|
120
139
|
streamBytes(proc.stderr),
|
|
121
140
|
]);
|
|
122
|
-
return { exitCode, stdout, stderr, timedOut };
|
|
141
|
+
return { exitCode, stdout, stderr, timedOut, timeoutMs };
|
|
123
142
|
} finally {
|
|
124
143
|
clearTimeout(timeout);
|
|
125
144
|
}
|
|
@@ -151,12 +170,13 @@ interface GitResult {
|
|
|
151
170
|
stdout: Uint8Array;
|
|
152
171
|
stderr: Uint8Array;
|
|
153
172
|
timedOut: boolean;
|
|
173
|
+
timeoutMs: number;
|
|
154
174
|
}
|
|
155
175
|
|
|
156
176
|
function gitErrorMessage(root: string, args: string[], result: GitResult): string {
|
|
157
177
|
const stderr = new TextDecoder().decode(result.stderr).trim();
|
|
158
178
|
const timeoutText = result.timedOut
|
|
159
|
-
? ` timed out after ${
|
|
179
|
+
? ` timed out after ${result.timeoutMs}ms`
|
|
160
180
|
: ` failed with exit code ${result.exitCode}`;
|
|
161
181
|
return [`git ${args.join(' ')}${timeoutText}`, `cwd: ${root}`, stderr].filter(Boolean).join('\n');
|
|
162
182
|
}
|
|
@@ -60,7 +60,13 @@ function kvIn(toml: string, table: AST.TOMLTable, key: string): AST.TOMLKeyValue
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/** The `<field>` KV of the `[[env.<env>.<arrayKey>]]` table whose `binding` matches, or null. */
|
|
63
|
-
function arrayTableKv(
|
|
63
|
+
function arrayTableKv(
|
|
64
|
+
toml: string,
|
|
65
|
+
env: string,
|
|
66
|
+
arrayKey: string,
|
|
67
|
+
binding: string,
|
|
68
|
+
field: string,
|
|
69
|
+
): AST.TOMLKeyValue | null {
|
|
64
70
|
const block = envRecord(toml, env);
|
|
65
71
|
const rows = isRecord(block) && Array.isArray(block[arrayKey]) ? block[arrayKey] : [];
|
|
66
72
|
const index = rows.findIndex((r) => isRecord(r) && r.binding === binding);
|
|
@@ -173,7 +179,8 @@ export function getD1Name(toml: string, env: string, binding: string): string |
|
|
|
173
179
|
const block = envRecord(toml, env);
|
|
174
180
|
const rows = isRecord(block) && Array.isArray(block.d1_databases) ? block.d1_databases : [];
|
|
175
181
|
for (const row of rows) {
|
|
176
|
-
if (isRecord(row) && row.binding === binding && typeof row.database_name === 'string')
|
|
182
|
+
if (isRecord(row) && row.binding === binding && typeof row.database_name === 'string')
|
|
183
|
+
return row.database_name || null;
|
|
177
184
|
}
|
|
178
185
|
return null;
|
|
179
186
|
}
|
|
@@ -193,7 +200,10 @@ export function blankD1Ids(toml: string, env: string): string {
|
|
|
193
200
|
/** Blank one field across every `[[env.<env>.<arrayKey>]]` table (value..EOL -> `""`). */
|
|
194
201
|
function blankArrayField(toml: string, env: string, arrayKey: string, field: string): string {
|
|
195
202
|
const edits = tables(toml)
|
|
196
|
-
.filter(
|
|
203
|
+
.filter(
|
|
204
|
+
(t) =>
|
|
205
|
+
t.kind === 'array' && t.resolvedKey[0] === 'env' && t.resolvedKey[1] === env && t.resolvedKey[2] === arrayKey,
|
|
206
|
+
)
|
|
197
207
|
.map((t) => kvIn(toml, t, field))
|
|
198
208
|
.flatMap((kv) => (kv ? [{ start: kv.value.range[0], end: endOfLine(toml, kv.value.range[1]) }] : []));
|
|
199
209
|
return applyBlanks(toml, edits);
|
|
@@ -332,7 +342,7 @@ export async function ensureNamespace(logical: string, existing: KvNamespace[],
|
|
|
332
342
|
try {
|
|
333
343
|
await $`bunx wrangler kv namespace create ${logical}`.cwd(cwd).quiet();
|
|
334
344
|
} catch (err) {
|
|
335
|
-
return errText(err).includes('already') ?
|
|
345
|
+
return errText(err).includes('already') ? await reList(logical, cwd) : null;
|
|
336
346
|
}
|
|
337
347
|
return reList(logical, cwd);
|
|
338
348
|
}
|
package/src/wrangler/scaffold.ts
CHANGED
|
@@ -16,7 +16,10 @@ export interface ScaffoldOptions {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/** Locate a workspace package by nx name, package name, or relative path; must have a wrangler.toml. */
|
|
19
|
-
function resolveProject(
|
|
19
|
+
function resolveProject(
|
|
20
|
+
root: string,
|
|
21
|
+
project: string,
|
|
22
|
+
): { dir: string; label: string; packageJsonPath: string; json: Record<string, unknown> } {
|
|
20
23
|
const manifests = getWorkspacePackageManifests(root);
|
|
21
24
|
const match = manifests.find((m) => {
|
|
22
25
|
const nx = recordProperty(m.json, 'nx');
|
|
@@ -83,7 +86,7 @@ async function checkMode(env: string): Promise<void> {
|
|
|
83
86
|
for (const binding of kvBindings) {
|
|
84
87
|
const inToml = pe.getKvId(toml, env, binding);
|
|
85
88
|
const liveId = live.find((n) => n.title === kvTitle(binding, env))?.id ?? null;
|
|
86
|
-
p.log.message(\` KV \${binding}: \${!liveId ? '✗ not created' : inToml === liveId ? \`✓ \${liveId}\` :
|
|
89
|
+
p.log.message(\` KV \${binding}: \${!liveId ? '✗ not created' : inToml === liveId ? \`✓ \${liveId}\` : \`! drift (live \${liveId}, toml \${inToml ?? 'unset'})\`}\`);
|
|
87
90
|
}
|
|
88
91
|
for (const name of vars) {
|
|
89
92
|
p.log.message(\` var \${name}: \${pe.getVar(toml, env, name) ? '✓ set' : '✗ empty'}\`);
|
|
@@ -234,6 +237,8 @@ export function scaffold(root: string, project: string, options: ScaffoldOptions
|
|
|
234
237
|
console.log(`updated ${label}/package.json prepare-env target`);
|
|
235
238
|
}
|
|
236
239
|
|
|
237
|
-
console.log(
|
|
240
|
+
console.log(
|
|
241
|
+
`\nnext: fill secret NAMES in ${label}/.dev.vars.example, then\n bunx nx run ${project}:prepare-env -- <env>`,
|
|
242
|
+
);
|
|
238
243
|
return scriptPath;
|
|
239
244
|
}
|