@tinycld/bootstrap 1.1.0 → 2.0.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.
@@ -1,149 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import { existsSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
3
- import { tmpdir } from 'node:os';
4
- import { join } from 'node:path';
5
- import { looksLikeWorkspaceRoot } from "./layout.js";
6
- // All feature members that exist in the ecosystem. The workspace manifest lists
7
- // ALL of them (npm tolerates absent dirs), so a partial checkout still installs.
8
- // But --tooling CLONES only app+core+requested — we do NOT force-clone all.
9
- const ALL_FEATURES = ['contacts', 'mail', 'calendar', 'drive', 'calc', 'text', 'google-takeout-import'];
10
- // Always cloned by tooling mode (the minimum viable workspace). package-scripts
11
- // ships inside the workspace meta-repo itself, so it is never cloned.
12
- const ALWAYS_CLONE = ['app', 'core'];
13
- // Listed in the manifest workspaces array (everything that could exist).
14
- const ALL_MEMBERS = ['app', 'core', 'package-scripts', ...ALL_FEATURES];
15
- /**
16
- * Write (or merge into) a workspace-root package.json + .npmrc in `dir`.
17
- *
18
- * When `dir/package.json` already exists (e.g. provided by the workspace clone),
19
- * we preserve its fields and only enforce the two things bootstrap owns:
20
- * the complete `workspaces` list (so later --with clones need no manifest edit)
21
- * and the `postinstall` script. All other fields — devDependencies, engines,
22
- * volta, extra scripts, etc. — survive as-is.
23
- *
24
- * When no package.json exists yet (workspace clone was skipped), the full
25
- * generated defaults are written, matching the previous behaviour.
26
- *
27
- * The workspaces array ALWAYS lists every possible member — npm ignores entries
28
- * whose dirs are absent, so a partial checkout installs fine.
29
- *
30
- * .npmrc is written only when one does not already exist, for the same reason.
31
- */
32
- export function writeWorkspaceManifest(dir) {
33
- const pkgPath = join(dir, 'package.json');
34
- let existing = {};
35
- if (existsSync(pkgPath)) {
36
- try {
37
- existing = JSON.parse(readFileSync(pkgPath, 'utf-8'));
38
- }
39
- catch {
40
- // Unparseable existing file — start from defaults
41
- }
42
- }
43
- const existingScripts = typeof existing.scripts === 'object' && existing.scripts !== null
44
- ? existing.scripts
45
- : {};
46
- const pkg = {
47
- name: '@tinycld/workspace',
48
- version: '0.0.0',
49
- private: true,
50
- type: 'module',
51
- ...existing,
52
- // Always enforce the canonical workspaces list and postinstall script.
53
- workspaces: [...ALL_MEMBERS],
54
- scripts: {
55
- ...existingScripts,
56
- postinstall: 'cd app && npm run packages:generate && npm run assets:copy-pdfjs',
57
- },
58
- };
59
- writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 4)}\n`);
60
- const npmrcPath = join(dir, '.npmrc');
61
- if (!existsSync(npmrcPath)) {
62
- writeFileSync(npmrcPath, 'legacy-peer-deps=true\n');
63
- }
64
- }
65
- function realClone(url, dest) {
66
- const r = spawnSync('git', ['clone', '--depth', '1', url, dest], { stdio: 'inherit' });
67
- return r.status === 0;
68
- }
69
- /**
70
- * Clone the workspace meta-repo into `root`, tolerating a non-empty target.
71
- *
72
- * A plain `git clone <url> <root>` fails when `root` already contains files
73
- * (e.g. the link-package flow pre-creates a `<slug>/` subdir there). We
74
- * clone into a fresh sibling temp dir, then move each top-level entry into
75
- * `root`, skipping any that already exist. The `.git` dir is moved too unless
76
- * `root/.git` already exists.
77
- *
78
- * The `cloneFn` primitive is the same injected-or-real clone used for app/core —
79
- * tests inject a stub that records URLs but does not create files, so the
80
- * move logic will simply move nothing from an empty temp dir (which is fine
81
- * for unit tests). Real runs move the full repo contents.
82
- */
83
- function cloneWorkspaceIntoRoot(url, root, cloneFn) {
84
- const tempDir = mkdtempSync(join(tmpdir(), 'tinycld-workspace-'));
85
- try {
86
- if (!cloneFn(url, tempDir))
87
- return false;
88
- const rootHasGit = existsSync(join(root, '.git'));
89
- for (const entry of readdirSync(tempDir)) {
90
- // Skip .git if root already has one
91
- if (entry === '.git' && rootHasGit)
92
- continue;
93
- const src = join(tempDir, entry);
94
- const dest = join(root, entry);
95
- // Never overwrite an entry that already exists in root
96
- if (existsSync(dest))
97
- continue;
98
- renameSync(src, dest);
99
- }
100
- return true;
101
- }
102
- finally {
103
- rmSync(tempDir, { recursive: true, force: true });
104
- }
105
- }
106
- /**
107
- * Assemble a workspace skeleton at opts.root: if root is not yet a workspace,
108
- * clone the workspace meta-repo into it first (self-init), then write the full
109
- * manifest, then clone ONLY app + core + the explicitly-requested feature
110
- * members (skipping any already present — e.g. a CI-checked-out member).
111
- * Unknown member names throw. Returns the members that ended up present. Does
112
- * NOT run npm install (the caller / CI controls that, since it may want a
113
- * clean `npm ci`).
114
- */
115
- export function bootstrapTooling(opts) {
116
- const requested = opts.members ?? [];
117
- const unknown = requested.filter((m) => !ALL_FEATURES.includes(m));
118
- if (unknown.length > 0) {
119
- throw new Error(`Unknown feature member(s): ${unknown.join(', ')}. Known: ${ALL_FEATURES.join(', ')}`);
120
- }
121
- const repoBase = opts.repoBase ?? 'git@github.com:tinycld';
122
- const clone = opts.clone ?? realClone;
123
- const present = [];
124
- // Self-init: clone the workspace meta-repo into root if it isn't already
125
- // a workspace root. This provides package-scripts/, tinycld.packages.ts,
126
- // tests/, .node-version, .go-version, .npmrc, and the canonical root
127
- // package.json before anything else runs.
128
- if (!looksLikeWorkspaceRoot(opts.root)) {
129
- if (cloneWorkspaceIntoRoot(`${repoBase}/workspace.git`, opts.root, clone)) {
130
- present.push('workspace');
131
- }
132
- }
133
- // Merge the canonical workspaces list + postinstall into any existing
134
- // package.json (provided by the workspace clone), or write defaults when
135
- // no file exists yet (workspace clone was skipped or failed).
136
- writeWorkspaceManifest(opts.root);
137
- const toClone = Array.from(new Set([...ALWAYS_CLONE, ...requested]));
138
- for (const m of toClone) {
139
- const dest = join(opts.root, m);
140
- if (existsSync(join(dest, '.git')) || existsSync(join(dest, 'package.json'))) {
141
- present.push(m);
142
- continue;
143
- }
144
- if (clone(`${repoBase}/${m}.git`, dest))
145
- present.push(m);
146
- }
147
- return present;
148
- }
149
- //# sourceMappingURL=bootstrap-tooling.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bootstrap-tooling.js","sourceRoot":"","sources":["../src/bootstrap-tooling.ts"],"names":[],"mappings":"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"}
package/dist/link-core.js DELETED
@@ -1,99 +0,0 @@
1
- import { spawnSync } from 'node:child_process';
2
- import { existsSync } from 'node:fs';
3
- import { dirname, join, relative } from 'node:path';
4
- import { confirm, isCancel, log, spinner } from '@clack/prompts';
5
- import pc from 'picocolors';
6
- const CORE_REPO_URL = 'git@github.com:tinycld/core.git';
7
- const APP_REPO_URL = 'git@github.com:tinycld/tinycld.git';
8
- const CORE_DIR_NAME = 'core';
9
- const APP_DIR_NAME = 'tinycld';
10
- /**
11
- * Returns true if the user chose to link (even if a subprocess failed —
12
- * the error is already logged, and we don't want to follow up with
13
- * "here are the manual steps" when the user already expressed intent).
14
- * Returns false only if linking was declined or skipped.
15
- *
16
- * Linking happens against the tinycld **app shell** (sibling repo
17
- * `tinycld/tinycld`), which owns `packages:link`. The `core` library
18
- * sibling is also cloned because the app shell installs it via
19
- * `file:../core` and the package's tsconfig points at `../core/...`.
20
- */
21
- export async function offerLinkCore({ packageName, targetDir, mode }) {
22
- if (mode === 'skip')
23
- return false;
24
- const parentDir = dirname(targetDir);
25
- const coreDir = join(parentDir, CORE_DIR_NAME);
26
- const appDir = join(parentDir, APP_DIR_NAME);
27
- const coreExists = existsSync(coreDir);
28
- const appExists = existsSync(appDir);
29
- if (mode === 'prompt') {
30
- const missing = [];
31
- if (!coreExists)
32
- missing.push(CORE_DIR_NAME);
33
- if (!appExists)
34
- missing.push(APP_DIR_NAME);
35
- const prompt = missing.length === 0
36
- ? `Link ${pc.bold(packageName)} into ${pc.bold(APP_DIR_NAME)} now?`
37
- : `Clone ${pc.bold(missing.join(' + '))} (shallow) and link ${pc.bold(packageName)} into ${pc.bold(APP_DIR_NAME)} now?`;
38
- const answer = await confirm({ message: prompt, initialValue: true });
39
- if (isCancel(answer) || answer !== true)
40
- return false;
41
- }
42
- if (!coreExists) {
43
- if (!cloneRepo(CORE_REPO_URL, coreDir))
44
- return true;
45
- }
46
- else {
47
- log.info(`Using existing ${CORE_DIR_NAME} at ${coreDir}`);
48
- }
49
- if (!appExists) {
50
- if (!cloneRepo(APP_REPO_URL, appDir))
51
- return true;
52
- }
53
- else {
54
- log.info(`Using existing ${APP_DIR_NAME} at ${appDir}`);
55
- }
56
- const install = spinner();
57
- install.start(`Installing ${APP_DIR_NAME} dependencies (bun install)`);
58
- const inst = spawnSync('bun', ['install'], { cwd: appDir, stdio: 'pipe', encoding: 'utf8' });
59
- if (inst.status !== 0) {
60
- install.stop(pc.red('bun install failed'), 1);
61
- log.error(inst.stderr.trim() || 'bun install exited non-zero');
62
- return true;
63
- }
64
- install.stop(`Installed ${APP_DIR_NAME} dependencies`);
65
- // packages:link in tinycld takes a sibling-directory locator and reads
66
- // the package name from the sibling's package.json. Pass a path relative
67
- // to the app shell so the symlink target stays portable.
68
- const link = spinner();
69
- link.start(`Linking ${packageName}`);
70
- const locator = relative(appDir, targetDir) || targetDir;
71
- const linkResult = spawnSync('bun', ['run', 'packages:link', locator], {
72
- cwd: appDir,
73
- stdio: 'pipe',
74
- encoding: 'utf8',
75
- });
76
- if (linkResult.status !== 0) {
77
- link.stop(pc.red('Link failed'), 1);
78
- log.error(linkResult.stderr.trim() || 'packages:link exited non-zero');
79
- return true;
80
- }
81
- link.stop(`Linked ${packageName} into ${APP_DIR_NAME}`);
82
- return true;
83
- }
84
- function cloneRepo(url, dest) {
85
- const s = spinner();
86
- s.start(`Cloning ${url} into ${dest}`);
87
- const result = spawnSync('git', ['clone', '--depth', '1', url, dest], {
88
- stdio: 'pipe',
89
- encoding: 'utf8',
90
- });
91
- if (result.status !== 0) {
92
- s.stop(pc.red('Clone failed'), 1);
93
- log.error(result.stderr.trim() || 'git clone exited non-zero');
94
- return false;
95
- }
96
- s.stop(`Cloned ${dest}`);
97
- return true;
98
- }
99
- //# sourceMappingURL=link-core.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"link-core.js","sourceRoot":"","sources":["../src/link-core.ts"],"names":[],"mappings":"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"}