@scandipwa/magento-scripts 2.4.11 → 2.4.12

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.
@@ -8,6 +8,16 @@ const { getArchSync } = require('../../util/arch')
8
8
  const ConsoleBlock = require('../../util/console-block')
9
9
  const { getInstanceMetadata } = require('../../util/instance-metadata')
10
10
 
11
+ // eslint-disable-next-line no-control-regex
12
+ const consoleStyleReplacer = /[]\[\S+?m/g
13
+
14
+ /**
15
+ * chalk already drops styling when stdout is not a TTY, but strip defensively
16
+ * so the plain output stays clean even under FORCE_COLOR.
17
+ * @param {string} str
18
+ */
19
+ const stripStyle = (str) => String(str).replace(consoleStyleReplacer, '')
20
+
11
21
  /**
12
22
  * @param {any} str
13
23
  * @returns {str is string}
@@ -230,9 +240,10 @@ const prettyStatus = async (ctx) => {
230
240
 
231
241
  Object.values(volumes)
232
242
  .map((volume) => {
233
- volume.volumeData = systemDFData.Volumes.find(
234
- (v) => v.Name === volume.name
235
- )
243
+ volume.volumeData =
244
+ systemDFData &&
245
+ systemDFData.Volumes &&
246
+ systemDFData.Volumes.find((v) => v.Name === volume.name)
236
247
 
237
248
  return volume
238
249
  })
@@ -273,4 +284,174 @@ const prettyStatus = async (ctx) => {
273
284
  block.log()
274
285
  }
275
286
 
276
- module.exports = { prettyStatus }
287
+ /**
288
+ * Plain-text status summary for non-interactive environments (AI agents, CI,
289
+ * pipes). No box drawing or ANSI styling — just the facts an agent needs to
290
+ * act, plus the commands to run next.
291
+ * @param {import('../../../typings/context').ListrContext & { containers: ReturnType<Awaited<ReturnType<import('../../config/docker')>>['getContainers']> }} ctx
292
+ */
293
+ const simpleStatus = (ctx) => {
294
+ const {
295
+ config: { baseConfig },
296
+ magentoVersion,
297
+ composerVersion,
298
+ dockerVersion,
299
+ containers,
300
+ systemDFData,
301
+ verbose
302
+ } = ctx
303
+
304
+ const lines = []
305
+
306
+ lines.push(
307
+ `magento-scripts ${packageVersion} — status (non-interactive)`,
308
+ '',
309
+ `Project: ${baseConfig.prefix}`,
310
+ `Location: ${process.cwd()}`,
311
+ `Magento: ${magentoVersion || 'unknown'}`,
312
+ `PHP: ${ctx.phpVersion || 'unknown'}`,
313
+ `Composer: ${composerVersion || 'unknown'}`,
314
+ `Docker: ${dockerVersion || 'unknown'}`,
315
+ `Platform: ${ctx.platform} (${getArchSync()})`
316
+ )
317
+
318
+ lines.push(
319
+ `Platform version: ${ctx.platformVersion || 'unknown'}`,
320
+ `CGroup version: ${ctx.cgroupVersion || 'unknown'}`
321
+ )
322
+
323
+ const projectCreatedAt = getProjectCreatedAt()
324
+ if (projectCreatedAt) {
325
+ lines.push(
326
+ `Project created: ${projectCreatedAt.toDateString()} ${projectCreatedAt.toTimeString()}`
327
+ )
328
+ }
329
+
330
+ lines.push('', 'Containers:')
331
+
332
+ let anyRunning = false
333
+
334
+ Object.values(containers).forEach((container) => {
335
+ const state = container.status && container.status.State
336
+ let status
337
+
338
+ if (state && state.Health && state.Status === 'running') {
339
+ status = `running (${state.Health.Status})`
340
+ anyRunning = true
341
+ } else if (state && state.Status && state.Status !== 'exited') {
342
+ status = state.Status
343
+ if (state.Status === 'running') {
344
+ anyRunning = true
345
+ }
346
+ } else {
347
+ status = 'not running'
348
+ }
349
+
350
+ lines.push(` ${container._ || container.name}: ${status}`)
351
+
352
+ lines.push(` Name: ${container.name}`)
353
+
354
+ const image =
355
+ container.status &&
356
+ container.status.Config &&
357
+ container.status.Config.Image
358
+ ? container.status.Config.Image
359
+ : container.image
360
+ lines.push(` Image: ${image}`, ` Network: ${container.network}`)
361
+
362
+ if (
363
+ status !== 'not running' &&
364
+ container.forwardedPorts &&
365
+ container.forwardedPorts.length > 0
366
+ ) {
367
+ lines.push(' Port forwarding:')
368
+ container.forwardedPorts.forEach((port) => {
369
+ const { host, hostPort, containerPort } = parsePort(port)
370
+ if (container.network !== 'host') {
371
+ lines.push(
372
+ ` ${host}:${hostPort} -> ${containerPort} (host -> container)`
373
+ )
374
+ } else {
375
+ lines.push(
376
+ ` Running on host network - ${host}:${hostPort}`
377
+ )
378
+ }
379
+ })
380
+ }
381
+
382
+ if (container.env && Object.keys(container.env).length > 0) {
383
+ lines.push(' Environment variables:')
384
+ for (const [envName, envValue] of Object.entries(container.env)) {
385
+ lines.push(` ${envName}=${envValue}`)
386
+ }
387
+ }
388
+
389
+ if (container.description) {
390
+ lines.push(' Description:')
391
+ container.description.split('\n').forEach((line) => {
392
+ lines.push(` ${stripStyle(line)}`)
393
+ })
394
+ }
395
+ })
396
+
397
+ lines.push('', 'Volumes:')
398
+
399
+ const { volumes } = ctx.config.docker
400
+
401
+ Object.values(volumes).forEach((volume) => {
402
+ const volumeData =
403
+ systemDFData &&
404
+ systemDFData.Volumes &&
405
+ systemDFData.Volumes.find((v) => v.Name === volume.name)
406
+
407
+ lines.push(` ${volume.name}`)
408
+
409
+ if (volumeData) {
410
+ lines.push(` Size: ${volumeData.Size}`)
411
+ }
412
+
413
+ if (ctx.isDockerDesktop && volume.opt && volume.opt.device) {
414
+ lines.push(
415
+ ` Mountpoint: ${volume.opt.device.replace(
416
+ process.cwd(),
417
+ '<project location>'
418
+ )}`
419
+ )
420
+ }
421
+ })
422
+
423
+ if (!verbose) {
424
+ lines.push(' (volume sizes omitted — pass --verbose to include them)')
425
+ }
426
+
427
+ const instanceMetadata = getInstanceMetadata(ctx)
428
+
429
+ lines.push('', 'Frontend:')
430
+ instanceMetadata.frontend.forEach(({ title, text }) => {
431
+ lines.push(` ${stripStyle(title)}: ${stripStyle(text)}`)
432
+ })
433
+
434
+ lines.push('', 'Admin:')
435
+ instanceMetadata.admin.forEach(({ title, text }) => {
436
+ lines.push(` ${stripStyle(title)}: ${stripStyle(text)}`)
437
+ })
438
+
439
+ lines.push('', 'MailDev:')
440
+ instanceMetadata.maildev.forEach(({ title, text }) => {
441
+ lines.push(` ${stripStyle(title)}: ${stripStyle(text)}`)
442
+ })
443
+
444
+ lines.push('')
445
+ if (!anyRunning) {
446
+ lines.push(
447
+ 'Environment is not running. Start it with: magento-scripts start'
448
+ )
449
+ }
450
+ lines.push(
451
+ 'Run Magento CLI: magento-scripts exec php bin/magento <command>'
452
+ )
453
+
454
+ logger.log(lines.join('\n'))
455
+ }
456
+
457
+ module.exports = { prettyStatus, simpleStatus }
@@ -30,18 +30,16 @@ const joinCommandArgs = (...args) =>
30
30
  * @param {{ containerName: string, commands: string[], user?: string, env?: Record<string, string> }} param0
31
31
  */
32
32
  const executeInContainer = ({ containerName, commands, user, env }) => {
33
- if (!process.stdin.isTTY) {
34
- process.stderr.write('This app works only in TTY mode')
35
- process.exit(1)
36
- }
37
33
  const [commandBin, ...commandsArgs] = commands
38
34
 
35
+ const isTTY = process.stdin.isTTY
36
+
39
37
  const execArgs = execCommand({
40
38
  container: containerName,
41
39
  command: commandBin,
42
40
  user,
43
- tty: true,
44
- interactive: true,
41
+ tty: isTTY,
42
+ interactive: isTTY,
45
43
  env: env || {}
46
44
  })
47
45
  const [command, ...args] = execArgs
@@ -91,18 +89,14 @@ const executeInContainerNonInteractive = async ({
91
89
  * @param {string[]} commands
92
90
  */
93
91
  const runInContainer = async (options, commands) => {
94
- if (!process.stdin.isTTY) {
95
- process.stderr.write('This app works only in TTY mode')
96
- process.exit(1)
97
- }
98
-
92
+ const isTTY = process.stdin.isTTY
99
93
  const [commandBin, ...commandsArgs] = commands
100
94
 
101
95
  const runResult = await run(
102
96
  {
103
97
  ...options,
104
98
  command: joinCommandArgs(commandBin, ...commandsArgs),
105
- tty: true,
99
+ tty: isTTY,
106
100
  detach: false,
107
101
  rm: true
108
102
  },
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Scripts and configuration used by CMA.",
4
4
  "homepage": "https://docs.create-magento-app.com/",
5
5
  "repository": "github:scandipwa/create-magento-app",
6
- "version": "2.4.11",
6
+ "version": "2.4.12",
7
7
  "main": "./index.js",
8
8
  "types": "./typings/index.d.ts",
9
9
  "license": "OSL-3.0",
@@ -59,5 +59,5 @@
59
59
  "@types/node": "^20.14.11",
60
60
  "@types/yargs": "^17.0.32"
61
61
  },
62
- "gitHead": "64c177af194cf32de4d8ae08116f016d30ec7f01"
62
+ "gitHead": "6989fd1f8233b1586050ea39a89c1db29334f6cb"
63
63
  }
@@ -8,6 +8,7 @@ import { PHPStormConfig } from './phpstorm'
8
8
 
9
9
  export interface ListrContext {
10
10
  noOpen?: boolean
11
+ open?: boolean
11
12
  skipSetup?: boolean
12
13
  resetGlobalConfig?: boolean
13
14
  withCustomersData?: boolean
@@ -159,4 +160,14 @@ export interface ListrContext {
159
160
  dockerClientData?: DockerVersionResult['Client']
160
161
  dockerVersion?: DockerVersionResult['Server']['Version']
161
162
  dockerMemoryLimit: number
163
+ silent?: boolean
164
+ nonInteractive?: boolean
165
+ deleteDb?: 'always' | 'never' | 'ask'
166
+ dbUser?: 'root' | 'magento'
167
+ fixCollation?: 'auto' | 'never' | 'ask'
168
+ installMagentoEmptyDb?: 'yes' | 'no' | 'ask'
169
+ privateKey?: string
170
+ passphrase?: string
171
+ makeRemoteDumps?: boolean
172
+ remoteDumpCommand?: string
162
173
  }