@loopress/cli 0.13.0 → 0.15.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/README.md +96 -44
- package/dist/commands/init.js +5 -5
- package/dist/commands/plugin/add.d.ts +0 -2
- package/dist/commands/plugin/add.js +6 -47
- package/dist/commands/plugin/pull.js +4 -6
- package/dist/commands/plugin/push.d.ts +1 -2
- package/dist/commands/plugin/push.js +18 -50
- package/dist/commands/project/pull.d.ts +8 -0
- package/dist/commands/project/pull.js +69 -0
- package/dist/commands/project/{sync.d.ts → push.d.ts} +1 -2
- package/dist/commands/project/{sync.js → push.js} +8 -44
- package/dist/commands/snippet/publish.js +1 -1
- package/dist/commands/status.js +6 -2
- package/dist/commands/telemetry/disable.d.ts +6 -0
- package/dist/commands/telemetry/disable.js +14 -0
- package/dist/commands/telemetry/enable.d.ts +6 -0
- package/dist/commands/telemetry/enable.js +14 -0
- package/dist/config/auth.manager.d.ts +4 -2
- package/dist/config/auth.manager.js +15 -5
- package/dist/config/project-config.manager.d.ts +7 -2
- package/dist/config/project-config.manager.js +39 -10
- package/dist/hooks/finally.js +17 -3
- package/dist/hooks/init.js +8 -16
- package/dist/lib/local-callback-server.d.ts +3 -3
- package/dist/lib/local-callback-server.js +14 -4
- package/dist/lib/open-browser.d.ts +1 -1
- package/dist/lib/open-browser.js +3 -10
- package/dist/lib/sentry.d.ts +1 -1
- package/dist/lib/sentry.js +17 -8
- package/dist/lib/wp-authorize-flow.d.ts +15 -3
- package/dist/lib/wp-authorize-flow.js +31 -24
- package/dist/lib/wp-client.d.ts +1 -1
- package/dist/lib/wp-client.js +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/global-config.generated.d.ts +13 -3
- package/dist/types/plugin.d.ts +4 -5
- package/dist/types/project-config.generated.d.ts +1 -4
- package/dist/utils/plugins.d.ts +3 -7
- package/dist/utils/plugins.js +27 -13
- package/oclif.manifest.json +236 -169
- package/package.json +6 -2
- package/schemas/global-config.schema.json +19 -3
- package/schemas/project-config.schema.json +3 -4
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ $ npm install -g @loopress/cli
|
|
|
21
21
|
$ lps COMMAND
|
|
22
22
|
running command...
|
|
23
23
|
$ lps (--version)
|
|
24
|
-
@loopress/cli/0.
|
|
24
|
+
@loopress/cli/0.15.0 linux-x64 node-v24.18.0
|
|
25
25
|
$ lps --help [COMMAND]
|
|
26
26
|
USAGE
|
|
27
27
|
$ lps COMMAND
|
|
@@ -35,8 +35,9 @@ Loopress sends crash reports to our Sentry project so we can find and fix bugs.
|
|
|
35
35
|
|
|
36
36
|
To opt out, either:
|
|
37
37
|
|
|
38
|
-
-
|
|
39
|
-
-
|
|
38
|
+
- run `lps telemetry disable` (persists across all future commands), or
|
|
39
|
+
- set `LOOPRESS_TELEMETRY_DISABLED=1` (overrides the persisted preference for a single run,
|
|
40
|
+
useful in CI).
|
|
40
41
|
|
|
41
42
|
A crash report includes the command name, its flags/args as typed, your Node.js
|
|
42
43
|
version, and OS. WordPress credentials are configured via `lps project config`
|
|
@@ -52,19 +53,22 @@ report.
|
|
|
52
53
|
* [`lps init`](#lps-init)
|
|
53
54
|
* [`lps login`](#lps-login)
|
|
54
55
|
* [`lps logout`](#lps-logout)
|
|
55
|
-
* [`lps plugin add SLUG
|
|
56
|
+
* [`lps plugin add SLUG`](#lps-plugin-add-slug)
|
|
56
57
|
* [`lps plugin pull`](#lps-plugin-pull)
|
|
57
58
|
* [`lps plugin push`](#lps-plugin-push)
|
|
58
59
|
* [`lps project config`](#lps-project-config)
|
|
59
60
|
* [`lps project list`](#lps-project-list)
|
|
61
|
+
* [`lps project pull`](#lps-project-pull)
|
|
62
|
+
* [`lps project push`](#lps-project-push)
|
|
60
63
|
* [`lps project remove`](#lps-project-remove)
|
|
61
64
|
* [`lps project switch`](#lps-project-switch)
|
|
62
|
-
* [`lps project sync`](#lps-project-sync)
|
|
63
65
|
* [`lps snippet list`](#lps-snippet-list)
|
|
64
66
|
* [`lps snippet publish [PATH]`](#lps-snippet-publish-path)
|
|
65
67
|
* [`lps snippet pull [PATH]`](#lps-snippet-pull-path)
|
|
66
68
|
* [`lps snippet push [PATH]`](#lps-snippet-push-path)
|
|
67
69
|
* [`lps status`](#lps-status)
|
|
70
|
+
* [`lps telemetry disable`](#lps-telemetry-disable)
|
|
71
|
+
* [`lps telemetry enable`](#lps-telemetry-enable)
|
|
68
72
|
|
|
69
73
|
## `lps composer pull`
|
|
70
74
|
|
|
@@ -86,7 +90,7 @@ EXAMPLES
|
|
|
86
90
|
$ lps composer pull --dry-run
|
|
87
91
|
```
|
|
88
92
|
|
|
89
|
-
_See code: [src/commands/composer/pull.ts](https://github.com/loopress/loopress/blob/v0.
|
|
93
|
+
_See code: [src/commands/composer/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/composer/pull.ts)_
|
|
90
94
|
|
|
91
95
|
## `lps composer push`
|
|
92
96
|
|
|
@@ -108,7 +112,7 @@ EXAMPLES
|
|
|
108
112
|
$ lps composer push --dry-run
|
|
109
113
|
```
|
|
110
114
|
|
|
111
|
-
_See code: [src/commands/composer/push.ts](https://github.com/loopress/loopress/blob/v0.
|
|
115
|
+
_See code: [src/commands/composer/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/composer/push.ts)_
|
|
112
116
|
|
|
113
117
|
## `lps help [COMMAND]`
|
|
114
118
|
|
|
@@ -145,7 +149,7 @@ EXAMPLES
|
|
|
145
149
|
$ lps init
|
|
146
150
|
```
|
|
147
151
|
|
|
148
|
-
_See code: [src/commands/init.ts](https://github.com/loopress/loopress/blob/v0.
|
|
152
|
+
_See code: [src/commands/init.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/init.ts)_
|
|
149
153
|
|
|
150
154
|
## `lps login`
|
|
151
155
|
|
|
@@ -162,7 +166,7 @@ EXAMPLES
|
|
|
162
166
|
$ lps login
|
|
163
167
|
```
|
|
164
168
|
|
|
165
|
-
_See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.
|
|
169
|
+
_See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/login.ts)_
|
|
166
170
|
|
|
167
171
|
## `lps logout`
|
|
168
172
|
|
|
@@ -179,19 +183,18 @@ EXAMPLES
|
|
|
179
183
|
$ lps logout
|
|
180
184
|
```
|
|
181
185
|
|
|
182
|
-
_See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.
|
|
186
|
+
_See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/logout.ts)_
|
|
183
187
|
|
|
184
|
-
## `lps plugin add SLUG
|
|
188
|
+
## `lps plugin add SLUG`
|
|
185
189
|
|
|
186
190
|
Add a WordPress.org plugin to loopress.json
|
|
187
191
|
|
|
188
192
|
```
|
|
189
193
|
USAGE
|
|
190
|
-
$ lps plugin add SLUG [
|
|
194
|
+
$ lps plugin add SLUG [-d]
|
|
191
195
|
|
|
192
196
|
ARGUMENTS
|
|
193
|
-
SLUG
|
|
194
|
-
[VERSION] Version to pin (default: latest)
|
|
197
|
+
SLUG Plugin slug on WordPress.org
|
|
195
198
|
|
|
196
199
|
FLAGS
|
|
197
200
|
-d, --dry-run Show what would change without making changes
|
|
@@ -202,12 +205,10 @@ DESCRIPTION
|
|
|
202
205
|
EXAMPLES
|
|
203
206
|
$ lps plugin add woocommerce
|
|
204
207
|
|
|
205
|
-
$ lps plugin add woocommerce 8.9.1
|
|
206
|
-
|
|
207
208
|
$ lps plugin add contact-form-7 --dry-run
|
|
208
209
|
```
|
|
209
210
|
|
|
210
|
-
_See code: [src/commands/plugin/add.ts](https://github.com/loopress/loopress/blob/v0.
|
|
211
|
+
_See code: [src/commands/plugin/add.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/plugin/add.ts)_
|
|
211
212
|
|
|
212
213
|
## `lps plugin pull`
|
|
213
214
|
|
|
@@ -229,7 +230,7 @@ EXAMPLES
|
|
|
229
230
|
$ lps plugin pull --dry-run
|
|
230
231
|
```
|
|
231
232
|
|
|
232
|
-
_See code: [src/commands/plugin/pull.ts](https://github.com/loopress/loopress/blob/v0.
|
|
233
|
+
_See code: [src/commands/plugin/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/plugin/pull.ts)_
|
|
233
234
|
|
|
234
235
|
## `lps plugin push`
|
|
235
236
|
|
|
@@ -251,7 +252,7 @@ EXAMPLES
|
|
|
251
252
|
$ lps plugin push --dry-run
|
|
252
253
|
```
|
|
253
254
|
|
|
254
|
-
_See code: [src/commands/plugin/push.ts](https://github.com/loopress/loopress/blob/v0.
|
|
255
|
+
_See code: [src/commands/plugin/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/plugin/push.ts)_
|
|
255
256
|
|
|
256
257
|
## `lps project config`
|
|
257
258
|
|
|
@@ -269,7 +270,7 @@ EXAMPLES
|
|
|
269
270
|
$ lps project config
|
|
270
271
|
```
|
|
271
272
|
|
|
272
|
-
_See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.
|
|
273
|
+
_See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/config.ts)_
|
|
273
274
|
|
|
274
275
|
## `lps project list`
|
|
275
276
|
|
|
@@ -286,58 +287,75 @@ EXAMPLES
|
|
|
286
287
|
$ lps project list
|
|
287
288
|
```
|
|
288
289
|
|
|
289
|
-
_See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.
|
|
290
|
+
_See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/list.ts)_
|
|
290
291
|
|
|
291
|
-
## `lps project
|
|
292
|
+
## `lps project pull`
|
|
292
293
|
|
|
293
|
-
|
|
294
|
+
Pull projects and environments from your Loopress account that are not configured locally yet
|
|
294
295
|
|
|
295
296
|
```
|
|
296
297
|
USAGE
|
|
297
|
-
$ lps project
|
|
298
|
+
$ lps project pull
|
|
298
299
|
|
|
299
300
|
DESCRIPTION
|
|
300
|
-
|
|
301
|
+
Pull projects and environments from your Loopress account that are not configured locally yet
|
|
301
302
|
|
|
302
303
|
EXAMPLES
|
|
303
|
-
$ lps project
|
|
304
|
+
$ lps project pull
|
|
304
305
|
```
|
|
305
306
|
|
|
306
|
-
_See code: [src/commands/project/
|
|
307
|
+
_See code: [src/commands/project/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/pull.ts)_
|
|
307
308
|
|
|
308
|
-
## `lps project
|
|
309
|
+
## `lps project push`
|
|
309
310
|
|
|
310
|
-
|
|
311
|
+
Push locally configured projects, environments and credentials to your Loopress account
|
|
311
312
|
|
|
312
313
|
```
|
|
313
314
|
USAGE
|
|
314
|
-
$ lps project
|
|
315
|
+
$ lps project push
|
|
315
316
|
|
|
316
317
|
DESCRIPTION
|
|
317
|
-
|
|
318
|
+
Push locally configured projects, environments and credentials to your Loopress account
|
|
318
319
|
|
|
319
320
|
EXAMPLES
|
|
320
|
-
$ lps project
|
|
321
|
+
$ lps project push
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
_See code: [src/commands/project/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/push.ts)_
|
|
325
|
+
|
|
326
|
+
## `lps project remove`
|
|
327
|
+
|
|
328
|
+
Remove one or more WordPress projects or environments
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
USAGE
|
|
332
|
+
$ lps project remove
|
|
333
|
+
|
|
334
|
+
DESCRIPTION
|
|
335
|
+
Remove one or more WordPress projects or environments
|
|
336
|
+
|
|
337
|
+
EXAMPLES
|
|
338
|
+
$ lps project remove
|
|
321
339
|
```
|
|
322
340
|
|
|
323
|
-
_See code: [src/commands/project/
|
|
341
|
+
_See code: [src/commands/project/remove.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/remove.ts)_
|
|
324
342
|
|
|
325
|
-
## `lps project
|
|
343
|
+
## `lps project switch`
|
|
326
344
|
|
|
327
|
-
|
|
345
|
+
Switch the active project and environment
|
|
328
346
|
|
|
329
347
|
```
|
|
330
348
|
USAGE
|
|
331
|
-
$ lps project
|
|
349
|
+
$ lps project switch
|
|
332
350
|
|
|
333
351
|
DESCRIPTION
|
|
334
|
-
|
|
352
|
+
Switch the active project and environment
|
|
335
353
|
|
|
336
354
|
EXAMPLES
|
|
337
|
-
$ lps project
|
|
355
|
+
$ lps project switch
|
|
338
356
|
```
|
|
339
357
|
|
|
340
|
-
_See code: [src/commands/project/
|
|
358
|
+
_See code: [src/commands/project/switch.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/switch.ts)_
|
|
341
359
|
|
|
342
360
|
## `lps snippet list`
|
|
343
361
|
|
|
@@ -357,7 +375,7 @@ EXAMPLES
|
|
|
357
375
|
$ lps snippet list
|
|
358
376
|
```
|
|
359
377
|
|
|
360
|
-
_See code: [src/commands/snippet/list.ts](https://github.com/loopress/loopress/blob/v0.
|
|
378
|
+
_See code: [src/commands/snippet/list.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/list.ts)_
|
|
361
379
|
|
|
362
380
|
## `lps snippet publish [PATH]`
|
|
363
381
|
|
|
@@ -380,7 +398,7 @@ EXAMPLES
|
|
|
380
398
|
$ lps snippet publish --path ./snippets
|
|
381
399
|
```
|
|
382
400
|
|
|
383
|
-
_See code: [src/commands/snippet/publish.ts](https://github.com/loopress/loopress/blob/v0.
|
|
401
|
+
_See code: [src/commands/snippet/publish.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/publish.ts)_
|
|
384
402
|
|
|
385
403
|
## `lps snippet pull [PATH]`
|
|
386
404
|
|
|
@@ -405,7 +423,7 @@ EXAMPLES
|
|
|
405
423
|
$ lps snippet pull --path ./snippets
|
|
406
424
|
```
|
|
407
425
|
|
|
408
|
-
_See code: [src/commands/snippet/pull.ts](https://github.com/loopress/loopress/blob/v0.
|
|
426
|
+
_See code: [src/commands/snippet/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/pull.ts)_
|
|
409
427
|
|
|
410
428
|
## `lps snippet push [PATH]`
|
|
411
429
|
|
|
@@ -431,7 +449,7 @@ EXAMPLES
|
|
|
431
449
|
$ lps snippet push --path ./snippets
|
|
432
450
|
```
|
|
433
451
|
|
|
434
|
-
_See code: [src/commands/snippet/push.ts](https://github.com/loopress/loopress/blob/v0.
|
|
452
|
+
_See code: [src/commands/snippet/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/push.ts)_
|
|
435
453
|
|
|
436
454
|
## `lps status`
|
|
437
455
|
|
|
@@ -448,5 +466,39 @@ EXAMPLES
|
|
|
448
466
|
$ lps status
|
|
449
467
|
```
|
|
450
468
|
|
|
451
|
-
_See code: [src/commands/status.ts](https://github.com/loopress/loopress/blob/v0.
|
|
469
|
+
_See code: [src/commands/status.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/status.ts)_
|
|
470
|
+
|
|
471
|
+
## `lps telemetry disable`
|
|
472
|
+
|
|
473
|
+
Disable error reporting to Sentry
|
|
474
|
+
|
|
475
|
+
```
|
|
476
|
+
USAGE
|
|
477
|
+
$ lps telemetry disable
|
|
478
|
+
|
|
479
|
+
DESCRIPTION
|
|
480
|
+
Disable error reporting to Sentry
|
|
481
|
+
|
|
482
|
+
EXAMPLES
|
|
483
|
+
$ lps telemetry disable
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
_See code: [src/commands/telemetry/disable.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/telemetry/disable.ts)_
|
|
487
|
+
|
|
488
|
+
## `lps telemetry enable`
|
|
489
|
+
|
|
490
|
+
Enable error reporting to Sentry
|
|
491
|
+
|
|
492
|
+
```
|
|
493
|
+
USAGE
|
|
494
|
+
$ lps telemetry enable
|
|
495
|
+
|
|
496
|
+
DESCRIPTION
|
|
497
|
+
Enable error reporting to Sentry
|
|
498
|
+
|
|
499
|
+
EXAMPLES
|
|
500
|
+
$ lps telemetry enable
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
_See code: [src/commands/telemetry/enable.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/telemetry/enable.ts)_
|
|
452
504
|
<!-- commandsstop -->
|
package/dist/commands/init.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Command } from '@oclif/core';
|
|
|
3
3
|
import { existsSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { configManager } from '../config/project-config.manager.js';
|
|
6
|
-
import {
|
|
6
|
+
import { writeLocalConfig } from '../utils/loopress-config.js';
|
|
7
7
|
// WordPress.org slugs for the two snippet plugins the Loopress WordPress plugin supports
|
|
8
8
|
// (see SnippetModule.php, which wires up both providers and auto-detects the active one).
|
|
9
9
|
const SNIPPET_PROVIDERS = [
|
|
@@ -76,11 +76,11 @@ export default class Init extends Command {
|
|
|
76
76
|
snippetsDir,
|
|
77
77
|
};
|
|
78
78
|
await writeLocalConfig(config);
|
|
79
|
-
let
|
|
79
|
+
let providerAdded = false;
|
|
80
80
|
if (providerChoice !== '__none__') {
|
|
81
81
|
try {
|
|
82
82
|
await this.config.runCommand('plugin:add', [providerChoice]);
|
|
83
|
-
|
|
83
|
+
providerAdded = true;
|
|
84
84
|
}
|
|
85
85
|
catch (error) {
|
|
86
86
|
this.warn(error.message);
|
|
@@ -89,8 +89,8 @@ export default class Init extends Command {
|
|
|
89
89
|
this.log(`\n✓ loopress.json created`);
|
|
90
90
|
this.log(` Project: ${projectLabel}`);
|
|
91
91
|
this.log(` Snippets: ${join(rootDir, snippetsDir)}`);
|
|
92
|
-
if (
|
|
93
|
-
this.log(` Plugin: ${providerChoice}
|
|
92
|
+
if (providerAdded) {
|
|
93
|
+
this.log(` Plugin: ${providerChoice}`);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { LoopressCommand } from '../../lib/base.js';
|
|
2
|
-
export declare function resolvePluginVersion(slug: string, version: string): Promise<string>;
|
|
3
2
|
export default class Add extends LoopressCommand {
|
|
4
3
|
static args: {
|
|
5
4
|
slug: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
-
version: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
5
|
};
|
|
8
6
|
static description: string;
|
|
9
7
|
static examples: string[];
|
|
@@ -1,73 +1,32 @@
|
|
|
1
1
|
import { Args } from '@oclif/core';
|
|
2
|
-
import got from 'got';
|
|
3
2
|
import { LoopressCommand } from '../../lib/base.js';
|
|
4
3
|
import { writeLocalConfig } from '../../utils/loopress-config.js';
|
|
5
|
-
const WP_ORG_API = 'https://api.wordpress.org/plugins/info/1.2/';
|
|
6
|
-
const WP_ORG_TIMEOUT_MS = 10_000;
|
|
7
|
-
export async function resolvePluginVersion(slug, version) {
|
|
8
|
-
if (version !== 'latest')
|
|
9
|
-
return version;
|
|
10
|
-
let info;
|
|
11
|
-
try {
|
|
12
|
-
info = await got
|
|
13
|
-
.get(WP_ORG_API, {
|
|
14
|
-
searchParams: {
|
|
15
|
-
action: 'plugin_information',
|
|
16
|
-
'request[slug]': slug,
|
|
17
|
-
},
|
|
18
|
-
timeout: { request: WP_ORG_TIMEOUT_MS },
|
|
19
|
-
})
|
|
20
|
-
.json();
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
throw new Error(`Plugin "${slug}" not found on WordPress.org.`);
|
|
24
|
-
}
|
|
25
|
-
if (info.error)
|
|
26
|
-
throw new Error(`Plugin "${slug}" not found on WordPress.org.`);
|
|
27
|
-
return info.version;
|
|
28
|
-
}
|
|
29
4
|
export default class Add extends LoopressCommand {
|
|
30
5
|
static args = {
|
|
31
6
|
slug: Args.string({ description: 'Plugin slug on WordPress.org', required: true }),
|
|
32
|
-
version: Args.string({ description: 'Version to pin (default: latest)' }),
|
|
33
7
|
};
|
|
34
8
|
static description = 'Add a WordPress.org plugin to loopress.json';
|
|
35
|
-
static examples = [
|
|
36
|
-
'$ lps plugin add woocommerce',
|
|
37
|
-
'$ lps plugin add woocommerce 8.9.1',
|
|
38
|
-
'$ lps plugin add contact-form-7 --dry-run',
|
|
39
|
-
];
|
|
9
|
+
static examples = ['$ lps plugin add woocommerce', '$ lps plugin add contact-form-7 --dry-run'];
|
|
40
10
|
static flags = {
|
|
41
11
|
...LoopressCommand.dryRunFlag,
|
|
42
12
|
};
|
|
43
13
|
async run() {
|
|
44
14
|
const { args } = await this.parse(Add);
|
|
45
15
|
const { slug } = args;
|
|
46
|
-
const requestedVersion = args.version ?? 'latest';
|
|
47
|
-
this.log(`Resolving ${slug}@${requestedVersion}...`);
|
|
48
|
-
let resolvedVersion;
|
|
49
|
-
try {
|
|
50
|
-
resolvedVersion = await resolvePluginVersion(slug, requestedVersion);
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
this.error(error.message);
|
|
54
|
-
}
|
|
55
|
-
this.log(`Resolved: ${slug}@${resolvedVersion}`);
|
|
56
16
|
const existing = this.localConfig.plugins ?? {};
|
|
57
|
-
if (existing[slug] ===
|
|
58
|
-
this.log(`${slug}
|
|
17
|
+
if (existing[slug] === 'latest') {
|
|
18
|
+
this.log(`${slug} is already in loopress.json, nothing to do.`);
|
|
59
19
|
return;
|
|
60
20
|
}
|
|
61
21
|
const updated = existing[slug] !== undefined;
|
|
62
|
-
const label = updated ? `${existing[slug]} → ${resolvedVersion}` : resolvedVersion;
|
|
63
22
|
if (this.dryRun) {
|
|
64
|
-
this.log(`[dry-run] Would ${updated ? 'update' : 'add'} ${slug}
|
|
23
|
+
this.log(`[dry-run] Would ${updated ? 'update' : 'add'} ${slug} in loopress.json`);
|
|
65
24
|
return;
|
|
66
25
|
}
|
|
67
26
|
await writeLocalConfig({
|
|
68
27
|
...this.localConfig,
|
|
69
|
-
plugins: { ...existing, [slug]:
|
|
28
|
+
plugins: { ...existing, [slug]: 'latest' },
|
|
70
29
|
});
|
|
71
|
-
this.log(`${updated ? 'Updated' : 'Added'} ${slug}
|
|
30
|
+
this.log(`${updated ? 'Updated' : 'Added'} ${slug}`);
|
|
72
31
|
}
|
|
73
32
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LoopressCommand } from '../../lib/base.js';
|
|
2
2
|
import { getComposerManagedSlugs, readComposerJson } from '../../utils/composer.js';
|
|
3
3
|
import { writeLocalConfig } from '../../utils/loopress-config.js';
|
|
4
|
-
import { mergePluginManifest } from '../../utils/plugins.js';
|
|
4
|
+
import { mergePluginManifest, parseInstalledPlugins } from '../../utils/plugins.js';
|
|
5
5
|
export default class Pull extends LoopressCommand {
|
|
6
6
|
static description = 'Pull installed plugins from WordPress into loopress.json';
|
|
7
7
|
static examples = ['$ lps plugin pull', '$ lps plugin pull --dry-run'];
|
|
@@ -11,10 +11,11 @@ export default class Pull extends LoopressCommand {
|
|
|
11
11
|
async run() {
|
|
12
12
|
const { url } = this.siteConfig;
|
|
13
13
|
this.log(`Pulling plugins from ${url}`);
|
|
14
|
-
const
|
|
14
|
+
const raw = await this.wp.get('wp/v2/plugins');
|
|
15
|
+
const installed = parseInstalledPlugins(raw);
|
|
15
16
|
const composerJson = await readComposerJson();
|
|
16
17
|
const composerSlugs = composerJson ? getComposerManagedSlugs(composerJson) : [];
|
|
17
|
-
const incoming = Object.fromEntries(installed.filter((p) => !composerSlugs.includes(p.slug)).map((p) => [p.slug,
|
|
18
|
+
const incoming = Object.fromEntries(installed.filter((p) => !composerSlugs.includes(p.slug)).map((p) => [p.slug, 'latest']));
|
|
18
19
|
if (composerSlugs.length > 0) {
|
|
19
20
|
const found = installed.filter((p) => composerSlugs.includes(p.slug)).map((p) => p.slug);
|
|
20
21
|
if (found.length > 0) {
|
|
@@ -38,8 +39,5 @@ export default class Pull extends LoopressCommand {
|
|
|
38
39
|
this.log(` + Added: ${added.join(', ')}`);
|
|
39
40
|
for (const u of updated)
|
|
40
41
|
this.log(` ~ Updated: ${u.slug} ${u.from} → ${u.to}`);
|
|
41
|
-
if (Object.keys(merged).length > 0) {
|
|
42
|
-
await this.wp.post('loopress/v1/plugins/auto-updates/disable', { slugs: Object.keys(merged) });
|
|
43
|
-
}
|
|
44
42
|
}
|
|
45
43
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { confirm } from '@inquirer/prompts';
|
|
2
1
|
import { Listr } from 'listr2';
|
|
3
2
|
import { PushCommand } from '../../lib/push-command.js';
|
|
4
3
|
import { getComposerManagedSlugs, readComposerJson } from '../../utils/composer.js';
|
|
5
|
-
import { diffPlugins } from '../../utils/plugins.js';
|
|
4
|
+
import { diffPlugins, parseInstalledPlugins } from '../../utils/plugins.js';
|
|
6
5
|
export default class Push extends PushCommand {
|
|
7
6
|
static description = 'Push plugins to WordPress to match loopress.json';
|
|
8
7
|
static examples = ['$ lps plugin push', '$ lps plugin push --dry-run'];
|
|
@@ -25,45 +24,39 @@ export default class Push extends PushCommand {
|
|
|
25
24
|
this.log('Run `lps composer push` to deploy them.');
|
|
26
25
|
}
|
|
27
26
|
this.log(`Pushing plugins to ${url}`);
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
27
|
+
const raw = await this.wp.get('wp/v2/plugins');
|
|
28
|
+
const installed = parseInstalledPlugins(raw);
|
|
29
|
+
const { toActivate, toInstall } = diffPlugins(filteredManifest, installed);
|
|
30
|
+
if (toInstall.length === 0 && toActivate.length === 0) {
|
|
31
31
|
this.log('Everything is already in sync.');
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
if (toInstall.length > 0) {
|
|
35
35
|
this.log(`\nTo install (${toInstall.length}):`);
|
|
36
36
|
for (const a of toInstall)
|
|
37
|
-
this.log(` + ${a.slug}
|
|
37
|
+
this.log(` + ${a.slug}`);
|
|
38
38
|
}
|
|
39
39
|
if (toActivate.length > 0) {
|
|
40
40
|
this.log(`\nTo activate (${toActivate.length}):`);
|
|
41
41
|
for (const a of toActivate)
|
|
42
42
|
this.log(` ↑ ${a.slug}`);
|
|
43
43
|
}
|
|
44
|
-
if (drifted.length > 0) {
|
|
45
|
-
this.log(`\nVersion mismatch (${drifted.length}):`);
|
|
46
|
-
for (const a of drifted) {
|
|
47
|
-
this.log(` ~ ${a.slug}: site has ${a.currentVersion}, manifest wants ${a.targetVersion}`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
44
|
if (this.dryRun)
|
|
51
45
|
return;
|
|
52
|
-
//
|
|
46
|
+
// Installing with `status: active` activates in the same call, so installs never need a
|
|
47
|
+
// separate activation step the way the old custom endpoint's two-step flow did.
|
|
53
48
|
if (toInstall.length > 0) {
|
|
54
49
|
await new Listr(toInstall.map((action) => ({
|
|
55
|
-
task: async (_ctx, task) => this.
|
|
56
|
-
title: `Install ${action.slug}
|
|
50
|
+
task: async (_ctx, task) => this.installPlugin(action.slug, task),
|
|
51
|
+
title: `Install ${action.slug}`,
|
|
57
52
|
})), { concurrent: false, exitOnError: false }).run();
|
|
58
53
|
}
|
|
59
|
-
// Activate installed-but-inactive plugins without prompting.
|
|
60
54
|
if (toActivate.length > 0) {
|
|
61
55
|
await new Listr(toActivate.map((action) => ({
|
|
62
|
-
task: async (_ctx, task) => this.activatePlugin(action.slug, task),
|
|
56
|
+
task: async (_ctx, task) => this.activatePlugin(action.file, action.slug, task),
|
|
63
57
|
title: `Activate ${action.slug}`,
|
|
64
58
|
})), { concurrent: false, exitOnError: false }).run();
|
|
65
59
|
}
|
|
66
|
-
await this.syncDrifted(drifted);
|
|
67
60
|
if (this.failedCount > 0) {
|
|
68
61
|
this.error(`${this.failedCount} plugin${this.failedCount === 1 ? '' : 's'} failed to install or activate.`);
|
|
69
62
|
}
|
|
@@ -75,18 +68,16 @@ export default class Push extends PushCommand {
|
|
|
75
68
|
// it falls back to plain logging. Rethrowing on failure (rather than swallowing) is what lets Listr
|
|
76
69
|
// mark the task as failed (red cross) instead of completed, even though `exitOnError: false` stops
|
|
77
70
|
// that failure from aborting sibling tasks in the same list.
|
|
78
|
-
async activatePlugin(slug, task) {
|
|
79
|
-
await this.performPluginAction('activate',
|
|
71
|
+
async activatePlugin(file, slug, task) {
|
|
72
|
+
await this.performPluginAction('activate', slug, () => this.wp.put(`wp/v2/plugins/${file}`, { status: 'active' }), task);
|
|
80
73
|
}
|
|
81
|
-
async
|
|
82
|
-
await this.performPluginAction('install',
|
|
83
|
-
await this.activatePlugin(slug, task);
|
|
74
|
+
async installPlugin(slug, task) {
|
|
75
|
+
await this.performPluginAction('install', slug, () => this.wp.post('wp/v2/plugins', { slug, status: 'active' }), task);
|
|
84
76
|
}
|
|
85
|
-
async performPluginAction(verb, request, task) {
|
|
86
|
-
const { body, endpoint, slug } = request;
|
|
77
|
+
async performPluginAction(verb, slug, request, task) {
|
|
87
78
|
try {
|
|
88
|
-
|
|
89
|
-
const message = `✓ ${
|
|
79
|
+
await request();
|
|
80
|
+
const message = `✓ ${slug} ${verb === 'install' ? 'installed and activated' : 'activated'}`;
|
|
90
81
|
if (task)
|
|
91
82
|
task.output = message;
|
|
92
83
|
else
|
|
@@ -102,27 +93,4 @@ export default class Push extends PushCommand {
|
|
|
102
93
|
throw error;
|
|
103
94
|
}
|
|
104
95
|
}
|
|
105
|
-
// Prompt per drifted plugin before syncing. Prompts run sequentially on plain stdout,
|
|
106
|
-
// before the Listr renderer takes over the terminal for the confirmed subset.
|
|
107
|
-
async syncDrifted(drifted) {
|
|
108
|
-
const confirmedDrift = [];
|
|
109
|
-
for (const action of drifted) {
|
|
110
|
-
const proceed = await confirm({
|
|
111
|
-
default: false,
|
|
112
|
-
message: `${action.slug} is at ${action.currentVersion} on the site but manifest wants ${action.targetVersion}. Sync to ${action.targetVersion}?`,
|
|
113
|
-
});
|
|
114
|
-
if (proceed) {
|
|
115
|
-
confirmedDrift.push(action);
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
this.log(` Skipped ${action.slug}`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
if (confirmedDrift.length === 0)
|
|
122
|
-
return;
|
|
123
|
-
await new Listr(confirmedDrift.map((action) => ({
|
|
124
|
-
task: async (_ctx, task) => this.installAndActivate(action.slug, action.targetVersion, task),
|
|
125
|
-
title: `Sync ${action.slug} to ${action.targetVersion}`,
|
|
126
|
-
})), { concurrent: false, exitOnError: false }).run();
|
|
127
|
-
}
|
|
128
96
|
}
|