@scandipwa/magento-scripts 2.0.0-alpha.0 → 2.0.0-alpha.11

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 (165) hide show
  1. package/exec.js +71 -0
  2. package/index.js +1 -1
  3. package/lib/commands/cli.js +7 -2
  4. package/lib/commands/execute.js +3 -58
  5. package/lib/commands/import-db.js +1 -1
  6. package/lib/commands/logs.js +1 -1
  7. package/lib/commands/start.js +18 -8
  8. package/lib/commands/status.js +9 -1
  9. package/lib/config/config.js +20 -2
  10. package/lib/config/docker.js +79 -85
  11. package/lib/config/index.js +2 -2
  12. package/lib/config/php/versions/php-7.2.js +1 -0
  13. package/lib/config/php/versions/php-7.3.js +1 -0
  14. package/lib/config/php/versions/php-7.4.js +1 -0
  15. package/lib/config/php/versions/php-8.1.js +1 -0
  16. package/lib/config/php-config.js +4 -3
  17. package/lib/config/port-config.js +1 -1
  18. package/lib/config/services/composer/versions/composer-1.js +8 -0
  19. package/lib/config/services/composer/versions/composer-2.js +8 -0
  20. package/lib/config/services/composer/versions/index.js +4 -0
  21. package/lib/config/services/elasticsearch/base-repo.js +3 -0
  22. package/lib/config/services/elasticsearch/default-es-env.js +6 -0
  23. package/lib/config/services/elasticsearch/versions/elasticsearch-6.8.js +19 -0
  24. package/lib/config/services/elasticsearch/versions/index.js +5 -0
  25. package/lib/config/services/nginx/versions/index.js +3 -0
  26. package/lib/config/services/nginx/versions/nginx-1.18.js +11 -0
  27. package/lib/config/{ssl-terminator → services/ssl-terminator}/index.js +3 -0
  28. package/lib/config/templates/magentorc.template +6 -5
  29. package/lib/config/templates/mariadb.template.cnf +191 -0
  30. package/lib/config/templates/php-debug.template.ini +31 -0
  31. package/lib/config/templates/php-fpm.template.conf +1 -2
  32. package/lib/config/templates/php.template.ini +6 -202
  33. package/lib/config/templates/ssl-terminator.template.conf +10 -3
  34. package/lib/config/templates/varnish.template.vcl +20 -13
  35. package/lib/config/varnish/varnish-6-0.js +4 -0
  36. package/lib/config/varnish/varnish-6-6.js +4 -0
  37. package/lib/config/varnish/varnish-7-0.js +4 -0
  38. package/lib/config/versions/magento-2.3.0.js +7 -12
  39. package/lib/config/versions/magento-2.3.1.js +7 -12
  40. package/lib/config/versions/magento-2.3.2-p1.js +7 -12
  41. package/lib/config/versions/magento-2.3.2-p2.js +7 -12
  42. package/lib/config/versions/magento-2.3.2.js +7 -12
  43. package/lib/config/versions/magento-2.3.3-p1.js +7 -12
  44. package/lib/config/versions/magento-2.3.3.js +7 -12
  45. package/lib/config/versions/magento-2.3.4-p1.js +7 -12
  46. package/lib/config/versions/magento-2.3.4-p2.js +7 -12
  47. package/lib/config/versions/magento-2.3.4.js +7 -12
  48. package/lib/config/versions/magento-2.3.5-p1.js +5 -9
  49. package/lib/config/versions/magento-2.3.5-p2.js +5 -9
  50. package/lib/config/versions/magento-2.3.5.js +5 -9
  51. package/lib/config/versions/magento-2.3.6-p1.js +5 -9
  52. package/lib/config/versions/magento-2.3.6.js +5 -9
  53. package/lib/config/versions/magento-2.3.7-p1.js +5 -9
  54. package/lib/config/versions/magento-2.3.7-p2.js +5 -9
  55. package/lib/config/versions/magento-2.3.7-p3.js +5 -9
  56. package/lib/config/versions/magento-2.3.7-p4.js +40 -0
  57. package/lib/config/versions/magento-2.3.7.js +5 -9
  58. package/lib/config/versions/magento-2.4.0-p1.js +5 -9
  59. package/lib/config/versions/magento-2.4.0.js +5 -9
  60. package/lib/config/versions/magento-2.4.1-p1.js +5 -9
  61. package/lib/config/versions/magento-2.4.1.js +5 -9
  62. package/lib/config/versions/magento-2.4.2-p1.js +5 -9
  63. package/lib/config/versions/magento-2.4.2-p2.js +5 -9
  64. package/lib/config/versions/magento-2.4.2.js +5 -9
  65. package/lib/config/versions/magento-2.4.3-p1.js +5 -9
  66. package/lib/config/versions/magento-2.4.3-p2.js +5 -9
  67. package/lib/config/versions/magento-2.4.3-p3.js +42 -0
  68. package/lib/config/versions/magento-2.4.3.js +5 -9
  69. package/lib/config/versions/magento-2.4.4-p1.js +42 -0
  70. package/lib/config/versions/magento-2.4.4.js +5 -9
  71. package/lib/config/versions/magento-2.4.5.js +42 -0
  72. package/lib/tasks/cleanup.js +1 -1
  73. package/lib/tasks/composer/local-auth-json.js +1 -1
  74. package/lib/tasks/database/connect-to-database.js +120 -0
  75. package/lib/tasks/database/create-magento-database.js +21 -0
  76. package/lib/tasks/database/create-magento-user.js +50 -0
  77. package/lib/tasks/database/default-magento-database.js +3 -0
  78. package/lib/tasks/database/default-magento-user.js +7 -0
  79. package/lib/tasks/{mysql → database}/dump-theme-config.js +3 -3
  80. package/lib/tasks/{mysql → database}/fix-db.js +2 -2
  81. package/lib/tasks/{mysql/import-dump-to-mysql.js → database/import-dump-to-database.js} +21 -20
  82. package/lib/tasks/{mysql → database}/import-remote-db/index.js +0 -0
  83. package/lib/tasks/{mysql/import-remote-db/ssh/mysqldump-command.js → database/import-remote-db/ssh/database-dump-command.js} +2 -2
  84. package/lib/tasks/{mysql → database}/import-remote-db/ssh/index.js +0 -0
  85. package/lib/tasks/{mysql → database}/import-remote-db/ssh/readymage.js +4 -4
  86. package/lib/tasks/{mysql → database}/import-remote-db/ssh/regular-server.js +2 -2
  87. package/lib/tasks/{mysql → database}/index.js +2 -2
  88. package/lib/tasks/{mysql → database}/magento-tables.js +0 -0
  89. package/lib/tasks/{mysql → database}/restore-theme-config.js +4 -4
  90. package/lib/tasks/docker/api.d.ts +25 -1
  91. package/lib/tasks/docker/api.js +31 -1
  92. package/lib/tasks/docker/containers/container-api.d.ts +18 -0
  93. package/lib/tasks/docker/containers/container-api.js +76 -17
  94. package/lib/tasks/docker/containers/tasks.js +32 -1
  95. package/lib/tasks/docker/convert-legacy-volumes.js +8 -7
  96. package/lib/tasks/docker/convert-mysql-to-mariadb.js +284 -0
  97. package/lib/tasks/docker/index.js +6 -1
  98. package/lib/tasks/docker/network/network-api.d.ts +1 -1
  99. package/lib/tasks/docker/project-image-builder.js +7 -9
  100. package/lib/tasks/docker/volume/index.js +9 -0
  101. package/lib/tasks/docker/volume/tasks.js +94 -0
  102. package/lib/tasks/docker/volume/volume-api.d.ts +49 -0
  103. package/lib/tasks/docker/volume/volume-api.js +90 -0
  104. package/lib/tasks/execute.js +100 -0
  105. package/lib/tasks/file-system/create-mariadb-config.js +23 -0
  106. package/lib/tasks/file-system/create-nginx-config.js +3 -5
  107. package/lib/tasks/file-system/create-php-config.js +2 -23
  108. package/lib/tasks/file-system/create-php-debug-config.js +45 -0
  109. package/lib/tasks/file-system/create-php-fpm-config.js +2 -4
  110. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-workspace-project-configuration-config.js +1 -1
  111. package/lib/tasks/file-system/create-ssl-terminator-config.js +4 -7
  112. package/lib/tasks/file-system/create-varnish-config.js +4 -7
  113. package/lib/tasks/file-system/index.js +5 -1
  114. package/lib/tasks/import-dump.js +6 -6
  115. package/lib/tasks/link.js +4 -2
  116. package/lib/tasks/magento/enable-magento-composer-plugins.js +85 -30
  117. package/lib/tasks/magento/install-magento-project.js +3 -2
  118. package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +3 -5
  119. package/lib/tasks/magento/setup-magento/create-admin.js +1 -1
  120. package/lib/tasks/magento/setup-magento/delete-admin-users.js +2 -2
  121. package/lib/tasks/magento/setup-magento/delete-customers.js +4 -4
  122. package/lib/tasks/magento/setup-magento/delete-orders.js +4 -4
  123. package/lib/tasks/magento/setup-magento/flush-redis-config.js +3 -6
  124. package/lib/tasks/magento/setup-magento/increase-admin-session-lifetime.js +2 -2
  125. package/lib/tasks/magento/setup-magento/index.js +2 -0
  126. package/lib/tasks/magento/setup-magento/install-magento.js +15 -17
  127. package/lib/tasks/magento/setup-magento/migrate-database.js +5 -11
  128. package/lib/tasks/magento/setup-magento/set-base-url.js +3 -3
  129. package/lib/tasks/magento/setup-magento/set-url-rewrite.js +2 -2
  130. package/lib/tasks/magento/setup-magento/varnish-config.js +8 -13
  131. package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +17 -16
  132. package/lib/tasks/php/php-container.js +7 -3
  133. package/lib/tasks/php/update-env-php.js +7 -6
  134. package/lib/tasks/php/update-env.php +12 -12
  135. package/lib/tasks/requirements/composer-credentials.js +7 -3
  136. package/lib/tasks/requirements/docker/context.js +88 -0
  137. package/lib/tasks/requirements/docker/index.js +110 -19
  138. package/lib/tasks/requirements/docker/install.js +21 -7
  139. package/lib/tasks/requirements/docker/permissions.js +2 -11
  140. package/lib/tasks/requirements/docker/running-status.js +94 -24
  141. package/lib/tasks/requirements/docker/version.js +1 -0
  142. package/lib/tasks/requirements/index.js +0 -2
  143. package/lib/tasks/requirements/php-version.js +4 -2
  144. package/lib/tasks/start.js +32 -31
  145. package/lib/tasks/status/index.js +17 -13
  146. package/lib/tasks/stop.js +2 -0
  147. package/lib/tasks/theme/link-theme.js +2 -2
  148. package/lib/util/config-file-validator.js +29 -13
  149. package/lib/util/database.js +7 -7
  150. package/lib/util/execute-in-container.js +63 -0
  151. package/lib/util/prefix.js +1 -1
  152. package/lib/util/systemctl.js +62 -13
  153. package/package.json +4 -3
  154. package/typings/context.d.ts +12 -5
  155. package/typings/index.d.ts +69 -31
  156. package/lib/tasks/docker/volumes.js +0 -63
  157. package/lib/tasks/execute/index.js +0 -23
  158. package/lib/tasks/mysql/connect-to-mysql.js +0 -127
  159. package/lib/tasks/mysql/create-magento-database.js +0 -18
  160. package/lib/tasks/requirements/dependency/arch.js +0 -50
  161. package/lib/tasks/requirements/dependency/centos.js +0 -36
  162. package/lib/tasks/requirements/dependency/fedora.js +0 -36
  163. package/lib/tasks/requirements/dependency/index.js +0 -33
  164. package/lib/tasks/requirements/dependency/mac.js +0 -124
  165. package/lib/tasks/requirements/dependency/ubuntu.js +0 -83
@@ -7,8 +7,10 @@ const { runContainerImage } = require('../../util/run-container-image');
7
7
  const checkPHPVersion = () => ({
8
8
  title: 'Checking container PHP version',
9
9
  task: async (ctx, task) => {
10
- const { php } = ctx.config.docker.getContainers(ctx.ports);
11
- const phpVersionResponse = await runContainerImage(php.image, 'php --version');
10
+ const phpVersionResponse = await runContainerImage(
11
+ ctx.config.overridenConfiguration.configuration.php.baseImage,
12
+ 'php --version'
13
+ );
12
14
 
13
15
  const phpVersionResponseResult = phpVersionResponse.match(/PHP\s(\d+\.\d+\.\d+)/i);
14
16
 
@@ -12,13 +12,7 @@ const { installMagentoProject, setupMagento } = require('./magento');
12
12
  const { pullImages, stopContainers } = require('./docker/containers');
13
13
  const dockerNetwork = require('./docker/network');
14
14
  const { setPrefix } = require('./prefix');
15
- const {
16
- connectToMySQL
17
- // importDumpToMySQL,
18
- // fixDB,
19
- // restoreThemeConfig,
20
- // dumpThemeConfig
21
- } = require('./mysql');
15
+ const { connectToDatabase } = require('./database');
22
16
  const { buildProjectImage, buildDebugProjectImage } = require('./docker/project-image-builder');
23
17
  const getProjectConfiguration = require('../config/get-project-configuration');
24
18
  const { getSystemConfigTask } = require('../config/system-config');
@@ -32,7 +26,19 @@ const checkForXDGOpen = require('../util/xdg-open-exists');
32
26
  const { getInstanceMetadata, constants: { WEB_LOCATION_TITLE } } = require('../util/instance-metadata');
33
27
  const waitingForVarnish = require('./magento/setup-magento/waiting-for-varnish');
34
28
  const checkPHPVersion = require('./requirements/php-version');
35
- const volumes = require('./docker/volumes');
29
+ const volumes = require('./docker/volume/tasks');
30
+ const convertMySQLDatabaseToMariaDB = require('./docker/convert-mysql-to-mariadb');
31
+ const { cmaGlobalConfig } = require('../config/cma-config');
32
+
33
+ /**
34
+ * @type {() => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
35
+ */
36
+ const resetCmaGlobalConfig = () => ({
37
+ skip: (ctx) => !ctx.resetGlobalConfig,
38
+ task: () => {
39
+ cmaGlobalConfig.clear();
40
+ }
41
+ });
36
42
 
37
43
  /**
38
44
  * @type {() => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
@@ -63,7 +69,8 @@ const retrieveProjectConfiguration = () => ({
63
69
  const stopProject = () => ({
64
70
  title: 'Stopping project',
65
71
  task: (ctx, task) => task.newListr([
66
- stopContainers()
72
+ stopContainers(),
73
+ volumes.removeLocalVolumes()
67
74
  ]),
68
75
  options: {
69
76
  showTimer: false
@@ -97,9 +104,20 @@ const retrieveFreshProjectConfiguration = () => ({
97
104
  const configureProject = () => ({
98
105
  title: 'Configuring project',
99
106
  task: (ctx, task) => task.newListr([
100
- pullImages(),
101
- dockerNetwork.tasks.createNetwork(),
102
- volumes.createVolumes(),
107
+ convertMySQLDatabaseToMariaDB(),
108
+ {
109
+ task: (ctx, task) => task.newListr([
110
+ pullImages(),
111
+ dockerNetwork.tasks.createNetwork(),
112
+ volumes.createVolumes()
113
+ ], { concurrent: true })
114
+ },
115
+ {
116
+ task: (ctx, task) => task.newListr([
117
+ checkPHPVersion(),
118
+ getComposerVersionTask()
119
+ ], { concurrent: true })
120
+ },
103
121
  {
104
122
  task: (ctx, task) => task.newListr([
105
123
  buildProjectImage(),
@@ -108,13 +126,11 @@ const configureProject = () => ({
108
126
  concurrent: true
109
127
  })
110
128
  },
111
- checkPHPVersion(),
112
- getComposerVersionTask(),
113
129
  prepareFileSystem(),
114
130
  installMagentoProject(),
115
131
  enableMagentoComposerPlugins(),
116
132
  startServices(),
117
- connectToMySQL()
133
+ connectToDatabase()
118
134
  ])
119
135
  });
120
136
 
@@ -125,22 +141,6 @@ const finishProjectConfiguration = () => ({
125
141
  title: 'Finishing project configuration',
126
142
  skip: ({ skipSetup }) => skipSetup,
127
143
  task: (ctx, task) => task.newListr([
128
- // {
129
- // skip: (ctx) => !ctx.importDb,
130
- // task: (ctx, task) => {
131
- // task.title = 'Importing database dump';
132
- // return task.newListr([
133
- // dumpThemeConfig(),
134
- // importDumpToMySQL(),
135
- // fixDB(),
136
- // restoreThemeConfig(),
137
- // setupMagento()
138
- // ], {
139
- // concurrent: false,
140
- // exitOnError: true
141
- // });
142
- // }
143
- // },
144
144
  setupThemes(),
145
145
  waitingForVarnish()
146
146
  ], {
@@ -158,6 +158,7 @@ const start = () => ({
158
158
  task: (ctx, task) => {
159
159
  task.title = `Starting project (magento-scripts@${pkg.version})`;
160
160
  return task.newListr([
161
+ resetCmaGlobalConfig(),
161
162
  checkRequirements(),
162
163
  retrieveProjectConfiguration(),
163
164
  stopProject(),
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-len */
1
2
  const path = require('path');
2
3
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
3
4
  const { getProjectCreatedAt, getPrefix } = require('../../util/prefix');
@@ -5,7 +6,6 @@ const { getProjectCreatedAt, getPrefix } = require('../../util/prefix');
5
6
  const { version: packageVersion } = require('../../../package.json');
6
7
  const { getArchSync } = require('../../util/arch');
7
8
  const ConsoleBlock = require('../../util/console-block');
8
- const { getComposerVersion } = require('../composer');
9
9
  const { getInstanceMetadata } = require('../../util/instance-metadata');
10
10
 
11
11
  /**
@@ -22,6 +22,9 @@ const parsePort = (port) => {
22
22
  };
23
23
  };
24
24
 
25
+ /**
26
+ * @param {import('../../../typings/context').ListrContext & { containers: ReturnType<Awaited<ReturnType<import('../../config/docker')>>['getContainers']> }} ctx
27
+ */
25
28
  const prettyStatus = async (ctx) => {
26
29
  const {
27
30
  config: {
@@ -31,10 +34,10 @@ const prettyStatus = async (ctx) => {
31
34
  dockerVersion,
32
35
  platform,
33
36
  platformVersion,
34
- containers
37
+ containers,
38
+ composerVersion
35
39
  } = ctx;
36
40
  const projectCreatedAt = getProjectCreatedAt();
37
- const composerVersion = await getComposerVersion(ctx);
38
41
 
39
42
  const prefix = getPrefix();
40
43
 
@@ -73,8 +76,10 @@ const prettyStatus = async (ctx) => {
73
76
 
74
77
  if (container.status && container.status.Health) {
75
78
  containerStatus = `✓ ${ logger.style.file(container.status.Health.Status) } and ${ logger.style.file('running') }`;
76
- } else {
79
+ } else if (container.status) {
77
80
  containerStatus = logger.style.file(container.status.Status);
81
+ } else {
82
+ containerStatus = '✖ Not running';
78
83
  }
79
84
 
80
85
  block
@@ -83,7 +88,7 @@ const prettyStatus = async (ctx) => {
83
88
  .addLine(`Image: ${logger.style.file(container.image)}`)
84
89
  .addLine(`Network: ${logger.style.link(container.network)}`);
85
90
 
86
- if (container.forwardedPorts && container.forwardedPorts.length > 0) {
91
+ if (!containerStatus.includes('Not running') && container.forwardedPorts && container.forwardedPorts.length > 0) {
87
92
  block.addLine('Port forwarding:');
88
93
  container.forwardedPorts.forEach((port) => {
89
94
  const { host, hostPort, containerPort } = parsePort(port);
@@ -101,6 +106,13 @@ const prettyStatus = async (ctx) => {
101
106
  block.addLine(`${' '.repeat(3)} ${logger.style.misc(envName)}=${logger.style.file(envValue)}`);
102
107
  }
103
108
  }
109
+
110
+ if (container.description) {
111
+ block.addLine('Description:');
112
+ container.description.split('\n').forEach((line) => {
113
+ block.addLine(line);
114
+ });
115
+ }
104
116
  });
105
117
 
106
118
  const instanceMetadata = getInstanceMetadata(ctx);
@@ -121,14 +133,6 @@ const prettyStatus = async (ctx) => {
121
133
  instanceMetadata.admin.forEach(({ title, text }) => {
122
134
  block.addLine(` ${title}: ${text}`);
123
135
  });
124
- // block
125
- // .addEmptyLine()
126
- // .addSeparator('Magento status')
127
- // .addEmptyLine()
128
- // .addLine(`Web location: ${logger.style.link(`${ssl.enabled ? 'https' : 'http'}://${host}${ports.app === 80 ? '' : `:${ports.app}`}/`)}`)
129
- // .addLine(`Magento Admin panel location: ${logger.style.link(`${ssl.enabled ? 'https' : 'http'}://${host}${ports.app === 80 ? '' : `:${ports.app}`}/${magentoConfiguration.adminuri}`)}`)
130
- // .addLine(`Magento Admin panel credentials: ${logger.style.misc(magentoConfiguration.user)} - ${logger.style.misc(magentoConfiguration.password)}`)
131
- // .addEmptyLine();
132
136
 
133
137
  block.log();
134
138
  };
package/lib/tasks/stop.js CHANGED
@@ -2,6 +2,7 @@ const { stopServices } = require('./docker');
2
2
  const getMagentoVersionConfig = require('../config/get-magento-version-config');
3
3
  const getProjectConfiguration = require('../config/get-project-configuration');
4
4
  const checkConfigurationFile = require('../config/check-configuration-file');
5
+ const getDockerVersion = require('./requirements/docker/version');
5
6
 
6
7
  /**
7
8
  * @type {() => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
@@ -9,6 +10,7 @@ const checkConfigurationFile = require('../config/check-configuration-file');
9
10
  const stop = () => ({
10
11
  title: 'Stopping project',
11
12
  task: async (ctx, task) => task.newListr([
13
+ getDockerVersion(),
12
14
  getMagentoVersionConfig(),
13
15
  checkConfigurationFile(),
14
16
  getProjectConfiguration(),
@@ -18,7 +18,7 @@ const linkTheme = () => ({
18
18
  absoluteThemePath,
19
19
  themePath,
20
20
  composerData,
21
- mysqlConnection
21
+ databaseConnection
22
22
  } = ctx;
23
23
  const {
24
24
  magento: { edition: magentoEdition },
@@ -27,7 +27,7 @@ const linkTheme = () => ({
27
27
 
28
28
  const isEnterprise = magentoEdition === 'enterprise';
29
29
  const isPageBuilderInstalled = isEnterprise && semver.satisfies(semver.coerce(magentoVersion), '^2.4');
30
- const [queryResult] = await mysqlConnection.query(`
30
+ const [queryResult] = await databaseConnection.query(`
31
31
  SELECT value AS isPagebuilderEnabled
32
32
  FROM core_config_data
33
33
  WHERE path = 'cms/pagebuilder/enabled'
@@ -46,10 +46,16 @@ const sslSchema = Joi.object({
46
46
  ssl_certificate_key: Joi.string().required()
47
47
  });
48
48
 
49
+ /**
50
+ * @type {Joi.ObjectSchema<import('../../typings/index').PHPExtensions>}
51
+ */
49
52
  const phpExtensionConfiguration = Joi.object()
50
53
  .pattern(
51
54
  Joi.string(),
52
55
  Joi.object({
56
+ alternativeName: Joi.array().items(Joi.string()).optional(),
57
+ command: Joi.func().optional(),
58
+ dependencies: Joi.array().items(Joi.string()).optional(),
53
59
  version: Joi.string().optional()
54
60
  })
55
61
  .unknown()
@@ -59,38 +65,49 @@ const phpExtensionConfiguration = Joi.object()
59
65
  * @type {Joi.ObjectSchema<import('../../typings').PHPConfiguration>}
60
66
  */
61
67
  const phpConfigurationSchema = Joi.object({
62
- version: Joi.string().optional().custom(versionValidator),
68
+ baseImage: Joi.string().optional(),
69
+ debugImage: Joi.string().optional(),
70
+ fpmConfigTemplate: Joi.string().optional(),
63
71
  configTemplate: Joi.string().optional().custom(fileExistsValidator),
64
- extensions: phpExtensionConfiguration.optional(),
65
- disabledExtensions: Joi.array().items(Joi.string())
72
+ debugTemplate: Joi.string().optional().custom(fileExistsValidator),
73
+ extensions: phpExtensionConfiguration.optional()
66
74
  });
67
75
 
68
76
  /**
69
77
  * @type {Joi.ObjectSchema<import('../../typings').NginxConfiguration>}
70
78
  */
71
79
  const nginxConfigurationSchema = Joi.object({
72
- version: Joi.string().optional(),
80
+ image: Joi.string().optional(),
73
81
  configTemplate: Joi.string().optional().custom(fileExistsValidator)
74
82
  });
75
83
 
76
84
  /**
77
- * @type {Joi.ObjectSchema<import('../../typings').NginxConfiguration>}
85
+ * @type {Joi.ObjectSchema<import('../../typings').VarnishConfiguration>}
78
86
  */
79
87
  const varnishConfigurationSchema = Joi.object({
80
88
  enabled: Joi.boolean().optional(),
81
- version: Joi.string().optional(),
89
+ healthCheck: Joi.boolean().optional(),
90
+ image: Joi.string().optional(),
82
91
  configTemplate: Joi.string().optional().custom(fileExistsValidator)
83
92
  });
84
93
 
85
94
  /**
86
- * @type {Joi.ObjectSchema<import('../../typings').ServiceWithVersion>}
95
+ * @type {Joi.ObjectSchema<import('../../typings').ServiceWithImage>}
87
96
  */
88
97
  const serviceConfigurationSchema = Joi.object({
89
- version: Joi.string().optional()
98
+ image: Joi.string().optional()
99
+ });
100
+
101
+ /**
102
+ * @type {Joi.ObjectSchema<import('../../typings').ElasticSearchConfiguration>}
103
+ */
104
+ const elasticsearchConfigurationSchema = Joi.object({
105
+ image: Joi.string().optional(),
106
+ env: Joi.object().optional()
90
107
  });
91
108
 
92
109
  /**
93
- * @type {Joi.ObjectSchema<import('../../typings').CMAConfiguration['configuration']['composer']>}
110
+ * @type {Joi.ObjectSchema<import('../../typings').ComposerConfiguration>}
94
111
  */
95
112
  const composerConfigurationSchema = Joi.object({
96
113
  version: Joi.string().optional().custom((value) => {
@@ -108,8 +125,8 @@ const composerConfigurationSchema = Joi.object({
108
125
  const configurationSchema = Joi.object({
109
126
  php: phpConfigurationSchema.optional(),
110
127
  nginx: nginxConfigurationSchema.optional(),
111
- mysql: serviceConfigurationSchema.optional(),
112
- elasticsearch: serviceConfigurationSchema.optional(),
128
+ mariadb: serviceConfigurationSchema.optional(),
129
+ elasticsearch: elasticsearchConfigurationSchema.optional(),
113
130
  redis: serviceConfigurationSchema.optional(),
114
131
  composer: composerConfigurationSchema.optional(),
115
132
  varnish: varnishConfigurationSchema.optional(),
@@ -124,8 +141,7 @@ const configFileSchema = Joi.object({
124
141
  host: Joi.string().optional(),
125
142
  ssl: sslSchema.optional(),
126
143
  prefix: Joi.bool().optional(),
127
- configuration: configurationSchema.required(),
128
- useNonOverlappingPorts: Joi.bool().forbidden()
144
+ configuration: configurationSchema.required()
129
145
  });
130
146
 
131
147
  /**
@@ -4,8 +4,8 @@
4
4
  * @param {{path: string, value: string}[]} values
5
5
  * @param {import('../../typings/context').ListrContext} param1
6
6
  */
7
- const updateTableValues = async (table, values, { mysqlConnection, task }) => {
8
- const [rows] = await mysqlConnection.query(`
7
+ const updateTableValues = async (table, values, { databaseConnection, task }) => {
8
+ const [rows] = await databaseConnection.query(`
9
9
  SELECT * FROM ${table}
10
10
  WHERE ${values.map((p) => `path = '${p.path}'`).join(' OR ')};
11
11
  `);
@@ -13,7 +13,7 @@ const updateTableValues = async (table, values, { mysqlConnection, task }) => {
13
13
  if (rows.filter(Boolean).length !== values.length) {
14
14
  const lostConfigs = values.filter((p) => !rows.some((row) => row.path === p.path));
15
15
  for (const config of lostConfigs) {
16
- await mysqlConnection.query(`
16
+ await databaseConnection.query(`
17
17
  INSERT INTO ${table}
18
18
  (scope, path, value)
19
19
  VALUES ('default', ?, ?);
@@ -22,7 +22,7 @@ const updateTableValues = async (table, values, { mysqlConnection, task }) => {
22
22
 
23
23
  const configsToUpdate = values.filter((p) => rows.some((row) => row.path === p.path));
24
24
  for (const config of configsToUpdate) {
25
- await mysqlConnection.query(`
25
+ await databaseConnection.query(`
26
26
  UPDATE ${table}
27
27
  SET value = ?
28
28
  WHERE path = ?;
@@ -50,7 +50,7 @@ const updateTableValues = async (table, values, { mysqlConnection, task }) => {
50
50
  });
51
51
 
52
52
  for (const config of configsToUpdate) {
53
- await mysqlConnection.query(`
53
+ await databaseConnection.query(`
54
54
  UPDATE ${table}
55
55
  SET value = ?
56
56
  WHERE path = ?;
@@ -63,11 +63,11 @@ const updateTableValues = async (table, values, { mysqlConnection, task }) => {
63
63
  * @param {String} tableName
64
64
  * @param {import('../../typings/context').ListrContext} param2
65
65
  */
66
- const isTableExists = async (database, tableName, { mysqlConnection }) => {
66
+ const isTableExists = async (database, tableName, { databaseConnection }) => {
67
67
  /**
68
68
  * @type {{ tableCount: number }[][]}
69
69
  */
70
- const [[{ tableCount }]] = await mysqlConnection.query(`
70
+ const [[{ tableCount }]] = await databaseConnection.query(`
71
71
  SELECT count(*) as tableCount
72
72
  FROM information_schema.TABLES
73
73
  WHERE (TABLE_SCHEMA = ?) AND (TABLE_NAME = ?);
@@ -0,0 +1,63 @@
1
+ const os = require('os');
2
+ const { spawn } = require('child_process');
3
+ const { runCommand } = require('../tasks/docker/containers/container-api');
4
+
5
+ /**
6
+ * @param {{ containerName: string, commands: string[], isDockerDesktop: boolean }} param0
7
+ */
8
+ const executeInContainer = ({ containerName, commands, isDockerDesktop }) => {
9
+ if (!process.stdin.isTTY) {
10
+ process.stderr.write('This app works only in TTY mode');
11
+ process.exit(1);
12
+ }
13
+
14
+ const userArg = ((os.platform() === 'linux' && isDockerDesktop) || !isDockerDesktop) && `--user=${os.userInfo().uid}:${os.userInfo().gid}`;
15
+
16
+ spawn('docker', [
17
+ 'exec',
18
+ '-it',
19
+ userArg,
20
+ containerName
21
+ ]
22
+ .filter(Boolean)
23
+ .concat(...commands.map((command) => command.split(' ')).flat()),
24
+ {
25
+ stdio: [0, 1, 2]
26
+ });
27
+
28
+ return new Promise((_resolve) => {
29
+ // never resolve
30
+ });
31
+ };
32
+
33
+ /**
34
+ * @param {import('../tasks/docker/containers/container-api').ContainerRunOptions} options
35
+ * @param {string[]} commands
36
+ */
37
+ const runInContainer = (options, commands) => {
38
+ if (!process.stdin.isTTY) {
39
+ process.stderr.write('This app works only in TTY mode');
40
+ process.exit(1);
41
+ }
42
+
43
+ const runArgs = runCommand({
44
+ ...options,
45
+ tty: true,
46
+ detach: false,
47
+ rm: true,
48
+ command: commands.map((command) => command.split(' ')).flat().join(' ')
49
+ });
50
+
51
+ const args = runArgs.slice(1).map((command) => command.split(' ')).flat();
52
+
53
+ spawn('docker', args, { stdio: [0, 1, 2] });
54
+
55
+ return new Promise((_resolve) => {
56
+ // never resolve
57
+ });
58
+ };
59
+
60
+ module.exports = {
61
+ executeInContainer,
62
+ runInContainer
63
+ };
@@ -22,7 +22,7 @@ const getPrefix = (fName = folderName) => {
22
22
  }
23
23
 
24
24
  if (projectInGlobalConfig && projectInGlobalConfig.prefix) {
25
- return `${fName}.${projectInGlobalConfig.prefix}`;
25
+ return `${fName}-${projectInGlobalConfig.prefix}`;
26
26
  }
27
27
 
28
28
  return fName;
@@ -3,10 +3,10 @@ const { execAsyncSpawn } = require('./exec-async-command');
3
3
  /**
4
4
  * @param {String} cmd
5
5
  * @param {String} serviceName
6
- * @param {{ now: boolean }} options
6
+ * @param {{ now: boolean, user: boolean }} options
7
7
  */
8
8
  const run = (cmd, serviceName, options = {}) => execAsyncSpawn(
9
- `systemctl ${ cmd }${ serviceName ? ` ${ serviceName }` : '' }${ options.now ? ' --now' : ''}`,
9
+ `systemctl ${ options.user ? '--user ' : '' }${ cmd }${ serviceName ? ` ${ serviceName }` : '' }${ options.now ? ' --now' : ''}`,
10
10
  {
11
11
  withCode: true
12
12
  }
@@ -14,29 +14,78 @@ const run = (cmd, serviceName, options = {}) => execAsyncSpawn(
14
14
 
15
15
  const daemonReload = () => run('daemon-reload');
16
16
 
17
- const systemctlControl = (serviceName) => ({
18
- disable: () => run('disable', serviceName),
19
- enable: () => run('enable', serviceName),
20
- enableAndStart: () => run('enable', serviceName, { now: true }),
21
- restart: () => run('restart', serviceName),
22
- start: () => run('start', serviceName),
23
- stop: () => run('stop', serviceName),
24
- isEnabled: async () => {
17
+ /**
18
+ * @param {String} serviceName
19
+ * @param {{ now: boolean, user: boolean }} defaultOptions
20
+ */
21
+ const systemctlControl = (serviceName, defaultOptions = {}) => ({
22
+ /**
23
+ * @param {{ now: boolean, user: boolean }} options
24
+ */
25
+ disable: (options = {}) => run('disable', serviceName, { ...defaultOptions, ...options }),
26
+ /**
27
+ * @param {{ now: boolean, user: boolean }} options
28
+ */
29
+ enable: (options = {}) => run('enable', serviceName, { ...defaultOptions, ...options }),
30
+ /**
31
+ * @param {{ now: boolean, user: boolean }} options
32
+ */
33
+ enableAndStart: (options = {}) => run('enable', serviceName, { now: true, ...defaultOptions, ...options }),
34
+ /**
35
+ * @param {{ now: boolean, user: boolean }} options
36
+ */
37
+ restart: (options = {}) => run('restart', serviceName, { ...defaultOptions, ...options }),
38
+ /**
39
+ * @param {{ now: boolean, user: boolean }} options
40
+ */
41
+ start: (options = {}) => run('start', serviceName, { ...defaultOptions, ...options }),
42
+ /**
43
+ * @param {{ now: boolean, user: boolean }} options
44
+ */
45
+ stop: (options = {}) => run('stop', serviceName, { ...defaultOptions, ...options }),
46
+ /**
47
+ * @param {{ now: boolean, user: boolean }} options
48
+ */
49
+ isEnabled: async (options = {}) => {
25
50
  try {
26
- const { result } = await run('is-enabled', serviceName);
51
+ const { result } = await run('is-enabled', serviceName, { ...defaultOptions, ...options });
27
52
  return result.includes('enabled');
28
53
  } catch (e) {
29
54
  return false;
30
55
  }
31
56
  },
32
- isRunning: async () => {
57
+ /**
58
+ * @param {{ now: boolean, user: boolean }} options
59
+ */
60
+ isRunning: async (options = {}) => {
33
61
  try {
34
- const { result } = await run('status', serviceName);
62
+ const { result } = await run('status', serviceName, { ...defaultOptions, ...options });
35
63
 
36
64
  return result.includes('active (running)');
37
65
  } catch (e) {
38
66
  return false;
39
67
  }
68
+ },
69
+ /**
70
+ * @param {{ user: boolean }} options
71
+ */
72
+ exists: async (options = {}) => {
73
+ const optionsToUse = { ...defaultOptions, ...options };
74
+ try {
75
+ // eslint-disable-next-line max-len, no-useless-escape
76
+ const command = `if [[ $(systemctl ${ optionsToUse.user ? '--user ' : ''}list-units --all -t service --full --no-legend "${ serviceName }.service" | sed 's/^\\s*//g' | cut -f1 -d' ') == ${ serviceName }.service ]]; then
77
+ echo "1"
78
+ else
79
+ echo "0"
80
+ fi`;
81
+ const result = await execAsyncSpawn(
82
+ command
83
+ );
84
+
85
+ return result === '1';
86
+ } catch (e) {
87
+ return false;
88
+ }
40
89
  }
41
90
  });
42
91
 
package/package.json CHANGED
@@ -3,12 +3,13 @@
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.0.0-alpha.0",
6
+ "version": "2.0.0-alpha.11",
7
7
  "main": "./index.js",
8
8
  "types": "./typings/index.d.ts",
9
9
  "license": "OSL-3.0",
10
10
  "bin": {
11
- "magento-scripts": "./index.js"
11
+ "magento-scripts": "./index.js",
12
+ "magento-scripts-exec": "./exec.js"
12
13
  },
13
14
  "engines": {
14
15
  "node": ">=12"
@@ -53,5 +54,5 @@
53
54
  "mysql",
54
55
  "scandipwa"
55
56
  ],
56
- "gitHead": "a63454a3015891e4ebe5a7e84a0c88989a1d0edc"
57
+ "gitHead": "b66794d8d364bb6f5a56a826e74a30c3914c17f9"
57
58
  }
@@ -1,17 +1,19 @@
1
1
  import mysql2 from 'mysql2';
2
2
 
3
+ import { DockerVersionResult } from '../lib/tasks/docker/api';
3
4
  import { CMAConfiguration, PHPExtensions } from './index';
4
5
  import { PHPStormConfig } from './phpstorm';
5
6
 
6
7
  export interface ListrContext {
7
8
  magentoVersion: string
8
9
  composerVersion: string
10
+ phpVersion: string
9
11
  port?: number
10
12
  ports?: {
11
13
  app: number
12
14
  fpm: number
13
15
  xdebug: number
14
- mysql: number
16
+ mariadb: number
15
17
  redis: number
16
18
  elasticsearch: number
17
19
  varnish: number
@@ -45,15 +47,15 @@ export interface ListrContext {
45
47
  network: {
46
48
  name: string
47
49
  }
48
- volumes: Record<'mysql' | 'redis' | 'elasticsearch' | 'nginx' | 'appPub' | 'appSetup', {
50
+ volumes: Record<'mariadb' | 'redis' | 'elasticsearch' | 'nginx' | 'appPub' | 'appSetup', {
49
51
  name: string
50
- opts?: {
52
+ opt?: {
51
53
  type: string
52
54
  device: string
53
55
  o: string
54
56
  }
55
57
  }>
56
- getContainers(): Record<'php' | 'sslTerminator' | 'nginx' | 'redis' | 'mysql' | 'elasticsearch' | 'varnish', {
58
+ getContainers(): Record<'php' | 'sslTerminator' | 'nginx' | 'redis' | 'mariadb' | 'elasticsearch' | 'varnish', {
57
59
  _: string
58
60
  ports: string[]
59
61
  healthCheck: {
@@ -67,6 +69,7 @@ export interface ListrContext {
67
69
  network: string
68
70
  image: string
69
71
  debugImage?: string
72
+ remoteImages?: string[]
70
73
  name: string
71
74
  command: string
72
75
  connectCommand: string[]
@@ -88,6 +91,10 @@ export interface ListrContext {
88
91
  analytics: boolean
89
92
  useNonOverlappingPorts: boolean
90
93
  }
91
- mysqlConnection: mysql2.Connection
94
+ databaseConnection: mysql2.Connection
92
95
  isSetupUpgradeNeeded?: boolean
96
+ isDockerDesktop?: boolean
97
+ dockerServerData?: DockerVersionResult['Server']
98
+ dockerClientData?: DockerVersionResult['Client']
99
+ dockerVersion?: DockerVersionResult['Server']['Version']
93
100
  }