@caweb/cli 1.0.4 → 1.1.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/bin/caweb +3 -17
- package/lib/caweb.js +20 -17
- package/lib/cli.js +194 -136
- package/lib/commands/destroy.js +66 -0
- package/lib/commands/index.js +29 -9
- package/lib/commands/shell.js +2 -3
- package/lib/commands/start.js +64 -72
- package/lib/commands/stop.js +41 -0
- package/lib/commands/tasks/update-plugins.js +15 -8
- package/lib/commands/test.js +15 -63
- package/lib/configs.js +79 -35
- package/lib/divi.js +28 -26
- package/lib/docker.js +24 -22
- package/lib/download-sources.js +14 -14
- package/lib/env.js +12 -7
- package/lib/options.js +1 -1
- package/lib/spinner.js +70 -0
- package/lib/wordpress.js +45 -35
- package/package.json +8 -3
- package/lib/commands/tasks/index.js +0 -13
- package/lib/config.yml +0 -3
package/lib/docker.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
'use strict';
|
|
2
1
|
/**
|
|
3
2
|
* External dependencies
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
import dockerCompose from 'docker-compose';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import loadConfig from '@wordpress/env/lib/config/load-config.js';
|
|
8
|
+
import getHostUser from '@wordpress/env/lib/get-host-user.js';
|
|
9
|
+
import { env } from 'node:process';
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
/**
|
|
@@ -17,24 +19,30 @@ const loadConfig = require( '@wordpress/env/lib/config/load-config' );
|
|
|
17
19
|
* @param {string} environment Which environment to run docker command on.
|
|
18
20
|
* @param {string[]} cmds Array of commands to run.
|
|
19
21
|
* @param {WPConfig} config The wp-env config object.
|
|
22
|
+
* @param {Object} spinner A CLI spinner which indicates progress.
|
|
20
23
|
*
|
|
21
|
-
* @returns {
|
|
24
|
+
* @returns {Promise}
|
|
22
25
|
*/
|
|
23
|
-
async function
|
|
26
|
+
async function runCLICmds(
|
|
24
27
|
environment,
|
|
25
28
|
cmds,
|
|
26
|
-
config
|
|
29
|
+
config,
|
|
30
|
+
spinner
|
|
27
31
|
) {
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return await dockerCompose.run(
|
|
33
|
+
// We return the promise whether there is an output or an error.
|
|
34
|
+
return await dockerCompose.run(
|
|
32
35
|
environment === 'development' ? 'cli' : 'tests-cli',
|
|
33
36
|
[ 'bash', '-c', cmds.join( ' && ' ) ],
|
|
34
37
|
{
|
|
35
38
|
cwd: config.workDirectoryPath,
|
|
36
|
-
commandOptions: [
|
|
39
|
+
commandOptions: [],
|
|
37
40
|
log: config.debug,
|
|
41
|
+
callback: (buffer, result) => {
|
|
42
|
+
if( config.debug ){
|
|
43
|
+
spinner.text = buffer.toString();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
).then(
|
|
40
48
|
(output) => {
|
|
@@ -44,23 +52,17 @@ async function runDockerCmds(
|
|
|
44
52
|
|
|
45
53
|
return '' !== output.out ? output.out : output.err;
|
|
46
54
|
},
|
|
47
|
-
(
|
|
55
|
+
(error) => {
|
|
48
56
|
// Remove the Container information and new lines.
|
|
49
|
-
|
|
57
|
+
error.err = error.err.replace(/\s*Container .*Running\n|\n/g, '')
|
|
50
58
|
|
|
51
|
-
return
|
|
59
|
+
return error;
|
|
52
60
|
}
|
|
53
61
|
);
|
|
54
62
|
|
|
55
|
-
} catch(error) {
|
|
56
|
-
console.log(error)
|
|
57
|
-
|
|
58
|
-
process.exit( 1 );
|
|
59
|
-
}
|
|
60
|
-
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
export {
|
|
67
|
+
runCLICmds
|
|
66
68
|
};
|
package/lib/download-sources.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Modified from wp-env
|
|
2
|
+
* Modified from wp-env
|
|
3
3
|
* Few modifications made:
|
|
4
4
|
* - Downloads CAWebPublishing Resources, excluding WordPress.
|
|
5
|
-
* - Target directory for downloadZipSource is expected to be absolute.
|
|
6
5
|
* - Ensure parent directory of source.path exists before attempting to extract in downloadZipSource, otherwise it will complain that file/directory doesn't exist.
|
|
7
6
|
* @see @wordpress/env/lib/download-sources.js
|
|
8
7
|
*/
|
|
9
|
-
|
|
8
|
+
|
|
10
9
|
/**
|
|
11
10
|
* External dependencies
|
|
12
11
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
import util from 'util';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import fs from 'fs-extra';
|
|
15
|
+
import SimpleGit from 'simple-git';
|
|
16
|
+
import got from 'got';
|
|
17
|
+
import stream from 'stream';
|
|
18
|
+
import zip from 'extract-zip';
|
|
19
|
+
import rim from 'rimraf';
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* Internal dependencies
|
|
@@ -23,9 +25,9 @@ const got = require( 'got' );
|
|
|
23
25
|
/**
|
|
24
26
|
* Promisified dependencies
|
|
25
27
|
*/
|
|
26
|
-
const pipeline = util.promisify(
|
|
27
|
-
const extractZip = util.promisify(
|
|
28
|
-
const rimraf = util.promisify(
|
|
28
|
+
const pipeline = util.promisify( stream.pipeline );
|
|
29
|
+
const extractZip = util.promisify( zip );
|
|
30
|
+
const rimraf = util.promisify( rim );
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* Download CAWeb Resources.
|
|
@@ -120,7 +122,6 @@ async function downloadSource(src, { onProgress, spinner, debug } ){
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
|
|
124
125
|
/**
|
|
125
126
|
* Clones the git repository at `source.url` into `source.path`. If the
|
|
126
127
|
* repository already exists, it is updated instead.
|
|
@@ -271,7 +272,6 @@ function dowloadPlugins(pluginDir){
|
|
|
271
272
|
]
|
|
272
273
|
}
|
|
273
274
|
|
|
274
|
-
|
|
275
|
+
export {
|
|
275
276
|
downloadSources
|
|
276
|
-
|
|
277
277
|
}
|
package/lib/env.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
'use strict';
|
|
2
1
|
/**
|
|
3
2
|
* Internal dependencies
|
|
4
3
|
*/
|
|
4
|
+
import start from './start.js';
|
|
5
|
+
import destroy from './destroy.js';
|
|
6
|
+
import test from './test.js';
|
|
7
|
+
import shell from './shell.js';
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
//const { LifecycleScriptError } = require( './execute-lifecycle-script' );
|
|
8
|
-
const commands = require( './commands' );
|
|
9
|
+
import updatePlugins from './tasks/update-plugins.js'
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
export {
|
|
12
|
+
start,
|
|
13
|
+
destroy,
|
|
14
|
+
test,
|
|
15
|
+
shell,
|
|
16
|
+
updatePlugins
|
|
17
|
+
}
|
package/lib/options.js
CHANGED
package/lib/spinner.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
|
|
4
|
+
// Colors.
|
|
5
|
+
const boldWhite = chalk.bold.white;
|
|
6
|
+
const wpPrimary = boldWhite.bgHex( '#00669b' );
|
|
7
|
+
const wpGreen = boldWhite.bgHex( '#4ab866' );
|
|
8
|
+
const wpRed = boldWhite.bgHex( '#d94f4f' );
|
|
9
|
+
const wpYellow = boldWhite.bgHex( '#f0b849' );
|
|
10
|
+
|
|
11
|
+
// Spinner.
|
|
12
|
+
const withSpinner =
|
|
13
|
+
( command ) =>
|
|
14
|
+
( ...args ) => {
|
|
15
|
+
const spinner = ora().start();
|
|
16
|
+
|
|
17
|
+
// commander passes arguments/options differently than yargs.
|
|
18
|
+
// lets combine arguments with options
|
|
19
|
+
const cmd = args.pop();
|
|
20
|
+
|
|
21
|
+
cmd.registeredArguments.forEach(arg => {
|
|
22
|
+
// get arg from list.
|
|
23
|
+
let v = args.shift();
|
|
24
|
+
|
|
25
|
+
// add arg to options.
|
|
26
|
+
args[args.length - 1][arg._name] = v;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// add any global options.
|
|
30
|
+
args[0] = {
|
|
31
|
+
...args[0],
|
|
32
|
+
...cmd.parent.opts()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
args[ 0 ].spinner = spinner;
|
|
36
|
+
let time = process.hrtime();
|
|
37
|
+
return command( ...args ).then(
|
|
38
|
+
( message ) => {
|
|
39
|
+
time = process.hrtime( time );
|
|
40
|
+
spinner.succeed(
|
|
41
|
+
`${ message || spinner.text } (in ${ time[ 0 ] }s ${ (
|
|
42
|
+
time[ 1 ] / 1e6
|
|
43
|
+
).toFixed( 0 ) }ms)`
|
|
44
|
+
);
|
|
45
|
+
process.exit( 0 );
|
|
46
|
+
},
|
|
47
|
+
( error ) => {
|
|
48
|
+
if( error ){
|
|
49
|
+
// Error is an unknown error. That means there was a bug in our code.
|
|
50
|
+
spinner.fail(
|
|
51
|
+
typeof error === 'string' ? error : error.message
|
|
52
|
+
);
|
|
53
|
+
// Disable reason: Using console.error() means we get a stack trace.
|
|
54
|
+
console.error( error );
|
|
55
|
+
process.exit( 1 );
|
|
56
|
+
}else{
|
|
57
|
+
spinner.fail( 'An unknown error occurred.' );
|
|
58
|
+
process.exit( 1 );
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export {
|
|
65
|
+
wpPrimary,
|
|
66
|
+
wpGreen,
|
|
67
|
+
wpRed,
|
|
68
|
+
wpYellow,
|
|
69
|
+
withSpinner
|
|
70
|
+
}
|
package/lib/wordpress.js
CHANGED
|
@@ -1,58 +1,71 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
const { writeFile } = require('fs-extra');
|
|
3
|
-
const path = require( 'path' );
|
|
4
|
-
const getHostUser = require( '@wordpress/env/lib/get-host-user' );
|
|
5
|
-
const { execSync } = require( 'child_process' );
|
|
6
|
-
|
|
7
1
|
/**
|
|
8
2
|
* External dependencies
|
|
9
3
|
*/
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
import path from 'node:path';
|
|
10
6
|
|
|
11
7
|
/**
|
|
12
8
|
* Internal dependencies
|
|
13
9
|
*/
|
|
14
|
-
|
|
10
|
+
import {runCLICmds} from './docker.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Promisified dependencies
|
|
14
|
+
*/
|
|
15
|
+
const { writeFile } = fs.promises;
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Checks whether WordPress environment is a multisite installation.
|
|
18
19
|
*
|
|
19
20
|
* @param {string} environment Which environment to check for multisite installation.
|
|
20
21
|
* @param {WPConfig} config The wp-env config object.
|
|
22
|
+
* @param {Object} spinner A CLI spinner which indicates progress.
|
|
21
23
|
* @returns
|
|
22
24
|
*/
|
|
23
|
-
async function isMultisite( environment, config ){
|
|
24
|
-
|
|
25
|
+
async function isMultisite( environment, config, spinner ){
|
|
26
|
+
|
|
27
|
+
const result = await runCLICmds(
|
|
25
28
|
environment,
|
|
26
29
|
[ 'wp config get MULTISITE' ],
|
|
27
|
-
config
|
|
30
|
+
config,
|
|
31
|
+
spinner
|
|
28
32
|
)
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* If the constant doesn't exist the wp cli returns an exit code of 1
|
|
36
|
+
* we have to return false, otherwise we can just return the cli result.
|
|
37
|
+
*/
|
|
38
|
+
return typeof result === 'object' && result.exitCode ? false : result;
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
/**
|
|
32
42
|
* Transforms an existing single-site installation into a multisite installation.
|
|
33
43
|
*
|
|
34
|
-
* @param {string}
|
|
35
|
-
* @param {WPConfig}
|
|
36
|
-
* @param {boolean}
|
|
44
|
+
* @param {string} environment Which environment to convert into a multisite installation.
|
|
45
|
+
* @param {WPConfig} config The wp-env config object.
|
|
46
|
+
* @param {boolean} subdomain True if converting to multisite subdomain.
|
|
47
|
+
* @param {Object} spinner A CLI spinner which indicates progress.
|
|
37
48
|
* @returns
|
|
38
49
|
*/
|
|
39
|
-
async function convertToMultisite( environment, config, subdomain ){
|
|
50
|
+
async function convertToMultisite( environment, config, subdomain, spinner ){
|
|
40
51
|
// before we can conver to multisite all plugins must be deactivated.
|
|
41
52
|
// first lets get all plugins
|
|
42
|
-
let activePlugins = await
|
|
53
|
+
let activePlugins = await runCLICmds(
|
|
43
54
|
environment,
|
|
44
55
|
['wp option get active_plugins --format=json'],
|
|
45
|
-
config
|
|
56
|
+
config,
|
|
57
|
+
spinner
|
|
46
58
|
)
|
|
47
59
|
|
|
48
60
|
activePlugins = Object.values(JSON.parse( activePlugins ));
|
|
49
61
|
|
|
50
62
|
// deactivate all active plugins.
|
|
51
63
|
if( activePlugins.length ){
|
|
52
|
-
await
|
|
64
|
+
await runCLICmds(
|
|
53
65
|
environment,
|
|
54
66
|
['wp plugin deactivate ' + activePlugins.join(' ')],
|
|
55
|
-
config
|
|
67
|
+
config,
|
|
68
|
+
spinner
|
|
56
69
|
)
|
|
57
70
|
}
|
|
58
71
|
|
|
@@ -63,10 +76,11 @@ async function convertToMultisite( environment, config, subdomain ){
|
|
|
63
76
|
command += ' --subdomains'
|
|
64
77
|
}
|
|
65
78
|
|
|
66
|
-
await
|
|
79
|
+
await runCLICmds(
|
|
67
80
|
environment,
|
|
68
81
|
[command],
|
|
69
|
-
config
|
|
82
|
+
config,
|
|
83
|
+
spinner
|
|
70
84
|
)
|
|
71
85
|
|
|
72
86
|
// generate .htaccess
|
|
@@ -74,10 +88,11 @@ async function convertToMultisite( environment, config, subdomain ){
|
|
|
74
88
|
|
|
75
89
|
// network activate all active plugins again.
|
|
76
90
|
if( activePlugins.length ){
|
|
77
|
-
await
|
|
91
|
+
await runCLICmds(
|
|
78
92
|
environment,
|
|
79
93
|
['wp plugin activate ' + activePlugins.join(' ') + ' --network'],
|
|
80
|
-
config
|
|
94
|
+
config,
|
|
95
|
+
spinner
|
|
81
96
|
)
|
|
82
97
|
}
|
|
83
98
|
|
|
@@ -86,8 +101,8 @@ async function convertToMultisite( environment, config, subdomain ){
|
|
|
86
101
|
/**
|
|
87
102
|
* Generates .htaccess file content.
|
|
88
103
|
*
|
|
89
|
-
* @param {string}
|
|
90
|
-
* @param {boolean} subdomain
|
|
104
|
+
* @param {string} environment Which environment to generate .htaccess for.
|
|
105
|
+
* @param {boolean} subdomain True if converting to multisite subdomain.
|
|
91
106
|
*/
|
|
92
107
|
async function generateHTAccess(environment, workDirectoryPath, subdomain){
|
|
93
108
|
let trailingSlash = subdomain ? '^wp-admin$ wp-admin/ [R=301,L]' : '^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/';
|
|
@@ -116,6 +131,7 @@ async function generateHTAccess(environment, workDirectoryPath, subdomain){
|
|
|
116
131
|
await writeFile(path.join(workDirectoryPath, folder, '.htaccess'), htaccess);
|
|
117
132
|
|
|
118
133
|
}
|
|
134
|
+
|
|
119
135
|
/**
|
|
120
136
|
* Configures WordPress for the given environment by installing WordPress,
|
|
121
137
|
* activating all plugins, and activating the first theme. These steps are
|
|
@@ -133,32 +149,26 @@ async function configureWordPress(environment, config, spinner, multisite, subdo
|
|
|
133
149
|
WP_PERMALINK
|
|
134
150
|
} = config.env[ environment ].config
|
|
135
151
|
|
|
136
|
-
const {name} = getHostUser();
|
|
137
|
-
|
|
138
|
-
const containerName = path.basename(workDirectoryPath) + ('tests' === environment ? '-tests' : '') + '-cli';
|
|
139
|
-
const containerID = await execSync(`docker ps -qf "name=${containerName}"`).toString().trim();
|
|
140
|
-
|
|
141
|
-
// Add cli config.yml to cli container.
|
|
142
|
-
await execSync(`docker exec ${containerID} mkdir -p /home/${name}/.wp-cli/ && docker cp ./lib/config.yml ${containerID}:/home/${name}/.wp-cli/config.yml`);
|
|
143
152
|
|
|
144
153
|
// Convert to multisite if flag was passed.
|
|
145
154
|
if( multisite ){
|
|
146
155
|
spinner.text = 'Converting to multisite ' + ( subdomain ? 'subdomain' : 'subdirectory') + '...'
|
|
147
156
|
|
|
148
|
-
await convertToMultisite( environment, config, subdomain )
|
|
157
|
+
await convertToMultisite( environment, config, subdomain, spinner )
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
// rewrite and flush permalink structure.
|
|
152
|
-
await
|
|
161
|
+
await runCLICmds(
|
|
153
162
|
environment,
|
|
154
163
|
[
|
|
155
164
|
`wp rewrite structure ${WP_PERMALINK} --hard`
|
|
156
165
|
],
|
|
157
|
-
config
|
|
166
|
+
config,
|
|
167
|
+
spinner
|
|
158
168
|
);
|
|
159
169
|
}
|
|
160
170
|
|
|
161
|
-
|
|
171
|
+
export {
|
|
162
172
|
configureWordPress,
|
|
163
173
|
isMultisite,
|
|
164
174
|
convertToMultisite,
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caweb/cli",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "CAWebPublishing Command Line Interface.",
|
|
5
|
-
"
|
|
5
|
+
"exports": "./lib/env.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"node": ">=16",
|
|
6
8
|
"files": [
|
|
7
9
|
"bin",
|
|
8
10
|
"lib"
|
|
@@ -16,6 +18,7 @@
|
|
|
16
18
|
},
|
|
17
19
|
"scripts": {
|
|
18
20
|
"caweb": "caweb",
|
|
21
|
+
"wp-env": "wp-env",
|
|
19
22
|
"local": "npm pack && npm i caweb-cli-%npm_package_version%.tgz",
|
|
20
23
|
"test": "echo \"Error: run tests from root\" && exit 0"
|
|
21
24
|
},
|
|
@@ -39,6 +42,7 @@
|
|
|
39
42
|
"dependencies": {
|
|
40
43
|
"@wordpress/env": "^9.0.0",
|
|
41
44
|
"chalk": "^4.0.0",
|
|
45
|
+
"commander": "^11.1.0",
|
|
42
46
|
"fs-extra": "^11.1.1"
|
|
43
47
|
},
|
|
44
48
|
"config": {
|
|
@@ -56,7 +60,8 @@
|
|
|
56
60
|
"ADMIN_COOKIE_PATH": "/",
|
|
57
61
|
"COOKIE_DOMAIN": "",
|
|
58
62
|
"COOKIEPATH": "",
|
|
59
|
-
"SITECOOKIEPATH": ""
|
|
63
|
+
"SITECOOKIEPATH": "",
|
|
64
|
+
"CONCATENATE_SCRIPTS": false
|
|
60
65
|
}
|
|
61
66
|
}
|
|
62
67
|
}
|
package/lib/config.yml
DELETED