@caweb/cli 1.1.0 → 1.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.
Files changed (51) hide show
  1. package/README.md +62 -27
  2. package/bin/caweb +1 -1
  3. package/bin/wp-cli.phar +0 -0
  4. package/commands/a11y.js +74 -0
  5. package/commands/blocks/create-block.js +109 -0
  6. package/commands/blocks/update-block.js +60 -0
  7. package/commands/build.js +73 -0
  8. package/commands/env/destroy.js +49 -0
  9. package/{lib/commands → commands/env}/start.js +30 -27
  10. package/{lib/commands → commands/env}/stop.js +4 -10
  11. package/{lib/commands → commands}/index.js +51 -39
  12. package/commands/serve.js +78 -0
  13. package/commands/sync.js +498 -0
  14. package/{lib/commands → commands}/tasks/update-plugins.js +2 -2
  15. package/commands/test.js +100 -0
  16. package/configs/aceconfig.js +28 -0
  17. package/{lib/configs.js → configs/docker-compose.js} +32 -55
  18. package/configs/webpack.config.js +119 -0
  19. package/configs/wp-env.js +76 -0
  20. package/gen/parser.js +166 -0
  21. package/gen/site-generator.js +111 -0
  22. package/lib/admin.js +40 -0
  23. package/lib/cli.js +129 -63
  24. package/lib/env.js +3 -11
  25. package/lib/helpers.js +109 -0
  26. package/lib/index.js +28 -0
  27. package/lib/spinner.js +10 -7
  28. package/lib/{caweb.js → wordpress/caweb.js} +1 -1
  29. package/lib/{divi.js → wordpress/divi.js} +1 -1
  30. package/lib/{download-sources.js → wordpress/download-sources.js} +75 -79
  31. package/lib/wordpress/index.js +16 -0
  32. package/lib/{options.js → wordpress/options.js} +1 -1
  33. package/lib/{wordpress.js → wordpress/wordpress.js} +4 -8
  34. package/package.json +42 -27
  35. package/template/assets/css/popover.css +80 -0
  36. package/template/assets/js/popover.js +30 -0
  37. package/template/block/edit.js.mustache +48 -0
  38. package/template/block/editor.scss.mustache +5 -0
  39. package/template/block/index.js.mustache +40 -0
  40. package/template/block/save.js.mustache +21 -0
  41. package/template/block/style.scss.mustache +6 -0
  42. package/template/index.cjs +48 -0
  43. package/template/plugin/$slug.php.mustache +135 -0
  44. package/template/plugin/core/cdec-api.php.mustache +44 -0
  45. package/template/plugin/core/filters.php.mustache +111 -0
  46. package/template/plugin/core/functions.php.mustache +25 -0
  47. package/template/plugin/inc/renderer.php.mustache +25 -0
  48. package/lib/commands/destroy.js +0 -66
  49. package/lib/commands/test.js +0 -46
  50. package/lib/docker.js +0 -68
  51. /package/{lib/commands → commands/tasks}/shell.js +0 -0
@@ -0,0 +1,111 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import path from 'path';
5
+ import fs from 'fs';
6
+ import HtmlWebpackPlugin from 'html-webpack-plugin';
7
+ import jsdom from 'jsdom';
8
+ import { fileURLToPath } from 'url';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import {
14
+ generatePages
15
+ } from './parser.js';
16
+
17
+ import {
18
+ projectPath,
19
+ appPath
20
+ } from '../lib/helpers.js';
21
+
22
+ const srcPath = path.join( appPath, 'src');
23
+ const dataPath = path.join( srcPath, 'data');
24
+ const assetsPath = path.join( srcPath, 'assets');
25
+
26
+ // default meta used for site generation when no meta is passed
27
+ const meta = {
28
+ "Author": "CAWebPublishing",
29
+ "Description": "State of California",
30
+ "Keywords": "California,government",
31
+ "viewport": "width=device-width, initial-scale=1.0, minimum-scale=1.0"
32
+ }
33
+
34
+
35
+ /**
36
+ * Returns an object containing all data from site.json and src/data/examples.json
37
+ *
38
+ * @returns {Object}
39
+ */
40
+ function getSiteData(){
41
+
42
+ // grab any sample data if it exists.
43
+ let sample = fs.existsSync( path.join(dataPath, 'examples.json') ) ? JSON.parse( fs.readFileSync( path.join(dataPath, 'examples.json') ) ) : {};
44
+
45
+ // grab any site data if it exists.
46
+ let site = fs.existsSync( path.join(appPath, 'site.json') ) ? JSON.parse( fs.readFileSync( path.join(appPath, 'site.json') ) ) : {};
47
+
48
+ // merge datasets together
49
+ let siteData = {
50
+ ...sample,
51
+ ...site
52
+ };
53
+
54
+ return siteData;
55
+ }
56
+
57
+ export default (webpackConfig) => {
58
+ // we only proceed if and index.html exists
59
+ if( ! fs.existsSync( path.join( srcPath, 'index.html' )) ){
60
+ return;
61
+ }
62
+
63
+ // we only want to display errors and warnings
64
+ webpackConfig.stats = 'errors-warnings';
65
+
66
+ // get site data
67
+ let siteData = getSiteData();
68
+
69
+ // if favicon doesn't exist use fallback asset.
70
+ let favicon = fs.existsSync(path.join(assetsPath, 'images', 'favicon.ico')) ?
71
+ path.join(assetsPath, 'images', 'favicon.ico') :
72
+ path.join(projectPath, 'assets', 'favicon.ico') ;
73
+
74
+ let defaultPage = {
75
+ minify: false,
76
+ favicon,
77
+ meta: siteData.meta || meta,
78
+ }
79
+
80
+ // add html
81
+ webpackConfig.plugins = [
82
+ ...webpackConfig.plugins,
83
+ new HtmlWebpackPlugin({
84
+ filename: path.join( process.cwd(), 'public', 'index.html'),
85
+ template: path.join(srcPath, 'index.html'),
86
+ //templateContent: generatePages(siteData),
87
+ title: 'Test Site',
88
+ ...defaultPage
89
+ })
90
+ ]
91
+
92
+ // add devServer
93
+ webpackConfig.devServer = {
94
+ devMiddleware: {
95
+ writeToDisk: true,
96
+ },
97
+ hot: false,
98
+ allowedHosts: 'auto',
99
+ host: 'localhost',
100
+ port: 9000,
101
+ compress: true,
102
+ proxy: {
103
+ '/public': {
104
+ pathRewrite: {
105
+ '^/build': '',
106
+ },
107
+ },
108
+ },
109
+ }
110
+
111
+ };
package/lib/admin.js ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import path from 'node:path';
5
+ import fs from 'fs-extra';
6
+
7
+ import { CAWEB_OPTIONS, DIVI_OPTIONS } from './options.js';
8
+
9
+ /**
10
+ * Generates the OVERRIDES.MD
11
+ *
12
+ */
13
+ export default async function generateOverridesMD() {
14
+
15
+ let output = [
16
+ '## [.wp-env.override.json](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/#wp-env-override-json)',
17
+ 'Any fields here will take precedence over .wp-env.json.',
18
+ '## <ins>Special Config Values</ins>',
19
+ ];
20
+
21
+ // Generate CAWeb Options overrides.
22
+ output.push('### <ins>CAWeb Options</ins>');
23
+ for (const [key, option] of Object.entries(CAWEB_OPTIONS)) {
24
+ output.push(`\`${key}\` - Updates CAWeb ${option.label} `);
25
+ }
26
+
27
+ // Generate Divi Options overrides.
28
+ output.push('### <ins>Divi Options</ins>');
29
+ for (const [group, options] of Object.entries(DIVI_OPTIONS)) {
30
+ for (const [key, option] of Object.entries(options)) {
31
+ output.push(`\`${key}\` - Updates CAWeb ${option.label} `);
32
+ }
33
+ }
34
+
35
+ fs.writeFileSync(
36
+ path.join(process.cwd(), 'docs', 'OVERRIDES.MD'),
37
+ output.join('\n')
38
+ );
39
+
40
+ };
package/lib/cli.js CHANGED
@@ -3,66 +3,54 @@
3
3
  */
4
4
  //const wpenv_cli = require('@wordpress/env/lib/cli');
5
5
 
6
- import path from 'node:path';
6
+ import path from 'path';
7
7
  import chalk from 'chalk';
8
- import parseXdebugMode from '@wordpress/env/lib/parse-xdebug-mode.js';
9
- import fs from 'fs-extra';
8
+ import fs from 'fs';
10
9
  import terminalLink from 'terminal-link';
11
- import { Command, Argument, Option } from 'commander';
10
+ import { Command, Argument, Option } from 'commander';
12
11
 
13
12
  /**
14
13
  * Internal dependencies
15
14
  */
16
- import * as env from './commands/index.js';
15
+ import * as env from '../commands/index.js';
17
16
  import {
18
17
  wpPrimary,
19
18
  wpGreen,
20
19
  wpYellow,
21
20
  wpRed,
22
- withSpinner
23
- } from './spinner.js';
21
+ withSpinner,
22
+ projectPath,
23
+ } from './index.js';
24
24
 
25
- const localPath = path.resolve( path.join(process.cwd(), 'node_modules/@caweb/cli/package.json') )
26
- const pkg = JSON.parse( await fs.readFile(localPath) );
25
+ const localFile = path.join(projectPath, 'package.json');
26
+ const pkg = JSON.parse( fs.readFileSync(localFile) );
27
27
  const program = new Command();
28
28
 
29
- export default function cli() {
30
- const envArg = new Argument('[environment]', 'Which environment to use.')
31
- .choices([
32
- 'development',
33
- 'tests',
34
- 'all'
35
- ])
36
- .default('development');
37
-
38
- const containerArg = new Argument('<container>', 'The underlying Docker service to run the command on.')
39
- .choices([
40
- 'mysql',
41
- 'tests-mysql',
42
- 'wordpress',
43
- 'tests-wordpress',
44
- 'cli',
45
- 'tests-cli',
46
- ])
47
- .default('development');
29
+ const containerArg = new Argument('<container>', 'The underlying Docker service to run the command on.')
30
+ .choices([
31
+ 'mysql',
32
+ 'tests-mysql',
33
+ 'wordpress',
34
+ 'tests-wordpress',
35
+ 'cli',
36
+ 'tests-cli',
37
+ ])
38
+ .default('development');
48
39
 
49
- program
50
- .name(wpPrimary( 'caweb'))
51
- .usage( wpYellow( '<command>' ) )
52
- .description('Command Line Interface utilized by CAWebPublishing to accomplish several tasks.')
53
- .version( pkg.version )
54
- .option(
55
- '--debug',
56
- 'Enable debug output.',
57
- false
58
- )
59
- .allowUnknownOption(true)
60
- .configureHelp({
61
- sortSubcommands: true,
62
- sortOptions: true,
63
- showGlobalOptions: true,
64
- })
65
- .addHelpCommand(false)
40
+ const envArg = new Argument('[environment]', 'Which environment to use.')
41
+ .choices([
42
+ 'development',
43
+ 'tests',
44
+ 'all'
45
+ ])
46
+ .default('development');
47
+
48
+
49
+ /**
50
+ * Adds commands for wp-env
51
+ */
52
+ function addWPEnvCommands(){
53
+
66
54
 
67
55
  // Start command.
68
56
  program.command('start')
@@ -90,6 +78,16 @@ export default function cli() {
90
78
  'True if excluding any downloads from CAWeb, use this if you want to use a local version of the CAWeb Theme, Configurations will still be applied.',
91
79
  false
92
80
  )
81
+ .option(
82
+ '-p, --plugin',
83
+ 'True if root directory is a plugin.',
84
+ false
85
+ )
86
+ .option(
87
+ '-t, --theme',
88
+ 'True if root directory is a theme.',
89
+ false
90
+ )
93
91
  .option(
94
92
  '-m, --multisite',
95
93
  'True if converting to multisite.',
@@ -118,13 +116,6 @@ export default function cli() {
118
116
  .allowUnknownOption(true)
119
117
  .action( withSpinner(env.destroy) )
120
118
 
121
- // Shell Command.
122
- program.command('shell')
123
- .description('Open shell terminal in WordPress environment.')
124
- .addArgument(envArg)
125
- .allowUnknownOption(true)
126
- .action( withSpinner(env.shell) )
127
-
128
119
  // Stop Command.
129
120
  program.command('stop')
130
121
  .description(
@@ -135,6 +126,12 @@ export default function cli() {
135
126
  .allowUnknownOption(true)
136
127
  .action( withSpinner(env.stop) )
137
128
 
129
+ // Install Path Command.
130
+ program.command('install-path')
131
+ .description('Get the path where all of the environment files are stored. This includes the Docker files, WordPress, PHPUnit files, and any sources that were downloaded.')
132
+ .allowUnknownOption(true)
133
+ .action( withSpinner(env.installPath) )
134
+
138
135
  // Clean Command.
139
136
  program.command('clean')
140
137
  .description(
@@ -162,7 +159,7 @@ export default function cli() {
162
159
  )
163
160
  .allowUnknownOption(true)
164
161
  .action( withSpinner(env.logs) )
165
-
162
+
166
163
 
167
164
  // Run Command.
168
165
  program.command('run')
@@ -179,12 +176,60 @@ export default function cli() {
179
176
  .allowUnknownOption(true)
180
177
  .action( withSpinner(env.run) )
181
178
 
179
+
180
+ // Shell Command.
181
+ program.command('shell')
182
+ .description('Open shell terminal in WordPress environment.')
183
+ .addArgument(envArg)
184
+ .allowUnknownOption(true)
185
+ .action( withSpinner(env.shell) )
182
186
 
183
- // Install Path Command.
184
- program.command('install-path')
185
- .description('Get the path where all of the environment files are stored. This includes the Docker files, WordPress, PHPUnit files, and any sources that were downloaded.')
187
+ }
188
+
189
+ export default function cli() {
190
+
191
+
192
+ program
193
+ .name(wpPrimary( 'caweb'))
194
+ .usage( wpYellow( '<command>' ) )
195
+ .description('Command Line Interface utilized by CAWebPublishing to accomplish several tasks.')
196
+ .version( pkg.version )
197
+ .option(
198
+ '--debug',
199
+ 'Enable debug output.',
200
+ false
201
+ )
186
202
  .allowUnknownOption(true)
187
- .action( withSpinner(env.installPath) )
203
+ .configureHelp({
204
+ sortSubcommands: true,
205
+ sortOptions: true,
206
+ showGlobalOptions: true,
207
+ })
208
+ .helpCommand(false)
209
+
210
+
211
+ // Build Command.
212
+ program.command('build')
213
+ .description('Builds the current project.')
214
+ .allowUnknownOption(true)
215
+ .action(withSpinner(env.build))
216
+
217
+
218
+ // Serve Command.
219
+ program.command('serve')
220
+ .description('Serve the current project')
221
+ .option(
222
+ '--no-template',
223
+ 'Disables inclusion of the template page header & footer, starting off with a plain html page.'
224
+ )
225
+ .allowUnknownOption(true)
226
+ .action(withSpinner(env.serve))
227
+
228
+ // a11y Command.
229
+ program.command('a11y')
230
+ .description('Runs accessibility checks.')
231
+ .allowUnknownOption(true)
232
+ .action(withSpinner(env.a11y))
188
233
 
189
234
  // Update Plugins Command.
190
235
  program.command('update-plugins')
@@ -194,18 +239,39 @@ export default function cli() {
194
239
  .allowUnknownOption(true)
195
240
  .action( withSpinner(env.updatePlugins) )
196
241
 
242
+ // Create a Design System Block Command.
243
+ program.command('create-block')
244
+ .description('Scaffold for WordPress plugin to register CA.gov Design System Block.')
245
+ .argument('<slug>', 'Plugin slug to use.')
246
+ .allowUnknownOption(true)
247
+ .action( withSpinner(env.createBlock) )
248
+
249
+ // Update a Design System Block Command.
250
+ program.command('update-block')
251
+ .description('Updates a CA.gov Design System Block.')
252
+ .argument('<slug>', 'Plugin slug to update.')
253
+ .allowUnknownOption(true)
254
+ .action( withSpinner(env.updateBlock) )
255
+
256
+
257
+ // Update a Design System Block Command.
258
+ program.command('sync')
259
+ .description('Sync changes from one destination to another.')
260
+ .argument('<from>', 'Target Site URL with current changes.')
261
+ .argument('<to>', 'Destination Site URL that should be synced.')
262
+ .allowUnknownOption(true)
263
+ .action( withSpinner(env.sync) )
264
+
197
265
  // Test Command.
198
266
  // Ensure this is commented out.
199
267
  program.command('test')
200
268
  .description('Test commands on a WordPress environment')
201
- .addArgument(envArg)
202
- .option(
203
- '--scripts',
204
- 'Execute any configured lifecycle scripts.',
205
- true
206
- )
269
+ //.addArgument(envArg)
207
270
  .allowUnknownOption(true)
208
271
  .action(withSpinner(env.test))
272
+
273
+
274
+ addWPEnvCommands();
209
275
 
210
276
  return program;
211
277
  };
package/lib/env.js CHANGED
@@ -1,17 +1,9 @@
1
1
  /**
2
2
  * Internal dependencies
3
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';
8
4
 
9
- import updatePlugins from './tasks/update-plugins.js'
5
+ import * as commands from './commands/index.js';
10
6
 
11
- export {
12
- start,
13
- destroy,
14
- test,
15
- shell,
16
- updatePlugins
7
+ export default {
8
+ ...commands
17
9
  }
package/lib/helpers.js ADDED
@@ -0,0 +1,109 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import path from 'path';
5
+ import spawn from 'cross-spawn';
6
+ import { fileURLToPath } from 'url';
7
+ import { sync as resolveBin } from 'resolve-bin';
8
+ import { v2 as dockerCompose } from 'docker-compose';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+
14
+ /**
15
+ * Path Directory Locations
16
+ * - currentPath - Current Directory
17
+ * - projectPath - Current Project Path
18
+ * - appPath - Current Application Path
19
+ */
20
+ const currentPath = path.dirname(fileURLToPath(import.meta.url));
21
+ const projectPath = path.resolve( currentPath, '..' );
22
+ const appPath = path.resolve( projectPath, '../../../' );
23
+
24
+ /**
25
+ * Runs command directly.
26
+ *
27
+ * @param string cmd Command to run.
28
+ * @param string[] args List of command arguments.
29
+ * @param string[] opts List of spawn options.
30
+ *
31
+ * @returns {Promise}
32
+ */
33
+ async function runCmd(cmd, args,opts = { stdio: 'inherit' }){
34
+ // fix various commands.
35
+ switch (cmd) {
36
+ case 'npm':
37
+ case 'npx':
38
+ /**
39
+ * On Windows we run npm.cmd, on Linux we run npm
40
+ */
41
+ cmd += /^win/.test(process.platform) ? '.cmd' : '';
42
+ break;
43
+ case 'webpack':
44
+ cmd = resolveBin(cmd)
45
+ break
46
+ }
47
+
48
+ return spawn.sync( cmd, args, {...opts, env: process.env});
49
+
50
+ }
51
+
52
+ /**
53
+ * Runs commands on the given WordPress environment.
54
+ *
55
+ * @param {string} environment Which environment to run docker command on.
56
+ * @param {string[]} cmds Array of commands to run.
57
+ * @param {WPConfig} config The wp-env config object.
58
+ * @param {Object} spinner A CLI spinner which indicates progress.
59
+ *
60
+ * @returns {Promise}
61
+ */
62
+ async function runCLICmds(
63
+ environment,
64
+ cmds,
65
+ config,
66
+ spinner
67
+ ) {
68
+
69
+ // We return the promise whether there is an output or an error.
70
+ return await dockerCompose.run(
71
+ environment === 'development' ? 'cli' : 'tests-cli',
72
+ [ 'bash', '-c', cmds.join( ' && ' ) ],
73
+ {
74
+ cwd: config.workDirectoryPath,
75
+ env: process.env,
76
+ commandOptions: [],
77
+ log: config.debug,
78
+ callback: (buffer, result) => {
79
+ if( config.debug ){
80
+ spinner.text = buffer.toString();
81
+ }
82
+ }
83
+ }
84
+ ).then(
85
+ (output) => {
86
+ // Remove the Container information and new lines.
87
+ output.err = output.err.replace(/\s*Container .*Running\n|\n/g, '')
88
+ output.out = output.out.replace(/\s*Container .*Running\n|\n/g, '')
89
+
90
+ return '' !== output.out ? output.out : output.err;
91
+ },
92
+ (error) => {
93
+ // Remove the Container information and new lines.
94
+ error.err = error.err.replace(/\s*Container .*Running\n|\n/g, '')
95
+
96
+ return error;
97
+ }
98
+ );
99
+ }
100
+
101
+
102
+
103
+ export {
104
+ currentPath,
105
+ projectPath,
106
+ appPath,
107
+ runCLICmds,
108
+ runCmd
109
+ };
package/lib/index.js ADDED
@@ -0,0 +1,28 @@
1
+ import {
2
+ wpPrimary,
3
+ wpGreen,
4
+ wpRed,
5
+ wpYellow,
6
+ withSpinner,
7
+ } from './spinner.js';
8
+
9
+ import {
10
+ runCmd,
11
+ runCLICmds,
12
+ currentPath,
13
+ projectPath,
14
+ appPath
15
+ } from './helpers.js';
16
+
17
+ export {
18
+ currentPath,
19
+ projectPath,
20
+ appPath,
21
+ wpPrimary,
22
+ wpGreen,
23
+ wpRed,
24
+ wpYellow,
25
+ withSpinner,
26
+ runCmd,
27
+ runCLICmds
28
+ }
package/lib/spinner.js CHANGED
@@ -18,13 +18,16 @@ const withSpinner =
18
18
  // lets combine arguments with options
19
19
  const cmd = args.pop();
20
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
- });
21
+ if( cmd.registeredArguments ){
22
+ cmd.registeredArguments.forEach(arg => {
23
+ // get arg from list.
24
+ let v = args.shift();
25
+
26
+ // add arg to options.
27
+ args[args.length - 1][arg._name] = v;
28
+ });
29
+ }
30
+
28
31
 
29
32
  // add any global options.
30
33
  args[0] = {
@@ -7,7 +7,7 @@ import retry from '@wordpress/env/lib/retry.js';
7
7
  * Internal dependencies
8
8
  */
9
9
  import { CAWEB_OPTIONS } from'./options.js';
10
- import { runCLICmds } from'./docker.js';
10
+ import { runCLICmds } from'../helpers.js';
11
11
  import { isMultisite } from'./wordpress.js';
12
12
  import { configureDivi } from'./divi.js';
13
13
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Internal dependencies
3
3
  */
4
- import { runCLICmds } from './docker.js';
4
+ import { runCLICmds } from '../helpers.js';
5
5
  import { DIVI_OPTIONS } from './options.js';
6
6
 
7
7