@automattic/jetpack-cli 0.1.0-beta.2 → 0.1.0-beta3

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 (3) hide show
  1. package/README.md +18 -0
  2. package/bin/jp.js +149 -124
  3. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # Jetpack
2
+
3
+
4
+ ## How to install Jetpack plugin on your site
5
+ ### Installation From Git Repo
6
+
7
+ ## Contribute
8
+
9
+ ## Get Help
10
+
11
+ ## Security
12
+
13
+ Need to report a security vulnerability? Go to [https://automattic.com/security/](https://automattic.com/security/) or directly to our security bug bounty site [https://hackerone.com/automattic](https://hackerone.com/automattic).
14
+
15
+ ## License
16
+
17
+ Licensed under [GNU General Public License v2 (or later)](./LICENSE.txt).
18
+
package/bin/jp.js CHANGED
@@ -1,13 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawnSync } from 'child_process';
4
- import fs from 'fs';
4
+ import fs, { readFileSync } from 'fs';
5
5
  import { dirname, resolve } from 'path';
6
6
  import process from 'process';
7
+ import { fileURLToPath } from 'url';
7
8
  import chalk from 'chalk';
8
9
  import dotenv from 'dotenv';
9
10
  import prompts from 'prompts';
10
11
 
12
+ // Get package.json path relative to this file
13
+ const __dirname = dirname( fileURLToPath( import.meta.url ) );
14
+ const packageJson = JSON.parse( readFileSync( resolve( __dirname, '../package.json' ), 'utf8' ) );
15
+
11
16
  /**
12
17
  * Check if a directory is the monorepo root.
13
18
  *
@@ -46,7 +51,6 @@ const findMonorepoRoot = startDir => {
46
51
  * @throws {Error} If clone fails
47
52
  */
48
53
  const cloneMonorepo = async targetDir => {
49
- // eslint-disable-next-line no-console
50
54
  console.log( chalk.blue( 'Cloning Jetpack monorepo...' ) );
51
55
  const result = spawnSync(
52
56
  'git',
@@ -84,15 +88,15 @@ const initJetpack = async () => {
84
88
 
85
89
  try {
86
90
  await cloneMonorepo( targetDir );
87
- // eslint-disable-next-line no-console
91
+
88
92
  console.log( chalk.green( '\nJetpack monorepo has been cloned successfully!' ) );
89
- // eslint-disable-next-line no-console
93
+
90
94
  console.log( '\nNext steps:' );
91
- // eslint-disable-next-line no-console
95
+
92
96
  console.log( '1. cd', response.directory );
93
- // eslint-disable-next-line no-console
97
+
94
98
  console.log( '2. jp docker up' );
95
- // eslint-disable-next-line no-console
99
+
96
100
  console.log( '3. jp docker install' );
97
101
  } catch ( error ) {
98
102
  throw new Error( `Failed to initialize Jetpack: ${ error.message }` );
@@ -104,6 +108,12 @@ const main = async () => {
104
108
  try {
105
109
  const args = process.argv.slice( 2 );
106
110
 
111
+ // Handle version flag
112
+ if ( args[ 0 ] === '--version' || args[ 0 ] === '-v' ) {
113
+ console.log( chalk.green( packageJson.version ) );
114
+ return;
115
+ }
116
+
107
117
  // Handle 'init' command specially
108
118
  if ( args[ 0 ] === 'init' ) {
109
119
  await initJetpack();
@@ -114,144 +124,160 @@ const main = async () => {
114
124
  const monorepoRoot = findMonorepoRoot( process.cwd() );
115
125
 
116
126
  if ( ! monorepoRoot ) {
117
- // eslint-disable-next-line no-console
118
127
  console.error( chalk.red( 'Could not find Jetpack monorepo.' ) );
119
- // eslint-disable-next-line no-console
128
+
120
129
  console.log( '\nTo get started:' );
121
- // eslint-disable-next-line no-console
130
+
122
131
  console.log( '1. Run', chalk.blue( 'jp init' ), 'to clone the repository' );
123
- // eslint-disable-next-line no-console
132
+
124
133
  console.log( ' OR' );
125
- // eslint-disable-next-line no-console
134
+
126
135
  console.log( '2. Navigate to an existing Jetpack monorepo directory' );
127
136
  throw new Error( 'Monorepo not found' );
128
137
  }
129
138
 
130
- // Handle docker commands on the host
139
+ // Handle docker commands that must run on the host machine
131
140
  if ( args[ 0 ] === 'docker' ) {
132
- // Commands that should run in the container
133
- const containerCommands = [ 'build-image', 'install' ];
134
- if ( containerCommands.includes( args[ 1 ] ) ) {
135
- const result = spawnSync(
136
- resolve( monorepoRoot, 'tools/docker/bin/monorepo' ),
137
- [ 'pnpm', 'jetpack', ...args ],
138
- {
139
- stdio: 'inherit',
140
- shell: true,
141
- cwd: monorepoRoot,
142
- }
143
- );
141
+ const hostCommands = [ 'up', 'down', 'stop', 'clean' ];
142
+ if ( hostCommands.includes( args[ 1 ] ) ) {
143
+ // Handle command-specific setup/cleanup
144
+ if ( args[ 1 ] === 'up' ) {
145
+ // Create required directories
146
+ fs.mkdirSync( resolve( monorepoRoot, 'tools/docker/data/jetpack_dev_mysql' ), {
147
+ recursive: true,
148
+ } );
149
+ fs.mkdirSync( resolve( monorepoRoot, 'tools/docker/data/ssh.keys' ), {
150
+ recursive: true,
151
+ } );
152
+ fs.mkdirSync( resolve( monorepoRoot, 'tools/docker/wordpress' ), { recursive: true } );
144
153
 
145
- if ( result.status !== 0 ) {
146
- throw new Error( `Command failed with status ${ result.status }` );
147
- }
148
- return;
149
- }
154
+ // Create empty .env file
155
+ fs.writeFileSync( resolve( monorepoRoot, 'tools/docker/.env' ), '' );
150
156
 
151
- // Run config generation first if this is an 'up' command
152
- if ( args[ 1 ] === 'up' ) {
153
- // Create required directories
154
- fs.mkdirSync( resolve( monorepoRoot, 'tools/docker/data/jetpack_dev_mysql' ), {
155
- recursive: true,
156
- } );
157
- fs.mkdirSync( resolve( monorepoRoot, 'tools/docker/data/ssh.keys' ), { recursive: true } );
158
- fs.mkdirSync( resolve( monorepoRoot, 'tools/docker/wordpress' ), { recursive: true } );
159
-
160
- const images = [
161
- { name: 'mariadb:lts' },
162
- { name: 'automattic/jetpack-wordpress-dev:latest' },
163
- { name: 'phpmyadmin/phpmyadmin:latest', platform: 'linux/amd64' },
164
- { name: 'maildev/maildev', platform: 'linux/amd64' },
165
- { name: 'atmoz/sftp', platform: 'linux/amd64' },
166
- ];
157
+ const images = [
158
+ { name: 'mariadb:lts' },
159
+ { name: 'automattic/jetpack-wordpress-dev:latest' },
160
+ { name: 'phpmyadmin/phpmyadmin:latest', platform: 'linux/amd64' },
161
+ { name: 'maildev/maildev', platform: 'linux/amd64' },
162
+ { name: 'atmoz/sftp', platform: 'linux/amd64' },
163
+ ];
167
164
 
168
- for ( const image of images ) {
169
- const inspect = spawnSync( 'docker', [ 'image', 'inspect', image.name ], {
170
- stdio: 'ignore',
171
- } );
172
- if ( inspect.status !== 0 ) {
173
- console.log( `Pulling ${ image.name }...` );
174
- const args = [ 'pull', image.name ];
175
- if ( image.platform ) {
176
- args.splice( 1, 0, '--platform', image.platform );
165
+ for ( const image of images ) {
166
+ const inspect = spawnSync( 'docker', [ 'image', 'inspect', image.name ], {
167
+ stdio: 'ignore',
168
+ } );
169
+ if ( inspect.status !== 0 ) {
170
+ console.log( chalk.blue( `Pulling ${ image.name }...` ) );
171
+ const pullArgs = [ 'pull', image.name ];
172
+ if ( image.platform ) {
173
+ pullArgs.splice( 1, 0, '--platform', image.platform );
174
+ }
175
+ const pull = spawnSync( 'docker', pullArgs, { stdio: 'inherit' } );
176
+ if ( pull.status !== 0 ) {
177
+ throw new Error( `Failed to pull ${ image.name }` );
178
+ }
177
179
  }
178
- const pull = spawnSync( 'docker', args, { stdio: 'inherit' } );
179
- if ( pull.status !== 0 ) {
180
- throw new Error( `Failed to pull ${ image.name }` );
180
+ }
181
+
182
+ const configResult = spawnSync(
183
+ resolve( monorepoRoot, 'tools/docker/bin/monorepo' ),
184
+ [ 'pnpm', 'jetpack', 'docker', 'config' ],
185
+ {
186
+ stdio: 'inherit',
187
+ shell: true,
188
+ cwd: monorepoRoot,
181
189
  }
190
+ );
191
+
192
+ if ( configResult.status !== 0 ) {
193
+ throw new Error( 'Failed to generate Docker config' );
182
194
  }
195
+ } else if ( args[ 1 ] === 'clean' ) {
196
+ // After docker-compose down -v, also remove local files
197
+ const projectName = args.includes( '--type=e2e' ) ? 'jetpack_e2e' : 'jetpack_dev';
198
+ const cleanupPaths = [
199
+ resolve( monorepoRoot, 'tools/docker/wordpress/' ),
200
+ resolve( monorepoRoot, 'tools/docker/wordpress-develop/*' ),
201
+ resolve( monorepoRoot, 'tools/docker/logs/', projectName ),
202
+ resolve( monorepoRoot, 'tools/docker/data/', `${ projectName }_mysql` ),
203
+ ];
204
+
205
+ // Function to clean up after docker-compose down
206
+ const cleanupFiles = () => {
207
+ for ( const path of cleanupPaths ) {
208
+ try {
209
+ fs.rmSync( path, { recursive: true, force: true } );
210
+ } catch ( error ) {
211
+ console.warn(
212
+ chalk.yellow( `Warning: Could not remove ${ path }: ${ error.message }` )
213
+ );
214
+ }
215
+ }
216
+ };
217
+
218
+ // Add cleanup to process events to ensure it runs after docker-compose
219
+ process.once( 'beforeExit', cleanupFiles );
220
+
221
+ // Replace 'clean' with 'down -v' in the arguments
222
+ args.splice( 1, 1, 'down', '-v' );
183
223
  }
184
224
 
185
- const configResult = spawnSync(
186
- resolve( monorepoRoot, 'tools/docker/bin/monorepo' ),
187
- [ 'pnpm', 'jetpack', 'docker', 'config' ],
188
- {
189
- stdio: 'inherit',
190
- shell: true,
191
- cwd: monorepoRoot,
225
+ // Get project name (from docker.js)
226
+ const projectName = args.includes( '--type=e2e' ) ? 'jetpack_e2e' : 'jetpack_dev';
227
+
228
+ // Load versions from .github/versions.sh
229
+ const versionsPath = resolve( monorepoRoot, '.github/versions.sh' );
230
+ const versions = fs.readFileSync( versionsPath, 'utf8' );
231
+ const versionVars = {};
232
+ versions.split( '\n' ).forEach( line => {
233
+ const match = line.match( /^([A-Z_]+)=(.+)$/ );
234
+ if ( match ) {
235
+ versionVars[ match[ 1 ] ] = match[ 2 ].replace( /['"]/g, '' );
192
236
  }
193
- );
237
+ } );
194
238
 
195
- if ( configResult.status !== 0 ) {
196
- throw new Error( 'Failed to generate Docker config' );
197
- }
198
- }
239
+ // Build environment variables (from docker.js)
240
+ const envVars = {
241
+ ...process.env,
242
+ // Load from default.env
243
+ ...( fs.existsSync( resolve( monorepoRoot, 'tools/docker/default.env' ) )
244
+ ? dotenv.parse( fs.readFileSync( resolve( monorepoRoot, 'tools/docker/default.env' ) ) )
245
+ : {} ),
246
+ // Load from .env if it exists
247
+ ...( fs.existsSync( resolve( monorepoRoot, 'tools/docker/.env' ) )
248
+ ? dotenv.parse( fs.readFileSync( resolve( monorepoRoot, 'tools/docker/.env' ) ) )
249
+ : {} ),
250
+ HOST_CWD: monorepoRoot,
251
+ PHP_VERSION: versionVars.PHP_VERSION,
252
+ COMPOSER_VERSION: versionVars.COMPOSER_VERSION,
253
+ NODE_VERSION: versionVars.NODE_VERSION,
254
+ PNPM_VERSION: versionVars.PNPM_VERSION,
255
+ COMPOSE_PROJECT_NAME: projectName,
256
+ PORT_WORDPRESS: args.includes( '--type=e2e' ) ? '8889' : '80',
257
+ };
199
258
 
200
- // Get project name (from docker.js)
201
- const projectName = args.includes( '--type=e2e' ) ? 'jetpack_e2e' : 'jetpack_dev';
202
-
203
- // Load versions from .github/versions.sh
204
- const versionsPath = resolve( monorepoRoot, '.github/versions.sh' );
205
- const versions = fs.readFileSync( versionsPath, 'utf8' );
206
- const versionVars = {};
207
- versions.split( '\n' ).forEach( line => {
208
- const match = line.match( /^([A-Z_]+)=(.+)$/ );
209
- if ( match ) {
210
- versionVars[ match[ 1 ] ] = match[ 2 ].replace( /['"]/g, '' );
211
- }
212
- } );
213
-
214
- // Build environment variables (from docker.js)
215
- const envVars = {
216
- ...process.env,
217
- // Load from default.env
218
- ...( fs.existsSync( resolve( monorepoRoot, 'tools/docker/default.env' ) )
219
- ? dotenv.parse( fs.readFileSync( resolve( monorepoRoot, 'tools/docker/default.env' ) ) )
220
- : {} ),
221
- // Load from .env if it exists
222
- ...( fs.existsSync( resolve( monorepoRoot, 'tools/docker/.env' ) )
223
- ? dotenv.parse( fs.readFileSync( resolve( monorepoRoot, 'tools/docker/.env' ) ) )
224
- : {} ),
225
- HOST_CWD: monorepoRoot,
226
- PHP_VERSION: versionVars.PHP_VERSION,
227
- COMPOSER_VERSION: versionVars.COMPOSER_VERSION,
228
- NODE_VERSION: versionVars.NODE_VERSION,
229
- PNPM_VERSION: versionVars.PNPM_VERSION,
230
- COMPOSE_PROJECT_NAME: projectName,
231
- PORT_WORDPRESS: args.includes( '--type=e2e' ) ? '8889' : '80',
232
- };
233
-
234
- // Build the list of compose files to use
235
- const composeFiles = [
236
- '-f',
237
- resolve( monorepoRoot, 'tools/docker/docker-compose.yml' ),
238
- '-f',
239
- resolve( monorepoRoot, 'tools/docker/compose-mappings.built.yml' ),
240
- '-f',
241
- resolve( monorepoRoot, 'tools/docker/compose-extras.built.yml' ),
242
- ];
243
-
244
- const result = spawnSync( 'docker', [ 'compose', ...composeFiles, ...args.slice( 1 ) ], {
245
- stdio: 'inherit',
246
- shell: true,
247
- cwd: resolve( monorepoRoot, 'tools/docker' ),
248
- env: envVars,
249
- } );
259
+ // Build the list of compose files to use
260
+ const composeFiles = [
261
+ '-f',
262
+ resolve( monorepoRoot, 'tools/docker/docker-compose.yml' ),
263
+ '-f',
264
+ resolve( monorepoRoot, 'tools/docker/compose-mappings.built.yml' ),
265
+ '-f',
266
+ resolve( monorepoRoot, 'tools/docker/compose-extras.built.yml' ),
267
+ ];
250
268
 
251
- if ( result.status !== 0 ) {
252
- throw new Error( `Docker command failed with status ${ result.status }` );
269
+ const result = spawnSync( 'docker', [ 'compose', ...composeFiles, ...args.slice( 1 ) ], {
270
+ stdio: 'inherit',
271
+ shell: true,
272
+ cwd: resolve( monorepoRoot, 'tools/docker' ),
273
+ env: envVars,
274
+ } );
275
+
276
+ if ( result.status !== 0 ) {
277
+ throw new Error( `Docker command failed with status ${ result.status }` );
278
+ }
279
+ return;
253
280
  }
254
- return;
255
281
  }
256
282
 
257
283
  // Run the monorepo script with the original arguments
@@ -269,7 +295,6 @@ const main = async () => {
269
295
  throw new Error( `Command failed with status ${ result.status }` );
270
296
  }
271
297
  } catch ( error ) {
272
- // eslint-disable-next-line no-console
273
298
  console.error( chalk.red( error.message ) );
274
299
  process.exitCode = 1;
275
300
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/jetpack-cli",
3
- "version": "0.1.0-beta.2",
3
+ "version": "0.1.0-beta3",
4
4
  "description": "Docker-based CLI for Jetpack development",
5
5
  "bin": {
6
6
  "jp": "bin/jp.js"
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "type": "module",
12
12
  "dependencies": {
13
- "chalk": "^4.1.2",
13
+ "chalk": "^5.4.1",
14
14
  "dotenv": "^16.3.1",
15
15
  "prompts": "^2.4.2"
16
16
  },