looply-cli 0.2.0 → 0.3.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/dist/.src-hash +1 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +77 -69
- package/dist/bin.js.map +1 -1
- package/dist/serve-cmd.d.ts +115 -0
- package/dist/serve-cmd.d.ts.map +1 -0
- package/dist/serve-cmd.js +505 -0
- package/dist/serve-cmd.js.map +1 -0
- package/dist/serve.d.ts +167 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +336 -0
- package/dist/serve.js.map +1 -0
- package/package.json +54 -54
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { type ProbeFn } from './run-lease';
|
|
2
|
+
import { type Platform, type ServeFs, type ServedRepo } from './serve';
|
|
3
|
+
/**
|
|
4
|
+
* `looply serve` and its verbs — the composition around `serve.ts`.
|
|
5
|
+
*
|
|
6
|
+
* looply serve add [path] list a repository to be served (default: here)
|
|
7
|
+
* looply serve remove <path> stop serving one
|
|
8
|
+
* looply serve list what is listed, and whether each is still set up
|
|
9
|
+
* looply serve run the supervisor: one daemon per listed repository
|
|
10
|
+
* looply serve install start the supervisor at login (Windows); a template elsewhere
|
|
11
|
+
* looply serve uninstall undo `install`
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ ADDING A REPOSITORY IS THE CONSENT. Each child runs `looply daemon --yes`,
|
|
14
|
+
* which registers the repository with the server without asking — there is no
|
|
15
|
+
* terminal to ask on. The question a person would have been asked at the
|
|
16
|
+
* daemon's prompt is the one they answered by typing `serve add`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const SERVE_USAGE: string;
|
|
19
|
+
export declare const EXIT_OK = 0;
|
|
20
|
+
export declare const EXIT_REFUSED = 1;
|
|
21
|
+
/** Somebody else is here — the same answer every other lock in this CLI gives. */
|
|
22
|
+
export declare const EXIT_HELD = 2;
|
|
23
|
+
export declare const EXIT_USAGE = 64;
|
|
24
|
+
/** How long children get to finish after being asked to stop, before they are killed outright. */
|
|
25
|
+
export declare const STOP_GRACE_MS = 10000;
|
|
26
|
+
export interface ChildEvents {
|
|
27
|
+
line(text: string): void;
|
|
28
|
+
/** Exactly once, whether the child ran and ended or never started. */
|
|
29
|
+
exit(code: number | null, signal: string | null, error?: Error): void;
|
|
30
|
+
}
|
|
31
|
+
export interface ChildHandle {
|
|
32
|
+
/** Ask it to stop; `force` is the second ask. */
|
|
33
|
+
kill(force: boolean): void;
|
|
34
|
+
}
|
|
35
|
+
export interface SupervisorDeps {
|
|
36
|
+
readonly platform: Platform;
|
|
37
|
+
/** The listed repositories. Throws when the list cannot be read. */
|
|
38
|
+
repos(): readonly ServedRepo[];
|
|
39
|
+
configExists(repo: string): boolean;
|
|
40
|
+
spawnDaemon(repo: string, on: ChildEvents): ChildHandle;
|
|
41
|
+
now(): number;
|
|
42
|
+
setTimer(fn: () => void, ms: number): unknown;
|
|
43
|
+
clearTimer(handle: unknown): void;
|
|
44
|
+
log(line: string): void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The supervisor: keeps one child per listed repository alive.
|
|
48
|
+
*
|
|
49
|
+
* ⚠️ A CHILD THAT FAILS IS THE CHILD'S PROBLEM. A repository already served by
|
|
50
|
+
* a daemon a person started by hand makes its child exit on the per-repo lock;
|
|
51
|
+
* that line is logged, the child waits out its backoff and tries again, and
|
|
52
|
+
* every other repository carries on. Nothing a child does can stop the
|
|
53
|
+
* supervisor.
|
|
54
|
+
*/
|
|
55
|
+
export declare class Supervisor {
|
|
56
|
+
private readonly deps;
|
|
57
|
+
private readonly entries;
|
|
58
|
+
private pollTimer;
|
|
59
|
+
private stopping;
|
|
60
|
+
private readError;
|
|
61
|
+
private drained;
|
|
62
|
+
/** One promise for every caller of `stop`, so the impatient second call resolves the first. */
|
|
63
|
+
private drain;
|
|
64
|
+
constructor(deps: SupervisorDeps);
|
|
65
|
+
/** The keys of the repositories that have an entry (running, waiting or skipped). */
|
|
66
|
+
keys(): string[];
|
|
67
|
+
running(): string[];
|
|
68
|
+
start(): void;
|
|
69
|
+
/** Re-read the list and make the running set match it. */
|
|
70
|
+
poll(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Stop every child and resolve when all are gone. A second call is the
|
|
73
|
+
* impatient one: whatever is left is killed outright.
|
|
74
|
+
*/
|
|
75
|
+
stop(): Promise<void>;
|
|
76
|
+
private admit;
|
|
77
|
+
private retire;
|
|
78
|
+
private launch;
|
|
79
|
+
private exited;
|
|
80
|
+
private later;
|
|
81
|
+
private say;
|
|
82
|
+
}
|
|
83
|
+
export interface ServeDeps {
|
|
84
|
+
readonly home: string;
|
|
85
|
+
readonly cwd: string;
|
|
86
|
+
readonly platform: Platform;
|
|
87
|
+
readonly env: NodeJS.ProcessEnv;
|
|
88
|
+
readonly fs: ServeFs;
|
|
89
|
+
readonly pid: number;
|
|
90
|
+
readonly probe: ProbeFn;
|
|
91
|
+
/** Node and this CLI's own bin.js; `bin` is null when it cannot be found (an unbuilt checkout). */
|
|
92
|
+
readonly launch: {
|
|
93
|
+
node: string;
|
|
94
|
+
bin: string | null;
|
|
95
|
+
};
|
|
96
|
+
now(): Date;
|
|
97
|
+
out(line: string): void;
|
|
98
|
+
err(line: string): void;
|
|
99
|
+
/** The supervisor's world; only `looply serve` itself needs it. */
|
|
100
|
+
supervisor?(): Omit<SupervisorDeps, 'repos' | 'configExists' | 'platform' | 'log'>;
|
|
101
|
+
/** Calls back on every SIGINT/SIGTERM; returns the unsubscribe. */
|
|
102
|
+
onSignal?(cb: () => void): () => void;
|
|
103
|
+
}
|
|
104
|
+
export declare function serveCommand(argv: readonly string[], deps: ServeDeps): Promise<number>;
|
|
105
|
+
/**
|
|
106
|
+
* This CLI's own entry file, for spawning children and writing startup files.
|
|
107
|
+
*
|
|
108
|
+
* `serve-cmd.js` is built next to `bin.js`, so that is where it is looked for
|
|
109
|
+
* first — true both in this repository's dist and in an installed package,
|
|
110
|
+
* where npm's shim and `npx` both end at the same file. `require.main` is the
|
|
111
|
+
* fallback for a bundling that moved things.
|
|
112
|
+
*/
|
|
113
|
+
export declare function selfBin(fileExists: (p: string) => boolean): string | null;
|
|
114
|
+
export declare function nodeServeDeps(): ServeDeps;
|
|
115
|
+
//# sourceMappingURL=serve-cmd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-cmd.d.ts","sourceRoot":"","sources":["../src/serve-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Supervisor = exports.STOP_GRACE_MS = exports.EXIT_USAGE = exports.EXIT_HELD = exports.EXIT_REFUSED = exports.EXIT_OK = exports.SERVE_USAGE = void 0;
|
|
4
|
+
exports.serveCommand = serveCommand;
|
|
5
|
+
exports.selfBin = selfBin;
|
|
6
|
+
exports.nodeServeDeps = nodeServeDeps;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_os_1 = require("node:os");
|
|
10
|
+
const node_path_1 = require("node:path");
|
|
11
|
+
const run_lease_1 = require("./run-lease");
|
|
12
|
+
const serve_1 = require("./serve");
|
|
13
|
+
/**
|
|
14
|
+
* `looply serve` and its verbs — the composition around `serve.ts`.
|
|
15
|
+
*
|
|
16
|
+
* looply serve add [path] list a repository to be served (default: here)
|
|
17
|
+
* looply serve remove <path> stop serving one
|
|
18
|
+
* looply serve list what is listed, and whether each is still set up
|
|
19
|
+
* looply serve run the supervisor: one daemon per listed repository
|
|
20
|
+
* looply serve install start the supervisor at login (Windows); a template elsewhere
|
|
21
|
+
* looply serve uninstall undo `install`
|
|
22
|
+
*
|
|
23
|
+
* ⚠️ ADDING A REPOSITORY IS THE CONSENT. Each child runs `looply daemon --yes`,
|
|
24
|
+
* which registers the repository with the server without asking — there is no
|
|
25
|
+
* terminal to ask on. The question a person would have been asked at the
|
|
26
|
+
* daemon's prompt is the one they answered by typing `serve add`.
|
|
27
|
+
*/
|
|
28
|
+
exports.SERVE_USAGE = [
|
|
29
|
+
'looply serve add [path] serve this repository (or <path>) from the one machine-wide supervisor',
|
|
30
|
+
'looply serve remove <path> stop serving a repository',
|
|
31
|
+
'looply serve list the served repositories, and whether each still has .looply/config.yaml',
|
|
32
|
+
'looply serve run the supervisor: one daemon per served repository, restarted if it falls over',
|
|
33
|
+
'looply serve install | uninstall start the supervisor at login (Windows); prints a service template elsewhere',
|
|
34
|
+
].join('\n');
|
|
35
|
+
exports.EXIT_OK = 0;
|
|
36
|
+
exports.EXIT_REFUSED = 1;
|
|
37
|
+
/** Somebody else is here — the same answer every other lock in this CLI gives. */
|
|
38
|
+
exports.EXIT_HELD = 2;
|
|
39
|
+
exports.EXIT_USAGE = 64;
|
|
40
|
+
/** How long children get to finish after being asked to stop, before they are killed outright. */
|
|
41
|
+
exports.STOP_GRACE_MS = 10_000;
|
|
42
|
+
/**
|
|
43
|
+
* The supervisor: keeps one child per listed repository alive.
|
|
44
|
+
*
|
|
45
|
+
* ⚠️ A CHILD THAT FAILS IS THE CHILD'S PROBLEM. A repository already served by
|
|
46
|
+
* a daemon a person started by hand makes its child exit on the per-repo lock;
|
|
47
|
+
* that line is logged, the child waits out its backoff and tries again, and
|
|
48
|
+
* every other repository carries on. Nothing a child does can stop the
|
|
49
|
+
* supervisor.
|
|
50
|
+
*/
|
|
51
|
+
class Supervisor {
|
|
52
|
+
deps;
|
|
53
|
+
entries = new Map();
|
|
54
|
+
pollTimer = null;
|
|
55
|
+
stopping = false;
|
|
56
|
+
readError = null;
|
|
57
|
+
drained = null;
|
|
58
|
+
/** One promise for every caller of `stop`, so the impatient second call resolves the first. */
|
|
59
|
+
drain = null;
|
|
60
|
+
constructor(deps) {
|
|
61
|
+
this.deps = deps;
|
|
62
|
+
}
|
|
63
|
+
/** The keys of the repositories that have an entry (running, waiting or skipped). */
|
|
64
|
+
keys() {
|
|
65
|
+
return [...this.entries.keys()];
|
|
66
|
+
}
|
|
67
|
+
running() {
|
|
68
|
+
return [...this.entries].filter(([, e]) => e.child !== null).map(([k]) => k);
|
|
69
|
+
}
|
|
70
|
+
start() {
|
|
71
|
+
this.poll();
|
|
72
|
+
}
|
|
73
|
+
/** Re-read the list and make the running set match it. */
|
|
74
|
+
poll() {
|
|
75
|
+
if (this.stopping)
|
|
76
|
+
return;
|
|
77
|
+
let wanted = null;
|
|
78
|
+
try {
|
|
79
|
+
wanted = this.deps.repos();
|
|
80
|
+
this.readError = null;
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
// Keep what is running. A list that cannot be read this minute is not a
|
|
84
|
+
// list that says "serve nothing".
|
|
85
|
+
const msg = e.message;
|
|
86
|
+
if (msg !== this.readError)
|
|
87
|
+
this.deps.log(`serve: cannot read the list — ${msg}; keeping what is running`);
|
|
88
|
+
this.readError = msg;
|
|
89
|
+
}
|
|
90
|
+
if (wanted !== null) {
|
|
91
|
+
const live = [...this.entries].filter(([, e]) => !e.removed).map(([k]) => k);
|
|
92
|
+
const plan = (0, serve_1.reconcile)(live, wanted, this.deps.platform);
|
|
93
|
+
for (const key of plan.stop)
|
|
94
|
+
this.retire(key);
|
|
95
|
+
for (const repo of plan.start)
|
|
96
|
+
this.admit(repo);
|
|
97
|
+
}
|
|
98
|
+
this.pollTimer = this.deps.setTimer(() => this.poll(), serve_1.REGISTRY_POLL_MS);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Stop every child and resolve when all are gone. A second call is the
|
|
102
|
+
* impatient one: whatever is left is killed outright.
|
|
103
|
+
*/
|
|
104
|
+
stop() {
|
|
105
|
+
const force = this.stopping;
|
|
106
|
+
this.stopping = true;
|
|
107
|
+
if (this.pollTimer !== null)
|
|
108
|
+
this.deps.clearTimer(this.pollTimer);
|
|
109
|
+
this.pollTimer = null;
|
|
110
|
+
for (const [key, e] of this.entries) {
|
|
111
|
+
if (e.timer !== null)
|
|
112
|
+
this.deps.clearTimer(e.timer);
|
|
113
|
+
e.timer = null;
|
|
114
|
+
if (e.child === null)
|
|
115
|
+
this.entries.delete(key);
|
|
116
|
+
else
|
|
117
|
+
e.child.kill(force);
|
|
118
|
+
}
|
|
119
|
+
// A child that ignores the polite ask is killed after the grace period.
|
|
120
|
+
if (!force && this.entries.size > 0)
|
|
121
|
+
this.deps.setTimer(() => void this.stop(), exports.STOP_GRACE_MS);
|
|
122
|
+
if (this.drain === null) {
|
|
123
|
+
this.drain = new Promise((resolve) => {
|
|
124
|
+
this.drained = resolve;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (this.entries.size === 0)
|
|
128
|
+
this.drained?.();
|
|
129
|
+
return this.drain;
|
|
130
|
+
}
|
|
131
|
+
admit(repo) {
|
|
132
|
+
const key = (0, serve_1.repoKey)(repo.path, this.deps.platform);
|
|
133
|
+
const prior = this.entries.get(key);
|
|
134
|
+
// Removed and re-added before its old child finished: let the old one go,
|
|
135
|
+
// and start fresh when it has.
|
|
136
|
+
if (prior) {
|
|
137
|
+
prior.removed = false;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const entry = {
|
|
141
|
+
repo,
|
|
142
|
+
label: (0, serve_1.repoLabel)(repo.path, this.deps.platform),
|
|
143
|
+
backoff: new serve_1.Backoff(),
|
|
144
|
+
child: null,
|
|
145
|
+
timer: null,
|
|
146
|
+
removed: false,
|
|
147
|
+
skipped: false,
|
|
148
|
+
};
|
|
149
|
+
this.entries.set(key, entry);
|
|
150
|
+
this.launch(key, entry);
|
|
151
|
+
}
|
|
152
|
+
retire(key) {
|
|
153
|
+
const e = this.entries.get(key);
|
|
154
|
+
if (!e)
|
|
155
|
+
return;
|
|
156
|
+
e.removed = true;
|
|
157
|
+
if (e.timer !== null)
|
|
158
|
+
this.deps.clearTimer(e.timer);
|
|
159
|
+
e.timer = null;
|
|
160
|
+
this.say(e, 'no longer listed; stopping');
|
|
161
|
+
if (e.child === null)
|
|
162
|
+
this.entries.delete(key);
|
|
163
|
+
else
|
|
164
|
+
e.child.kill(false);
|
|
165
|
+
}
|
|
166
|
+
launch(key, e) {
|
|
167
|
+
e.timer = null;
|
|
168
|
+
if (this.stopping || e.removed)
|
|
169
|
+
return;
|
|
170
|
+
if (!this.deps.configExists(e.repo.path)) {
|
|
171
|
+
if (!e.skipped) {
|
|
172
|
+
this.say(e, `skipped: ${(0, serve_1.configPathOf)(e.repo.path, this.deps.platform)} is missing — run \`looply init\` there, ` +
|
|
173
|
+
`or \`looply serve remove ${e.repo.path}\`. Checking again later.`);
|
|
174
|
+
}
|
|
175
|
+
e.skipped = true;
|
|
176
|
+
this.later(key, e, e.backoff.exited(this.deps.now()));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (e.skipped)
|
|
180
|
+
this.say(e, 'config is back');
|
|
181
|
+
e.skipped = false;
|
|
182
|
+
this.say(e, `starting daemon in ${e.repo.path}`);
|
|
183
|
+
e.backoff.started(this.deps.now());
|
|
184
|
+
let done = false;
|
|
185
|
+
e.child = this.deps.spawnDaemon(e.repo.path, {
|
|
186
|
+
line: (text) => this.say(e, text),
|
|
187
|
+
exit: (code, signal, error) => {
|
|
188
|
+
if (done)
|
|
189
|
+
return;
|
|
190
|
+
done = true;
|
|
191
|
+
this.exited(key, e, code, signal, error);
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
exited(key, e, code, signal, error) {
|
|
196
|
+
e.child = null;
|
|
197
|
+
const how = error
|
|
198
|
+
? `could not start (${error.message})`
|
|
199
|
+
: signal
|
|
200
|
+
? `stopped by ${signal}`
|
|
201
|
+
: `exited with code ${code}`;
|
|
202
|
+
if (this.stopping || e.removed) {
|
|
203
|
+
this.say(e, `daemon ${how}`);
|
|
204
|
+
this.entries.delete(key);
|
|
205
|
+
if (this.stopping && this.entries.size === 0 && this.drained)
|
|
206
|
+
this.drained();
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const delay = e.backoff.exited(this.deps.now());
|
|
210
|
+
this.say(e, `daemon ${how}; restarting in ${Math.round(delay / 1000)}s`);
|
|
211
|
+
this.later(key, e, delay);
|
|
212
|
+
}
|
|
213
|
+
later(key, e, ms) {
|
|
214
|
+
e.timer = this.deps.setTimer(() => this.launch(key, e), ms);
|
|
215
|
+
}
|
|
216
|
+
say(e, text) {
|
|
217
|
+
this.deps.log(`[${e.label}] ${text}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
exports.Supervisor = Supervisor;
|
|
221
|
+
async function serveCommand(argv, deps) {
|
|
222
|
+
const args = argv.filter((a) => a !== '--yes' && a !== '-y');
|
|
223
|
+
const [verb, ...rest] = args;
|
|
224
|
+
switch (verb) {
|
|
225
|
+
case undefined:
|
|
226
|
+
return supervise(deps);
|
|
227
|
+
case 'add':
|
|
228
|
+
return add(rest, deps);
|
|
229
|
+
case 'remove':
|
|
230
|
+
case 'rm':
|
|
231
|
+
return remove(rest, deps);
|
|
232
|
+
case 'list':
|
|
233
|
+
case 'ls':
|
|
234
|
+
return list(deps);
|
|
235
|
+
case 'install':
|
|
236
|
+
return install(deps);
|
|
237
|
+
case 'uninstall':
|
|
238
|
+
return uninstall(deps);
|
|
239
|
+
default:
|
|
240
|
+
deps.err(`looply serve: ${JSON.stringify(verb)} — no idea what that means.\n\n${exports.SERVE_USAGE}`);
|
|
241
|
+
return exports.EXIT_USAGE;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function load(deps) {
|
|
245
|
+
try {
|
|
246
|
+
return (0, serve_1.readRegistry)(deps.fs, (0, serve_1.servedFilePath)(deps.home));
|
|
247
|
+
}
|
|
248
|
+
catch (e) {
|
|
249
|
+
deps.err(`looply serve: ${e.message}`);
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function add(rest, deps) {
|
|
254
|
+
if (rest.length > 1) {
|
|
255
|
+
deps.err(`looply serve add: one path at a time.\n\n${exports.SERVE_USAGE}`);
|
|
256
|
+
return exports.EXIT_USAGE;
|
|
257
|
+
}
|
|
258
|
+
const path = (0, serve_1.normaliseRepoPath)(rest[0] ?? '.', deps.cwd, deps.platform);
|
|
259
|
+
if (!deps.fs.isDir(path)) {
|
|
260
|
+
deps.err(`looply serve add: ${path} is not a folder`);
|
|
261
|
+
return exports.EXIT_REFUSED;
|
|
262
|
+
}
|
|
263
|
+
const cfg = (0, serve_1.configPathOf)(path, deps.platform);
|
|
264
|
+
if (!deps.fs.exists(cfg)) {
|
|
265
|
+
deps.err(`looply serve add: ${path} has no .looply/config.yaml. Run \`looply init\` in that folder first, then add it again.`);
|
|
266
|
+
return exports.EXIT_REFUSED;
|
|
267
|
+
}
|
|
268
|
+
const registry = load(deps);
|
|
269
|
+
if (registry === null)
|
|
270
|
+
return exports.EXIT_REFUSED;
|
|
271
|
+
const out = (0, serve_1.addRepo)(registry, path, deps.now().toISOString(), deps.platform);
|
|
272
|
+
if (!out.added) {
|
|
273
|
+
deps.out(`serve: ${path} is already served — nothing to do.`);
|
|
274
|
+
return exports.EXIT_OK;
|
|
275
|
+
}
|
|
276
|
+
(0, serve_1.writeRegistry)(deps.fs, (0, serve_1.servedFilePath)(deps.home), out.registry);
|
|
277
|
+
deps.out(`serve: added ${path}`);
|
|
278
|
+
deps.out(' a running `looply serve` picks it up within 30 seconds; otherwise start one with `looply serve`, ' +
|
|
279
|
+
'or `looply serve install` to have it start at login.');
|
|
280
|
+
return exports.EXIT_OK;
|
|
281
|
+
}
|
|
282
|
+
function remove(rest, deps) {
|
|
283
|
+
if (rest.length !== 1) {
|
|
284
|
+
deps.err(`looply serve remove: which repository?\n\n${exports.SERVE_USAGE}`);
|
|
285
|
+
return exports.EXIT_USAGE;
|
|
286
|
+
}
|
|
287
|
+
const path = (0, serve_1.normaliseRepoPath)(rest[0], deps.cwd, deps.platform);
|
|
288
|
+
const registry = load(deps);
|
|
289
|
+
if (registry === null)
|
|
290
|
+
return exports.EXIT_REFUSED;
|
|
291
|
+
const out = (0, serve_1.removeRepo)(registry, path, deps.platform);
|
|
292
|
+
if (!out.removed) {
|
|
293
|
+
deps.out(`serve: ${path} is not served — nothing to do.`);
|
|
294
|
+
return exports.EXIT_OK;
|
|
295
|
+
}
|
|
296
|
+
(0, serve_1.writeRegistry)(deps.fs, (0, serve_1.servedFilePath)(deps.home), out.registry);
|
|
297
|
+
deps.out(`serve: removed ${path}; a running \`looply serve\` stops its daemon within 30 seconds.`);
|
|
298
|
+
return exports.EXIT_OK;
|
|
299
|
+
}
|
|
300
|
+
function list(deps) {
|
|
301
|
+
const registry = load(deps);
|
|
302
|
+
if (registry === null)
|
|
303
|
+
return exports.EXIT_REFUSED;
|
|
304
|
+
if (registry.repos.length === 0) {
|
|
305
|
+
deps.out('serve: no repositories are served yet. `looply serve add` in a repository to add it.');
|
|
306
|
+
return exports.EXIT_OK;
|
|
307
|
+
}
|
|
308
|
+
deps.out(`serve: ${registry.repos.length} served ${registry.repos.length === 1 ? 'repository' : 'repositories'}`);
|
|
309
|
+
for (const r of registry.repos) {
|
|
310
|
+
const ok = deps.fs.exists((0, serve_1.configPathOf)(r.path, deps.platform));
|
|
311
|
+
deps.out(` ${ok ? 'ok ' : 'MISSING'} ${r.path}${ok ? '' : ' (no .looply/config.yaml — skipped until it is back)'}`);
|
|
312
|
+
}
|
|
313
|
+
return exports.EXIT_OK;
|
|
314
|
+
}
|
|
315
|
+
function launchPaths(deps, verb) {
|
|
316
|
+
if (deps.launch.bin === null) {
|
|
317
|
+
deps.err(`looply serve${verb}: cannot find this CLI's built bin.js — build it first (npm run build)`);
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
return { node: deps.launch.node, bin: deps.launch.bin, log: (0, serve_1.serveLogPath)(deps.home) };
|
|
321
|
+
}
|
|
322
|
+
function install(deps) {
|
|
323
|
+
const paths = launchPaths(deps, ' install');
|
|
324
|
+
if (paths === null)
|
|
325
|
+
return exports.EXIT_REFUSED;
|
|
326
|
+
if (deps.platform !== 'win32') {
|
|
327
|
+
deps.out((0, serve_1.unixServiceHint)(paths, deps.platform));
|
|
328
|
+
return exports.EXIT_OK;
|
|
329
|
+
}
|
|
330
|
+
const folder = (0, serve_1.windowsStartupFolder)(deps.env);
|
|
331
|
+
if (folder === null) {
|
|
332
|
+
deps.err('looply serve install: %APPDATA% is not set, so the Startup folder cannot be found');
|
|
333
|
+
return exports.EXIT_REFUSED;
|
|
334
|
+
}
|
|
335
|
+
deps.fs.mkdirp((0, node_path_1.dirname)(paths.log));
|
|
336
|
+
deps.fs.mkdirp(folder);
|
|
337
|
+
const file = (0, node_path_1.join)(folder, serve_1.STARTUP_FILE);
|
|
338
|
+
deps.fs.write(file, (0, serve_1.windowsStartupScript)(paths));
|
|
339
|
+
deps.out(`serve: installed ${file}`);
|
|
340
|
+
deps.out(` the supervisor starts minimised at your next login, and writes to ${paths.log}`);
|
|
341
|
+
deps.out(' to start it now, run `looply serve`. `looply serve uninstall` removes the startup entry.');
|
|
342
|
+
return exports.EXIT_OK;
|
|
343
|
+
}
|
|
344
|
+
function uninstall(deps) {
|
|
345
|
+
if (deps.platform !== 'win32') {
|
|
346
|
+
deps.out('serve: nothing was installed on this platform; remove the launchd/systemd entry you created, if any.');
|
|
347
|
+
return exports.EXIT_OK;
|
|
348
|
+
}
|
|
349
|
+
const folder = (0, serve_1.windowsStartupFolder)(deps.env);
|
|
350
|
+
const file = folder === null ? null : (0, node_path_1.join)(folder, serve_1.STARTUP_FILE);
|
|
351
|
+
if (file === null || !deps.fs.exists(file)) {
|
|
352
|
+
deps.out('serve: not installed — nothing to remove.');
|
|
353
|
+
return exports.EXIT_OK;
|
|
354
|
+
}
|
|
355
|
+
deps.fs.remove(file);
|
|
356
|
+
deps.out(`serve: removed ${file}. A supervisor already running keeps running until you stop it.`);
|
|
357
|
+
return exports.EXIT_OK;
|
|
358
|
+
}
|
|
359
|
+
async function supervise(deps) {
|
|
360
|
+
const registry = load(deps);
|
|
361
|
+
if (registry === null)
|
|
362
|
+
return exports.EXIT_REFUSED;
|
|
363
|
+
if (registry.repos.length === 0) {
|
|
364
|
+
deps.out('serve: no repositories are served yet.');
|
|
365
|
+
deps.out(' in each repository you want served: `looply serve add` (it needs `looply init` first).');
|
|
366
|
+
deps.out(' then run `looply serve` again, or `looply serve install` to start it at login.');
|
|
367
|
+
return exports.EXIT_OK;
|
|
368
|
+
}
|
|
369
|
+
const lock = (0, serve_1.takeServeLock)(deps.fs, (0, serve_1.serveLockPath)(deps.home), { pid: deps.pid, at: deps.now().toISOString() }, deps.probe);
|
|
370
|
+
if (lock.kind === 'held') {
|
|
371
|
+
deps.err(`looply serve: another supervisor is already running (pid ${lock.pid}). Nothing started.`);
|
|
372
|
+
return exports.EXIT_HELD;
|
|
373
|
+
}
|
|
374
|
+
if (lock.tookOverFrom !== undefined)
|
|
375
|
+
deps.out(`serve: took over a stale lock left by pid ${lock.tookOverFrom}`);
|
|
376
|
+
if (!deps.supervisor || !deps.onSignal) {
|
|
377
|
+
lock.release();
|
|
378
|
+
deps.err('looply serve: no process wiring to supervise with');
|
|
379
|
+
return exports.EXIT_REFUSED;
|
|
380
|
+
}
|
|
381
|
+
const sup = new Supervisor({
|
|
382
|
+
...deps.supervisor(),
|
|
383
|
+
platform: deps.platform,
|
|
384
|
+
repos: () => (0, serve_1.readRegistry)(deps.fs, (0, serve_1.servedFilePath)(deps.home)).repos,
|
|
385
|
+
configExists: (repo) => deps.fs.exists((0, serve_1.configPathOf)(repo, deps.platform)),
|
|
386
|
+
log: (line) => deps.out(line),
|
|
387
|
+
});
|
|
388
|
+
deps.out(`serve: supervising ${registry.repos.length} listed ${registry.repos.length === 1 ? 'repository' : 'repositories'} (pid ${deps.pid}). Ctrl-C stops them all.`);
|
|
389
|
+
try {
|
|
390
|
+
await new Promise((resolve) => {
|
|
391
|
+
let asked = 0;
|
|
392
|
+
const off = deps.onSignal(() => {
|
|
393
|
+
asked += 1;
|
|
394
|
+
deps.out(asked === 1 ? 'serve: stopping every daemon — Ctrl-C again to kill them now' : 'serve: killing what is left');
|
|
395
|
+
sup.stop().then(() => {
|
|
396
|
+
off();
|
|
397
|
+
resolve();
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
sup.start();
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
finally {
|
|
404
|
+
lock.release();
|
|
405
|
+
}
|
|
406
|
+
deps.out('serve: stopped');
|
|
407
|
+
return exports.EXIT_OK;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* This CLI's own entry file, for spawning children and writing startup files.
|
|
411
|
+
*
|
|
412
|
+
* `serve-cmd.js` is built next to `bin.js`, so that is where it is looked for
|
|
413
|
+
* first — true both in this repository's dist and in an installed package,
|
|
414
|
+
* where npm's shim and `npx` both end at the same file. `require.main` is the
|
|
415
|
+
* fallback for a bundling that moved things.
|
|
416
|
+
*/
|
|
417
|
+
/* istanbul ignore next — real fs and process; the logic lives above */
|
|
418
|
+
function selfBin(fileExists) {
|
|
419
|
+
const candidates = [(0, node_path_1.join)(__dirname, 'bin.js'), require.main?.filename ?? ''];
|
|
420
|
+
for (const c of candidates) {
|
|
421
|
+
if (c.endsWith('.js') && fileExists(c)) {
|
|
422
|
+
try {
|
|
423
|
+
return (0, node_fs_1.realpathSync)(c);
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
return c;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
/* istanbul ignore next — process wiring, exercised by running the binary */
|
|
433
|
+
function nodeServeDeps() {
|
|
434
|
+
const node = process.execPath;
|
|
435
|
+
const bin = selfBin((p) => serve_1.nodeServeFs.exists(p));
|
|
436
|
+
return {
|
|
437
|
+
home: (0, node_os_1.homedir)(),
|
|
438
|
+
cwd: process.cwd(),
|
|
439
|
+
platform: process.platform,
|
|
440
|
+
env: process.env,
|
|
441
|
+
fs: serve_1.nodeServeFs,
|
|
442
|
+
pid: process.pid,
|
|
443
|
+
probe: run_lease_1.nodeProbe,
|
|
444
|
+
launch: { node, bin },
|
|
445
|
+
now: () => new Date(),
|
|
446
|
+
out: (line) => process.stdout.write(`${line}\n`),
|
|
447
|
+
err: (line) => process.stderr.write(`${line}\n`),
|
|
448
|
+
supervisor: () => {
|
|
449
|
+
// A supervisor whose terminal or log pipe went away keeps supervising;
|
|
450
|
+
// an unhandled EPIPE on its own stdout must not take every daemon down.
|
|
451
|
+
for (const s of [process.stdout, process.stderr])
|
|
452
|
+
s.on('error', () => undefined);
|
|
453
|
+
return {
|
|
454
|
+
now: () => Date.now(),
|
|
455
|
+
setTimer: (fn, ms) => setTimeout(fn, ms),
|
|
456
|
+
clearTimer: (h) => clearTimeout(h),
|
|
457
|
+
spawnDaemon: (repo, on) => {
|
|
458
|
+
if (bin === null) {
|
|
459
|
+
on.exit(null, null, new Error("this CLI's bin.js was not found"));
|
|
460
|
+
return { kill: () => undefined };
|
|
461
|
+
}
|
|
462
|
+
// `--no-color` because the output goes to a log; `--yes` because adding
|
|
463
|
+
// the repository was the consent (see the header).
|
|
464
|
+
const child = (0, node_child_process_1.spawn)(node, [bin, 'daemon', '--yes', '--no-color'], {
|
|
465
|
+
cwd: repo,
|
|
466
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
467
|
+
windowsHide: true,
|
|
468
|
+
});
|
|
469
|
+
for (const stream of [child.stdout, child.stderr]) {
|
|
470
|
+
const split = new serve_1.LineSplitter();
|
|
471
|
+
stream.setEncoding('utf8');
|
|
472
|
+
stream.on('data', (chunk) => split.push(chunk).forEach((l) => on.line(l)));
|
|
473
|
+
stream.on('end', () => split.flush().forEach((l) => on.line(l)));
|
|
474
|
+
}
|
|
475
|
+
child.on('error', (e) => on.exit(null, null, e));
|
|
476
|
+
child.on('close', (code, signal) => on.exit(code, signal));
|
|
477
|
+
return {
|
|
478
|
+
kill: (force) => {
|
|
479
|
+
try {
|
|
480
|
+
child.kill(force ? 'SIGKILL' : 'SIGTERM');
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
// Already gone; its `close` says so.
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
},
|
|
488
|
+
};
|
|
489
|
+
},
|
|
490
|
+
onSignal: (cb) => {
|
|
491
|
+
const signals = [
|
|
492
|
+
'SIGINT',
|
|
493
|
+
'SIGTERM',
|
|
494
|
+
...(process.platform === 'win32' ? ['SIGBREAK'] : []),
|
|
495
|
+
];
|
|
496
|
+
for (const s of signals)
|
|
497
|
+
process.on(s, cb);
|
|
498
|
+
return () => {
|
|
499
|
+
for (const s of signals)
|
|
500
|
+
process.off(s, cb);
|
|
501
|
+
};
|
|
502
|
+
},
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
//# sourceMappingURL=serve-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-cmd.js","sourceRoot":"","sources":["../src/serve-cmd.ts"],"names":[],"mappings":"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"}
|