Skip to content

Commit cd53d5a

Browse files
authored
add --pull flag to sync-docs, pull existing repo if nec (#726)
* add --pull flag to sync-docs, pull existing repo if nec * fix branch
1 parent b917545 commit cd53d5a

File tree

2 files changed

+59
-22
lines changed

2 files changed

+59
-22
lines changed

apps/svelte.dev/scripts/sync-docs/index.ts

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { preprocess } from '@sveltejs/site-kit/markdown/preprocess';
22
import path from 'node:path';
33
import fs from 'node:fs';
4+
import { parseArgs } from 'node:util';
45
import ts from 'typescript';
56
import glob from 'tiny-glob/sync';
67
import chokidar from 'chokidar';
@@ -19,6 +20,22 @@ interface Package {
1920
process_modules?: (modules: Modules, pkg: Package) => Promise<Modules>;
2021
}
2122

23+
const parsed = parseArgs({
24+
args: process.argv.slice(2),
25+
options: {
26+
watch: {
27+
type: 'boolean',
28+
short: 'w'
29+
},
30+
pull: {
31+
type: 'boolean',
32+
short: 'p'
33+
}
34+
},
35+
strict: true,
36+
allowPositionals: true
37+
});
38+
2239
const dirname = fileURLToPath(new URL('.', import.meta.url));
2340
const REPOS = path.join(dirname, '../../repos');
2441
const DOCS = path.join(dirname, '../../content/docs');
@@ -111,29 +128,42 @@ const packages: Package[] = [
111128
{
112129
name: 'cli',
113130
repo: 'sveltejs/cli',
114-
branch: 'chore/add-docs',
131+
branch: 'main',
115132
pkg: 'packages/cli',
116133
docs: 'documentation/docs',
117134
types: null
118135
}
119136
];
120137

138+
const unknown = parsed.positionals.filter((name) => !packages.some((pkg) => pkg.name === name));
139+
140+
if (unknown.length > 0) {
141+
throw new Error(
142+
`Valid repos are ${packages.map((pkg) => pkg.name).join(', ')} (saw ${unknown.join(', ')})`
143+
);
144+
}
145+
146+
const filtered =
147+
parsed.positionals.length === 0
148+
? packages
149+
: packages.filter((pkg) => parsed.positionals.includes(pkg.name));
150+
121151
/**
122152
* Depending on your setup, this will either clone the Svelte and SvelteKit repositories
123153
* or use the local paths you provided above to read the documentation files.
124154
* It will then copy them into the `content/docs` directory and process them to replace
125155
* placeholders for types with content from the generated types.
126156
*/
127-
if (process.env.USE_GIT === 'true') {
157+
if (parsed.values.pull) {
128158
try {
129159
fs.mkdirSync(REPOS);
130160
} catch {
131161
// ignore if it already exists
132162
}
133163

134-
await Promise.all(
135-
packages.map((pkg) => clone_repo(`https://github.com/${pkg.repo}.git`, pkg.branch, REPOS))
136-
);
164+
for (const pkg of filtered) {
165+
await clone_repo(`https://github.com/${pkg.repo}.git`, pkg.name, pkg.branch, REPOS);
166+
}
137167
}
138168

139169
async function sync(pkg: Package) {
@@ -157,16 +187,18 @@ async function sync(pkg: Package) {
157187
}
158188
}
159189

160-
for (const pkg of packages) {
190+
for (const pkg of filtered) {
161191
await sync(pkg);
162192
}
163193

164-
if (process.argv.includes('-w') || process.argv.includes('--watch')) {
165-
for (const pkg of packages) {
194+
if (parsed.values.watch) {
195+
for (const pkg of filtered) {
166196
chokidar
167197
.watch(`${REPOS}/${pkg.name}/${pkg.docs}`, { ignoreInitial: true })
168198
.on('all', (event) => {
169199
sync(pkg);
170200
});
171201
}
202+
203+
console.log(`\nwatching for changes in ${parsed.positionals.join(', ')}`);
172204
}

apps/svelte.dev/scripts/sync-docs/utils.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
import { spawn, type SpawnOptions } from 'node:child_process';
1+
import { execSync, spawn, type SpawnOptions } from 'node:child_process';
22
import fs from 'node:fs';
33
import glob from 'tiny-glob/sync';
44

5-
export async function clone_repo(repo: string, branch: string, cwd: string) {
6-
const regex_result = /https:\/\/github.com\/\w+\/(\w+).git/.exec(repo);
7-
if (!regex_result || regex_result.length < 2) {
8-
throw new Error(`Expected https://github.com/xxx/xxx.git, but got ${repo}`);
9-
}
5+
export async function clone_repo(repo: string, name: string, branch: string, cwd: string) {
6+
const dir = `${cwd}/${name}`;
7+
8+
if (fs.existsSync(dir)) {
9+
const opts = { cwd: dir };
10+
11+
if (execSync('git status -s', opts).toString() !== '') {
12+
throw new Error(`${name} repo is dirty — aborting`);
13+
}
14+
15+
await invoke('git', ['checkout', branch], opts);
16+
await invoke('git', ['pull'], opts);
1017

11-
const dirname = `${cwd}/${regex_result[1]}`;
12-
if (fs.existsSync(dirname)) {
13-
// TODO skip if we detect that same branch is already cloned
14-
fs.rmSync(dirname, { recursive: true });
18+
return;
1519
}
1620

1721
await invoke('git', ['clone', '--depth', '1', '--branch', branch, repo], {
@@ -22,14 +26,15 @@ export async function clone_repo(repo: string, branch: string, cwd: string) {
2226
export function invoke(cmd: string, args: string[], opts: SpawnOptions) {
2327
const child = spawn(cmd, args, { ...opts, stdio: 'inherit' });
2428

25-
return new Promise<void>((resolve) => {
29+
return new Promise<void>((fulfil, reject) => {
2630
child.on('close', (code) => {
27-
if (!code) {
28-
console.log(`${[cmd, ...args].join(' ')} successfully completed`);
31+
if (code) {
32+
reject(new Error(`Exited with code ${code}`));
33+
return;
2934
}
3035

3136
// Give it some extra time to finish writing files to disk
32-
setTimeout(() => resolve(), 500);
37+
setTimeout(fulfil, 500);
3338
});
3439
});
3540
}

0 commit comments

Comments
 (0)