@caweb/cli 1.0.5 → 1.2.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.
Files changed (38) hide show
  1. package/README.md +62 -27
  2. package/bin/caweb +3 -17
  3. package/lib/admin.js +40 -0
  4. package/lib/caweb.js +20 -17
  5. package/lib/cli.js +224 -142
  6. package/lib/commands/blocks/create-block.js +110 -0
  7. package/lib/commands/blocks/update-block.js +66 -0
  8. package/lib/commands/destroy.js +56 -0
  9. package/lib/commands/index.js +33 -9
  10. package/lib/commands/shell.js +2 -3
  11. package/lib/commands/start.js +57 -69
  12. package/lib/commands/stop.js +41 -0
  13. package/lib/commands/tasks/update-plugins.js +15 -8
  14. package/lib/commands/test.js +17 -70
  15. package/lib/configs.js +41 -21
  16. package/lib/divi.js +28 -26
  17. package/lib/download-sources.js +15 -15
  18. package/lib/env.js +3 -6
  19. package/lib/options.js +2 -2
  20. package/lib/spinner.js +70 -0
  21. package/lib/template/assets/css/popover.css +80 -0
  22. package/lib/template/assets/js/popover.js +30 -0
  23. package/lib/template/block/edit.js.mustache +48 -0
  24. package/lib/template/block/editor.scss.mustache +5 -0
  25. package/lib/template/block/index.js.mustache +40 -0
  26. package/lib/template/block/save.js.mustache +21 -0
  27. package/lib/template/block/style.scss.mustache +6 -0
  28. package/lib/template/index.cjs +48 -0
  29. package/lib/template/plugin/$slug.php.mustache +135 -0
  30. package/lib/template/plugin/core/cdec-api.php.mustache +44 -0
  31. package/lib/template/plugin/core/filters.php.mustache +111 -0
  32. package/lib/template/plugin/core/functions.php.mustache +25 -0
  33. package/lib/template/plugin/inc/renderer.php.mustache +25 -0
  34. package/lib/utils.js +150 -0
  35. package/lib/wordpress.js +45 -27
  36. package/package.json +10 -4
  37. package/lib/commands/tasks/index.js +0 -13
  38. package/lib/docker.js +0 -66
@@ -0,0 +1,110 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import path from 'node:path';
5
+ import fs from 'fs-extra';
6
+ import { spawn } from 'node:child_process';
7
+ import inquirer from 'inquirer';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import {runCmd} from '../../utils.js';
13
+ import updateBlock from './update-block.js';
14
+
15
+ const localPath = path.resolve( path.join(process.cwd(), 'node_modules/@caweb/cli/package.json') )
16
+ const pkg = JSON.parse( await fs.readFile(localPath) );
17
+
18
+ /**
19
+ * Get NPM Package Latest Version
20
+ * @param {string} options.slug Block slug.
21
+ * @param {Object} options.spinner A CLI spinner which indicates progress.
22
+ */
23
+ async function getNPMPackageVersion(pkg, spinner){
24
+ return await runCmd(
25
+ 'npm',
26
+ [
27
+ 'view',
28
+ `${pkg}`,
29
+ 'version'
30
+ ],
31
+ spinner
32
+ )
33
+
34
+ }
35
+
36
+ /**
37
+ * Create Block
38
+ *
39
+ * @param {Object} options
40
+ * @param {Object} options.spinner A CLI spinner which indicates progress.
41
+ * @param {boolean} options.debug True if debug mode is enabled.
42
+ * @param {string} options.slug Block slug.
43
+ */
44
+ export default async function createBlock({
45
+ spinner,
46
+ debug,
47
+ slug
48
+ } ) {
49
+ // if block directory already exists.
50
+ if( fs.existsSync(path.resolve(process.cwd(), slug)) ){
51
+ spinner.info(`${slug} already exists.`)
52
+
53
+ const { yesUpdate } = await inquirer.prompt( [
54
+ {
55
+ type: 'confirm',
56
+ name: 'yesUpdate',
57
+ message: 'Would you like to update it?',
58
+ default: false,
59
+ },
60
+ ] );
61
+
62
+ if( yesUpdate ){
63
+ spinner.text = `Updating ${slug}...`;
64
+ await updateBlock({spinner, debug, slug});
65
+ }
66
+ // create a new block
67
+ }else{
68
+ // Get cagov component version if it exists.
69
+ let version = await getNPMPackageVersion(`@cagov/${slug}`, spinner);
70
+
71
+ // call the wordpress create-block command using our template.
72
+ await runCmd(
73
+ 'npx',
74
+ [
75
+ `@wordpress/create-block`,
76
+ slug,
77
+ '--template=' + path.resolve( path.join(process.cwd(), 'node_modules/@caweb/cli/lib/template/index.cjs') )
78
+ ],
79
+ spinner,
80
+ {
81
+ stdio: 'inherit'
82
+ }
83
+ )
84
+
85
+ // install cagov npm package if it exists.
86
+ if( version ){
87
+ // capture spinner.text result
88
+ let spinnerText = spinner.text;
89
+ spinner.text = '';
90
+
91
+ await runCmd(
92
+ 'npm',
93
+ [
94
+ 'install',
95
+ `@cagov/${slug}@${version}`,
96
+ ],
97
+ spinner,
98
+ {
99
+ cwd: path.resolve( path.join(process.cwd(), slug ) ),
100
+ stdio: 'inherit'
101
+ }
102
+ )
103
+
104
+ spinner.text = spinnerText;
105
+
106
+ }
107
+ }
108
+
109
+
110
+ };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import path from 'node:path';
5
+ import fs from 'fs-extra';
6
+ import { spawn } from 'node:child_process';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import {runCmd} from '../../utils.js';
12
+ import createBlock from './create-block.js';
13
+
14
+ const localPath = path.resolve( path.join(process.cwd(), 'node_modules/@caweb/cli/package.json') )
15
+ const pkg = JSON.parse( await fs.readFile(localPath) );
16
+
17
+
18
+ /**
19
+ * Create Block
20
+ *
21
+ * @param {Object} options
22
+ * @param {Object} options.spinner A CLI spinner which indicates progress.
23
+ * @param {boolean} options.debug True if debug mode is enabled.
24
+ * @param {string} options.slug Block slug.
25
+ */
26
+ export default async function updateBlock({
27
+ spinner,
28
+ debug,
29
+ slug
30
+ } ) {
31
+
32
+ // if block directory exists.
33
+ if( fs.existsSync(path.resolve(process.cwd(), slug)) ){
34
+ spinner.text = `Updating ${slug} block plugin.`;
35
+
36
+ // make tmp directory
37
+ fs.ensureDir( `${slug}.tmp`);
38
+
39
+ // move inc directory to tmp directory
40
+ fs.copySync(`${slug}/inc/`, `${slug}.tmp/inc/`);
41
+
42
+ // move src directory to tmp directory
43
+ fs.copySync(`${slug}/src/`, `${slug}.tmp/src/`);
44
+
45
+ // delete old block.
46
+ fs.removeSync( `${slug}` );
47
+
48
+ // Recreate the block.
49
+ await createBlock({spinner, debug, slug});
50
+
51
+ // move inc directory back to block directory
52
+ fs.copySync(`${slug}.tmp/inc/`, `${slug}/inc/` );
53
+
54
+ // move src directory back to block directory
55
+ fs.copySync(`${slug}.tmp/src/`, `${slug}/src/`);
56
+
57
+ // delete tmp directory.
58
+ fs.removeSync( `${slug}.tmp` );
59
+
60
+ spinner.succeed(`${slug} has been updated!`);
61
+
62
+ }else{
63
+ spinner.fail(`${slug} plugin directory not found.`)
64
+ }
65
+
66
+ };
@@ -0,0 +1,56 @@
1
+
2
+ /**
3
+ * External dependencies
4
+ */
5
+ import { spawn } from 'node:child_process';
6
+ import { default as wpEnvDestroy } from '@wordpress/env/lib/commands/destroy.js';
7
+
8
+ /**
9
+ * Destroys the development server.
10
+ *
11
+ * @param {Object} options
12
+ * @param {Object} options.spinner A CLI spinner which indicates progress.
13
+ * @param {boolean} options.scripts Indicates whether or not lifecycle scripts should be executed.
14
+ * @param {boolean} options.debug True if debug mode is enabled.
15
+ *
16
+ */
17
+ export default async function destroy({
18
+ spinner,
19
+ scripts,
20
+ debug,
21
+ }) {
22
+
23
+ await wpEnvDestroy({spinner, scripts, debug });
24
+
25
+ // wp-env destroy completed successfully if spinner.text reads.
26
+ if( 'Removed WordPress environment.' === spinner.text ){
27
+ spinner.text = "Cleaning up...";
28
+
29
+ // Stop phpMyAdmin as well
30
+ // wp-env doesn't destroy the phpmyadmin image so we have to do it ourselves.
31
+ await new Promise( (resolve, reject) => {
32
+ const childProc = spawn(
33
+ 'docker',
34
+ [
35
+ 'image',
36
+ 'rm',
37
+ 'phpmyadmin'
38
+ ],
39
+ { stdio: 'ignore' },
40
+ spinner
41
+ );
42
+
43
+ childProc.on( 'error', reject );
44
+ childProc.on( 'exit', ( code ) => {
45
+ if ( code === 0 ) {
46
+ resolve();
47
+ } else {
48
+ reject( `Command failed with exit code ${ code }` );
49
+ }
50
+ } );
51
+ });
52
+ spinner.text = "Removed WordPress environment.'";
53
+
54
+ }
55
+
56
+ }
@@ -1,20 +1,44 @@
1
- 'use strict';
2
1
  /**
3
2
  * External dependencies
4
3
  */
5
4
 
5
+ /**
6
+ * These are default wp-env commands. No need to overwrite these commands
7
+ */
8
+ import clean from '@wordpress/env/lib/commands/clean.js';
9
+ import logs from '@wordpress/env/lib/commands/logs.js';
10
+ import run from '@wordpress/env/lib/commands/run.js';
11
+ import installPath from '@wordpress/env/lib/commands/install-path.js';
12
+
6
13
  /**
7
14
  * Internal dependencies
8
15
  */
9
- const shell = require('./shell')
10
- const start = require('./start')
11
- const test = require( './test' );
16
+ import shell from './shell.js';
17
+ import updatePlugins from './tasks/update-plugins.js'
18
+ import createBlock from './blocks/create-block.js'
19
+ import updateBlock from './blocks/update-block.js'
12
20
 
13
- const tasks = require('./tasks');
21
+ import test from './test.js';
14
22
 
15
- module.exports = {
16
- shell,
23
+ /**
24
+ * These are default wp-env commands, we overwrite these commands so we can run additional steps.
25
+ */
26
+ import start from './start.js';
27
+ import destroy from './destroy.js';
28
+ import stop from './stop.js';
29
+
30
+
31
+ export {
32
+ clean,
33
+ logs,
34
+ run,
35
+ installPath,
17
36
  start,
37
+ stop,
38
+ destroy,
18
39
  test,
19
- ...tasks
20
- };
40
+ shell,
41
+ updatePlugins,
42
+ createBlock,
43
+ updateBlock
44
+ }
@@ -1,8 +1,7 @@
1
- 'use strict';
2
1
  /**
3
2
  * External dependencies
4
3
  */
5
- const run = require( '@wordpress/env/lib/commands/run' );
4
+ import run from '@wordpress/env/lib/commands/run.js';
6
5
 
7
6
  /**
8
7
  * Internal dependencies
@@ -16,7 +15,7 @@ const run = require( '@wordpress/env/lib/commands/run' );
16
15
  * @param {boolean} options.environment Which environment to open terminal in.
17
16
  * @param {boolean} options.debug True if debug mode is enabled.
18
17
  */
19
- module.exports = async function shell({
18
+ export default async function shell({
20
19
  spinner,
21
20
  environment,
22
21
  debug
@@ -1,40 +1,36 @@
1
- /**
2
- * Modified from wp-env 8.11.0
3
- * @see @wordpress/env/lib/commands/start
4
- */
5
- 'use strict';
6
- /**
7
- * External dependencies
8
- */
9
- const path = require( 'path' );
10
- const fs = require( 'fs-extra' );
11
- const wpEnvStart = require('@wordpress/env/lib/commands/start');
12
- const util = require( 'util' );
13
- const { didCacheChange, getCache } = require( '@wordpress/env/lib/cache' );
14
- const {
1
+ import path from 'node:path';
2
+ import util from 'node:util';
3
+ import fs from 'fs-extra';
4
+ import yaml from 'js-yaml';
5
+ import dockerCompose from 'docker-compose';
6
+
7
+ import { default as wpEnvStart} from '@wordpress/env/lib/commands/start.js';
8
+ import {
15
9
  checkDatabaseConnection,
16
10
  canAccessWPORG
17
- } = require( '@wordpress/env/lib/wordpress' );
18
- const loadConfig = require( '@wordpress/env/lib/config/load-config' );
19
- const retry = require( '@wordpress/env/lib/retry' );
20
- const yaml = require( 'js-yaml' );
21
- const dockerCompose = require( 'docker-compose' );
11
+ } from '@wordpress/env/lib/wordpress.js';
12
+
13
+ import retry from '@wordpress/env/lib/retry.js';
22
14
 
23
15
  const CONFIG_CACHE_KEY = 'config_checksum';
24
16
 
17
+ import loadConfig from '@wordpress/env/lib/config/load-config.js';
18
+ import { didCacheChange, getCache } from '@wordpress/env/lib/cache.js';
19
+
25
20
  /**
26
21
  * Internal dependencies
27
22
  */
28
- const { configureCAWeb } = require('../caweb');
29
- const { buildWPEnvConfig, buildDockerComposeConfig } = require('../configs');
30
- const {downloadSources } = require('../download-sources');
31
- const { configureWordPress } = require('../wordpress');
23
+
24
+ import { configureCAWeb } from '../caweb.js';
25
+ import {downloadSources } from '../download-sources.js';
26
+ import { configureWordPress } from '../wordpress.js';
27
+ import { buildWPEnvConfig, buildDockerComposeConfig } from '../configs.js';
32
28
 
33
29
  /**
34
30
  * Promisified dependencies
35
31
  */
36
- const { writeFile } = fs.promises;
37
32
  const sleep = util.promisify( setTimeout );
33
+ const { writeFile } = fs.promises;
38
34
 
39
35
  /**
40
36
  * Starts the development server.
@@ -46,26 +42,31 @@ const sleep = util.promisify( setTimeout );
46
42
  * @param {boolean} options.scripts Indicates whether or not lifecycle scripts should be executed.
47
43
  * @param {boolean} options.debug True if debug mode is enabled.
48
44
  * @param {boolean} options.bare True if excluding any CAWeb Configurations.
45
+ * @param {boolean} options.plugin True if root directory is a plugin.
46
+ * @param {boolean} options.theme True if root directory is a theme.
49
47
  * @param {boolean} options.multisite True if converting to multisite.
50
48
  * @param {boolean} options.subdomain True if converting to multisite subdomain.
51
49
  *
52
50
  */
53
- module.exports = async function start({
51
+ export default async function start({
54
52
  spinner,
55
53
  update,
56
54
  xdebug,
57
55
  scripts,
58
56
  debug,
59
57
  bare,
58
+ plugin,
59
+ theme,
60
60
  multisite,
61
61
  subdomain
62
62
  }) {
63
+
63
64
  spinner.text = 'Writing configuration file...';
64
65
 
65
66
  // Write CAWeb .wp-env.json file.
66
67
  await writeFile(
67
68
  path.join(process.cwd(), '.wp-env.json'),
68
- JSON.stringify( buildWPEnvConfig(bare, multisite), null, 4 )
69
+ JSON.stringify( buildWPEnvConfig(bare, multisite, plugin, theme), null, 4 )
69
70
  );
70
71
 
71
72
  // Get current wp-env cache key
@@ -93,38 +94,26 @@ module.exports = async function start({
93
94
  ( await canAccessWPORG() );
94
95
 
95
96
 
96
- // Only run configurations when config has changed.
97
- if( shouldConfigureWp ){
98
- // Save pretext from wp-env if it exists for later.
99
- let preText = undefined !== spinner.prefixText ? spinner.prefixText.slice(0, -1) : '';
100
-
101
- try {
102
- // We aren't done lets clear the default WordPress text.
103
- spinner.prefixText = '';
104
- spinner.text = '';
105
-
106
- await checkDatabaseConnection( config );
107
- } catch ( error ) {
108
- // Wait 30 seconds for MySQL to accept connections.
109
- await retry( () => checkDatabaseConnection( config ), {
110
- times: 30,
111
- delay: 1000,
112
- } );
113
-
114
- // It takes 3-4 seconds for MySQL to be ready after it starts accepting connections.
115
- await sleep( 4000 );
116
- }
97
+ // Save pretext from wp-env if it exists for later.
98
+ let preText = undefined !== spinner.prefixText ? spinner.prefixText.slice(0, -1) : '';
117
99
 
118
- // Download any resources required for CAWeb.
119
- if( ! bare ){
120
- await downloadSources({spinner, config});
121
- }
100
+ // We aren't done lets clear the default WordPress text.
101
+ spinner.prefixText = '';
102
+ spinner.text = '';
103
+
104
+ // Download any resources required for CAWeb.
105
+ if( shouldConfigureWp && ! bare ){
106
+ await downloadSources({spinner, config});
107
+ }
108
+
109
+ // Write docker-compose.override.yml file to workDirectoryPath.
110
+ await writeFile(
111
+ path.join(workDirectoryPath, 'docker-compose.override.yml'),
112
+ yaml.dump( buildDockerComposeConfig(workDirectoryPath) )
113
+ );
122
114
 
123
- // Write docker-compose.override.yml file to workDirectoryPath.
124
- await writeFile(
125
- path.join(workDirectoryPath, 'docker-compose.override.yml'),
126
- yaml.dump( buildDockerComposeConfig(workDirectoryPath) )
127
- );
115
+ // Only run configurations when config has changed.
116
+ if( shouldConfigureWp ){
128
117
 
129
118
  // We need to bring the WordPress and CLI instances up again so they pick up
130
119
  // any config changes that may have been added to the docker-compose.override.yml.
@@ -158,24 +147,23 @@ module.exports = async function start({
158
147
  } ),
159
148
  ] );
160
149
 
161
- // Start phpMyAdmin Service.
162
- spinner.text = 'Starting phpMyAdmin Service';
150
+ }
163
151
 
164
- await dockerCompose.upMany(
165
- [
166
- 'phpmyadmin','tests-phpmyadmin',
167
- ], {
152
+ // Start phpMyAdmin Service.
153
+ spinner.text = 'Starting phpMyAdmin Service';
154
+
155
+ await dockerCompose.upOne(
156
+ 'phpmyadmin',
157
+ {
168
158
  cwd: workDirectoryPath,
169
159
  commandOptions: ['--build', '--force-recreate'],
170
160
  log: debug
171
- })
172
-
173
- spinner.prefixText = preText +
174
- `phpMyAdmin development site started at http://localhost:8080\n` +
175
- `phpMyAdmin test site started at http://localhost:9090\n\n`;
161
+ }
162
+ )
176
163
 
177
- spinner.text = 'Done!';
164
+ spinner.prefixText = preText +
165
+ `phpMyAdmin site started at http://localhost:8080\n\n`;
178
166
 
179
- }
167
+ spinner.text = 'Done!';
180
168
 
181
169
  };
@@ -0,0 +1,41 @@
1
+ import path from 'node:path';
2
+ import { spawn } from 'node:child_process';
3
+ import loadConfig from '@wordpress/env/lib/config/load-config.js';
4
+ import { v2 as dockerCompose } from 'docker-compose';
5
+
6
+ import { default as wpEnvStop } from '@wordpress/env/lib/commands/stop.js';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+
12
+ /**
13
+ * Promisified dependencies
14
+ */
15
+
16
+ /**
17
+ * Starts the development server.
18
+ *
19
+ * @param {Object} options
20
+ * @param {Object} options.spinner A CLI spinner which indicates progress.
21
+ * @param {boolean} options.scripts Indicates whether or not lifecycle scripts should be executed.
22
+ * @param {boolean} options.debug True if debug mode is enabled.
23
+ *
24
+ */
25
+ export default async function stop({
26
+ spinner,
27
+ debug,
28
+ }) {
29
+ const config = await loadConfig(path.resolve('.'));
30
+ const { workDirectoryPath } = config;
31
+
32
+ // Stop wp-env services
33
+ await wpEnvStop({spinner, debug });
34
+
35
+ // Stop phpMyAdmin as well
36
+ await dockerCompose.down( {
37
+ config: path.join(workDirectoryPath, 'docker-compose.override.yml'),
38
+ log: debug,
39
+ } );
40
+
41
+ }
@@ -1,15 +1,13 @@
1
- 'use strict';
2
1
  /**
3
2
  * External dependencies
4
3
  */
5
- const run = require('@wordpress/env/lib/commands/run');
4
+ import path from 'node:path';
5
+ import loadConfig from '@wordpress/env/lib/config/load-config.js';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
9
9
  */
10
- const { runDockerCmds } = require('../../docker');
11
- const path = require( 'path' );
12
- const loadConfig = require( '@wordpress/env/lib/config/load-config' );
10
+ import {runCLICmds} from '../../utils.js';
13
11
 
14
12
  /**
15
13
  * Promisified dependencies
@@ -22,15 +20,24 @@ const loadConfig = require( '@wordpress/env/lib/config/load-config' );
22
20
  * @param {Object} options.spinner A CLI spinner which indicates progress.
23
21
  * @param {string} options.environment Which environment to updated.
24
22
  */
25
- module.exports = async function updatePlugins({
23
+ export default async function updatePlugins({
26
24
  spinner,
27
- environment
25
+ environment,
26
+ slug
28
27
  }) {
29
28
 
30
29
  spinner.text = "Updating plugins...";
31
30
  const config = await loadConfig(path.resolve('.'));
32
31
 
33
- await runDockerCmds( environment, ['wp plugin update --all'], config );
32
+ let plugin = 'all' === slug ? '--all' : slug;
33
+
34
+ let result = await runCLICmds(
35
+ environment,
36
+ [`wp plugin update ${plugin}`],
37
+ config
38
+ );
39
+
40
+ spinner.prefixText = `${result}\n`;
34
41
 
35
42
  spinner.text = 'Completed updating plugins!'
36
43