@getmonoceros/workbench 1.6.0 → 1.6.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/bin.js +86 -18
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -2850,8 +2850,11 @@ async function assertSafeTargetDir(targetDir, expectedOrigin) {
|
|
|
2850
2850
|
}
|
|
2851
2851
|
return;
|
|
2852
2852
|
}
|
|
2853
|
+
if (entries.length === 1 && entries[0] === ".monoceros") {
|
|
2854
|
+
return;
|
|
2855
|
+
}
|
|
2853
2856
|
throw new Error(
|
|
2854
|
-
`Refusing to materialize into non-empty directory ${targetDir} (no Monoceros state.json found). Delete the directory before re-running.`
|
|
2857
|
+
`Refusing to materialize into non-empty directory ${targetDir} (no Monoceros state.json found, and the directory has files we don't recognise). Delete the directory before re-running.`
|
|
2855
2858
|
);
|
|
2856
2859
|
}
|
|
2857
2860
|
function warnOnDeprecatedFeatureRefs(containerFeatures, globalConfig, logger) {
|
|
@@ -3131,7 +3134,6 @@ import { consola as consola13 } from "consola";
|
|
|
3131
3134
|
// src/init/index.ts
|
|
3132
3135
|
import { existsSync as existsSync7, promises as fs10 } from "fs";
|
|
3133
3136
|
import { consola as consola12 } from "consola";
|
|
3134
|
-
import { parseDocument as parseDocument3 } from "yaml";
|
|
3135
3137
|
|
|
3136
3138
|
// src/init/components.ts
|
|
3137
3139
|
import { existsSync as existsSync5, promises as fs9 } from "fs";
|
|
@@ -3308,7 +3310,7 @@ var SCHEMA_HEADER = [
|
|
|
3308
3310
|
"# under `features:` also accepts options not shown here \u2014 check",
|
|
3309
3311
|
"# the feature's `devcontainer-feature.json` for the full list."
|
|
3310
3312
|
];
|
|
3311
|
-
function generateComposedYml(name, components, lookupManifest) {
|
|
3313
|
+
function generateComposedYml(name, components, lookupManifest, repoUrls = []) {
|
|
3312
3314
|
const merged = mergeComponents(components);
|
|
3313
3315
|
const lines = [];
|
|
3314
3316
|
for (const h of SCHEMA_HEADER) lines.push(h);
|
|
@@ -3339,9 +3341,17 @@ function generateComposedYml(name, components, lookupManifest) {
|
|
|
3339
3341
|
}
|
|
3340
3342
|
lines.push("");
|
|
3341
3343
|
}
|
|
3344
|
+
if (repoUrls.length > 0) {
|
|
3345
|
+
renderReposBlock(
|
|
3346
|
+
lines,
|
|
3347
|
+
repoUrls,
|
|
3348
|
+
/* commented */
|
|
3349
|
+
false
|
|
3350
|
+
);
|
|
3351
|
+
}
|
|
3342
3352
|
return ensureTrailingNewline(lines.join("\n"));
|
|
3343
3353
|
}
|
|
3344
|
-
function generateDocumentedYml(name, catalog, lookupManifest) {
|
|
3354
|
+
function generateDocumentedYml(name, catalog, lookupManifest, repoUrls = []) {
|
|
3345
3355
|
const byCategory = groupByCategory(catalog);
|
|
3346
3356
|
const lines = [];
|
|
3347
3357
|
for (const h of SCHEMA_HEADER) lines.push(h);
|
|
@@ -3442,6 +3452,12 @@ function generateDocumentedYml(name, catalog, lookupManifest) {
|
|
|
3442
3452
|
}
|
|
3443
3453
|
lines.push("");
|
|
3444
3454
|
}
|
|
3455
|
+
renderReposBlock(
|
|
3456
|
+
lines,
|
|
3457
|
+
repoUrls,
|
|
3458
|
+
/* commented */
|
|
3459
|
+
repoUrls.length === 0
|
|
3460
|
+
);
|
|
3445
3461
|
return ensureTrailingNewline(lines.join("\n"));
|
|
3446
3462
|
}
|
|
3447
3463
|
var COMMENT_WIDTH = 72;
|
|
@@ -3497,6 +3513,57 @@ function emitHint(out, hint, description, linePrefix) {
|
|
|
3497
3513
|
}
|
|
3498
3514
|
out.push(`${linePrefix}${hint}:`);
|
|
3499
3515
|
}
|
|
3516
|
+
function renderReposBlock(out, urls, commented) {
|
|
3517
|
+
out.push("# Repos \u2014 git repositories cloned into projects/ during");
|
|
3518
|
+
out.push("# post-create. HTTPS-only (ADR 0006). Provider auto-detected");
|
|
3519
|
+
out.push("# for github.com, gitlab.com, bitbucket.org; for any other host");
|
|
3520
|
+
out.push("# (self-hosted GitLab, Bitbucket Data Center, Gitea/Forgejo,");
|
|
3521
|
+
out.push("# GitHub Enterprise, \u2026) declare provider explicitly.");
|
|
3522
|
+
out.push("#");
|
|
3523
|
+
if (commented) {
|
|
3524
|
+
out.push("# repos:");
|
|
3525
|
+
out.push("# - url: https://github.com/<org>/<repo>.git");
|
|
3526
|
+
out.push(
|
|
3527
|
+
"# # path: <folder> # subfolder under projects/; default: URL-derived"
|
|
3528
|
+
);
|
|
3529
|
+
out.push(
|
|
3530
|
+
"# # provider: github # github | gitlab | bitbucket | gitea"
|
|
3531
|
+
);
|
|
3532
|
+
out.push(
|
|
3533
|
+
"# # git: # per-repo committer identity override"
|
|
3534
|
+
);
|
|
3535
|
+
out.push("# # user:");
|
|
3536
|
+
out.push("# # name: Your Name");
|
|
3537
|
+
out.push("# # email: you@example.com");
|
|
3538
|
+
out.push("");
|
|
3539
|
+
return;
|
|
3540
|
+
}
|
|
3541
|
+
out.push("repos:");
|
|
3542
|
+
for (const url of urls) {
|
|
3543
|
+
const derivedPath = deriveDefaultPath(url);
|
|
3544
|
+
out.push(` - url: ${url}`);
|
|
3545
|
+
out.push(
|
|
3546
|
+
` # path: ${derivedPath} # subfolder under projects/; default: URL-derived (${derivedPath})`
|
|
3547
|
+
);
|
|
3548
|
+
out.push(
|
|
3549
|
+
" # provider: github # github | gitlab | bitbucket | gitea"
|
|
3550
|
+
);
|
|
3551
|
+
out.push(
|
|
3552
|
+
" # git: # per-repo committer identity override"
|
|
3553
|
+
);
|
|
3554
|
+
out.push(" # user:");
|
|
3555
|
+
out.push(" # name: Your Name");
|
|
3556
|
+
out.push(" # email: you@example.com");
|
|
3557
|
+
}
|
|
3558
|
+
out.push("");
|
|
3559
|
+
}
|
|
3560
|
+
function deriveDefaultPath(url) {
|
|
3561
|
+
let last = url;
|
|
3562
|
+
const slash = url.lastIndexOf("/");
|
|
3563
|
+
if (slash >= 0) last = url.slice(slash + 1);
|
|
3564
|
+
if (last.endsWith(".git")) last = last.slice(0, -4);
|
|
3565
|
+
return last || "repo";
|
|
3566
|
+
}
|
|
3500
3567
|
function wrapToComment(text, width) {
|
|
3501
3568
|
const words = text.split(/\s+/).filter((w) => w.length > 0);
|
|
3502
3569
|
if (words.length === 0) return [""];
|
|
@@ -3621,15 +3688,14 @@ async function runInit(opts) {
|
|
|
3621
3688
|
}
|
|
3622
3689
|
const checkoutRoot = opts.workbenchRoot ?? workbenchCheckoutRoot();
|
|
3623
3690
|
const lookup = (ref) => loadFeatureManifestSummary(ref, checkoutRoot);
|
|
3624
|
-
|
|
3625
|
-
const
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3691
|
+
const reposRaw = (opts.withRepo ?? []).map((u) => u.trim()).filter((u) => u.length > 0);
|
|
3692
|
+
const repos = [];
|
|
3693
|
+
const seenRepoUrls = /* @__PURE__ */ new Set();
|
|
3694
|
+
for (const url of reposRaw) {
|
|
3695
|
+
if (seenRepoUrls.has(url)) continue;
|
|
3696
|
+
seenRepoUrls.add(url);
|
|
3697
|
+
repos.push(url);
|
|
3631
3698
|
}
|
|
3632
|
-
const repos = (opts.withRepo ?? []).map((u) => u.trim()).filter((u) => u.length > 0);
|
|
3633
3699
|
if (repos.length > 0) {
|
|
3634
3700
|
const offending = [];
|
|
3635
3701
|
for (const url of repos) {
|
|
@@ -3653,12 +3719,14 @@ async function runInit(opts) {
|
|
|
3653
3719
|
].join("\n")
|
|
3654
3720
|
);
|
|
3655
3721
|
}
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3722
|
+
}
|
|
3723
|
+
let text;
|
|
3724
|
+
const requested = opts.with ?? [];
|
|
3725
|
+
if (requested.length === 0) {
|
|
3726
|
+
text = generateDocumentedYml(opts.name, catalog, lookup, repos);
|
|
3727
|
+
} else {
|
|
3728
|
+
const components = resolveComponents(catalog, requested);
|
|
3729
|
+
text = generateComposedYml(opts.name, components, lookup, repos);
|
|
3662
3730
|
}
|
|
3663
3731
|
await fs10.mkdir(containerConfigsDir(home), { recursive: true });
|
|
3664
3732
|
await fs10.writeFile(dest, text, "utf8");
|