git-watchtower 1.10.18 → 1.10.20
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/bin/git-watchtower.js +8 -0
- package/package.json +1 -1
- package/src/cli/args.js +32 -3
- package/src/server/process.js +9 -5
package/bin/git-watchtower.js
CHANGED
|
@@ -368,6 +368,14 @@ const cliArgs = parseCliArgs(process.argv.slice(2), {
|
|
|
368
368
|
onHelp: (v) => { console.log(getHelpText(v)); process.exit(0); },
|
|
369
369
|
});
|
|
370
370
|
|
|
371
|
+
if (cliArgs.errors.length > 0) {
|
|
372
|
+
for (const err of cliArgs.errors) {
|
|
373
|
+
console.error(`Error: ${err}`);
|
|
374
|
+
}
|
|
375
|
+
console.error('\nRun git-watchtower --help for usage information.');
|
|
376
|
+
process.exit(1);
|
|
377
|
+
}
|
|
378
|
+
|
|
371
379
|
// Configuration - these will be set after config is loaded
|
|
372
380
|
let SERVER_MODE = 'static'; // 'static' | 'command' | 'none'
|
|
373
381
|
let NO_SERVER = false; // Derived from SERVER_MODE === 'none'
|
package/package.json
CHANGED
package/src/cli/args.js
CHANGED
|
@@ -22,6 +22,7 @@ const { version: PACKAGE_VERSION } = require('../../package.json');
|
|
|
22
22
|
* @property {boolean} casino - Enable casino mode
|
|
23
23
|
* @property {boolean} web - Enable web dashboard mode
|
|
24
24
|
* @property {number|null} webPort - Web dashboard port override
|
|
25
|
+
* @property {string[]} errors - Validation errors encountered during parsing
|
|
25
26
|
*/
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -55,6 +56,8 @@ function parseArgs(argv, options = {}) {
|
|
|
55
56
|
// Actions
|
|
56
57
|
init: false,
|
|
57
58
|
casino: false,
|
|
59
|
+
// Parsing errors
|
|
60
|
+
errors: [],
|
|
58
61
|
};
|
|
59
62
|
|
|
60
63
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -63,21 +66,33 @@ function parseArgs(argv, options = {}) {
|
|
|
63
66
|
const mode = args[i + 1];
|
|
64
67
|
if (['static', 'command', 'none'].includes(mode)) {
|
|
65
68
|
result.mode = mode;
|
|
69
|
+
} else {
|
|
70
|
+
result.errors.push(`Invalid value for ${args[i]}: "${mode || ''}" (expected: static, command, none)`);
|
|
66
71
|
}
|
|
67
72
|
i++;
|
|
68
73
|
} else if (args[i] === '--port' || args[i] === '-p') {
|
|
69
74
|
const portValue = parseInt(args[i + 1], 10);
|
|
70
75
|
if (!isNaN(portValue) && portValue > 0 && portValue < 65536) {
|
|
71
76
|
result.port = portValue;
|
|
77
|
+
} else {
|
|
78
|
+
result.errors.push(`Invalid value for ${args[i]}: "${args[i + 1] || ''}" (expected: port number 1-65535)`);
|
|
72
79
|
}
|
|
73
80
|
i++;
|
|
74
81
|
} else if (args[i] === '--no-server' || args[i] === '-n') {
|
|
75
82
|
result.noServer = true;
|
|
76
83
|
} else if (args[i] === '--static-dir') {
|
|
77
|
-
|
|
84
|
+
if (args[i + 1] && !args[i + 1].startsWith('-')) {
|
|
85
|
+
result.staticDir = args[i + 1];
|
|
86
|
+
} else {
|
|
87
|
+
result.errors.push(`Missing value for ${args[i]}`);
|
|
88
|
+
}
|
|
78
89
|
i++;
|
|
79
90
|
} else if (args[i] === '--command' || args[i] === '-c') {
|
|
80
|
-
|
|
91
|
+
if (args[i + 1] !== undefined) {
|
|
92
|
+
result.command = args[i + 1];
|
|
93
|
+
} else {
|
|
94
|
+
result.errors.push(`Missing value for ${args[i]}`);
|
|
95
|
+
}
|
|
81
96
|
i++;
|
|
82
97
|
} else if (args[i] === '--restart-on-switch') {
|
|
83
98
|
result.restartOnSwitch = true;
|
|
@@ -86,7 +101,11 @@ function parseArgs(argv, options = {}) {
|
|
|
86
101
|
}
|
|
87
102
|
// Git settings
|
|
88
103
|
else if (args[i] === '--remote' || args[i] === '-r') {
|
|
89
|
-
|
|
104
|
+
if (args[i + 1] && !args[i + 1].startsWith('-')) {
|
|
105
|
+
result.remote = args[i + 1];
|
|
106
|
+
} else {
|
|
107
|
+
result.errors.push(`Missing value for ${args[i]}`);
|
|
108
|
+
}
|
|
90
109
|
i++;
|
|
91
110
|
} else if (args[i] === '--auto-pull') {
|
|
92
111
|
result.autoPull = true;
|
|
@@ -96,6 +115,8 @@ function parseArgs(argv, options = {}) {
|
|
|
96
115
|
const interval = parseInt(args[i + 1], 10);
|
|
97
116
|
if (!isNaN(interval) && interval > 0) {
|
|
98
117
|
result.pollInterval = interval;
|
|
118
|
+
} else {
|
|
119
|
+
result.errors.push(`Invalid value for ${args[i]}: "${args[i + 1] || ''}" (expected: positive integer in ms)`);
|
|
99
120
|
}
|
|
100
121
|
i++;
|
|
101
122
|
}
|
|
@@ -108,6 +129,8 @@ function parseArgs(argv, options = {}) {
|
|
|
108
129
|
const count = parseInt(args[i + 1], 10);
|
|
109
130
|
if (!isNaN(count) && count > 0) {
|
|
110
131
|
result.visibleBranches = count;
|
|
132
|
+
} else {
|
|
133
|
+
result.errors.push(`Invalid value for ${args[i]}: "${args[i + 1] || ''}" (expected: positive integer)`);
|
|
111
134
|
}
|
|
112
135
|
i++;
|
|
113
136
|
} else if (args[i] === '--casino') {
|
|
@@ -120,6 +143,8 @@ function parseArgs(argv, options = {}) {
|
|
|
120
143
|
const webPortValue = parseInt(args[i + 1], 10);
|
|
121
144
|
if (!isNaN(webPortValue) && webPortValue > 0 && webPortValue < 65536) {
|
|
122
145
|
result.webPort = webPortValue;
|
|
146
|
+
} else {
|
|
147
|
+
result.errors.push(`Invalid value for ${args[i]}: "${args[i + 1] || ''}" (expected: port number 1-65535)`);
|
|
123
148
|
}
|
|
124
149
|
i++;
|
|
125
150
|
}
|
|
@@ -135,6 +160,10 @@ function parseArgs(argv, options = {}) {
|
|
|
135
160
|
options.onHelp(PACKAGE_VERSION);
|
|
136
161
|
}
|
|
137
162
|
}
|
|
163
|
+
// Unknown flag
|
|
164
|
+
else if (args[i].startsWith('-')) {
|
|
165
|
+
result.errors.push(`Unknown option: ${args[i]}`);
|
|
166
|
+
}
|
|
138
167
|
}
|
|
139
168
|
return result;
|
|
140
169
|
}
|
package/src/server/process.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const { spawn } = require('child_process');
|
|
7
7
|
const { ServerError } = require('../utils/errors');
|
|
8
|
+
const { Mutex } = require('../utils/async');
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @typedef {Object} ServerProcessState
|
|
@@ -90,6 +91,7 @@ class ProcessManager {
|
|
|
90
91
|
this.crashed = false;
|
|
91
92
|
this.logs = [];
|
|
92
93
|
this.command = '';
|
|
94
|
+
this._restartMutex = new Mutex();
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
/**
|
|
@@ -283,13 +285,15 @@ class ProcessManager {
|
|
|
283
285
|
* @returns {Promise<{success: boolean, error?: Error, pid?: number}>}
|
|
284
286
|
*/
|
|
285
287
|
async restart() {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
+
return this._restartMutex.withLock(async () => {
|
|
289
|
+
const command = this.command;
|
|
290
|
+
this.stop();
|
|
288
291
|
|
|
289
|
-
|
|
290
|
-
|
|
292
|
+
// Wait before restarting
|
|
293
|
+
await new Promise((resolve) => setTimeout(resolve, RESTART_DELAY));
|
|
291
294
|
|
|
292
|
-
|
|
295
|
+
return this.start(command);
|
|
296
|
+
});
|
|
293
297
|
}
|
|
294
298
|
|
|
295
299
|
/**
|