@scandipwa/magento-scripts 2.0.0-alpha.1 → 2.0.0-alpha.10

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 (28) hide show
  1. package/exec.js +71 -0
  2. package/index.js +1 -1
  3. package/lib/commands/execute.js +2 -57
  4. package/lib/config/docker.js +8 -5
  5. package/lib/config/services/elasticsearch/default-es-env.js +6 -0
  6. package/lib/config/services/elasticsearch/versions/elasticsearch-6.8.js +2 -6
  7. package/lib/config/templates/magentorc.template +5 -5
  8. package/lib/config/templates/ssl-terminator.template.conf +8 -3
  9. package/lib/config/versions/magento-2.3.7-p4.js +44 -0
  10. package/lib/config/versions/magento-2.4.3-p3.js +46 -0
  11. package/lib/config/versions/magento-2.4.4-p1.js +46 -0
  12. package/lib/config/versions/magento-2.4.5.js +46 -0
  13. package/lib/tasks/docker/containers/container-api.d.ts +4 -0
  14. package/lib/tasks/docker/containers/container-api.js +26 -16
  15. package/lib/tasks/docker/project-image-builder.js +2 -2
  16. package/lib/tasks/execute.js +97 -0
  17. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-workspace-project-configuration-config.js +1 -1
  18. package/lib/tasks/magento/enable-magento-composer-plugins.js +85 -30
  19. package/lib/tasks/magento/install-magento-project.js +3 -2
  20. package/lib/tasks/magento/setup-magento/set-base-url.js +1 -1
  21. package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +3 -1
  22. package/lib/tasks/php/php-container.js +6 -2
  23. package/lib/tasks/requirements/docker/index.js +3 -1
  24. package/lib/tasks/start.js +1 -1
  25. package/lib/util/execute-in-container.js +63 -0
  26. package/package.json +4 -3
  27. package/lib/tasks/execute/index.js +0 -26
  28. package/yarn-error.log +0 -9660
@@ -0,0 +1,97 @@
1
+ const { Listr } = require('listr2');
2
+ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
3
+ const { checkRequirements } = require('./requirements');
4
+ const getMagentoVersionConfig = require('../config/get-magento-version-config');
5
+ const checkConfigurationFile = require('../config/check-configuration-file');
6
+ const getProjectConfiguration = require('../config/get-project-configuration');
7
+ const { getCachedPorts } = require('../config/get-port-config');
8
+ const { executeInContainer, runInContainer } = require('../util/execute-in-container');
9
+ const { containerApi } = require('./docker/containers');
10
+ const KnownError = require('../errors/known-error');
11
+
12
+ /**
13
+ *
14
+ * @param {{ containername: string, commands?: string[] }} argv
15
+ * @returns
16
+ */
17
+ const executeTask = async (argv) => {
18
+ const tasks = new Listr([
19
+ checkRequirements(),
20
+ getMagentoVersionConfig(),
21
+ checkConfigurationFile(),
22
+ getProjectConfiguration(),
23
+ getCachedPorts()
24
+ ], {
25
+ concurrent: false,
26
+ exitOnError: true,
27
+ ctx: { throwMagentoVersionMissing: true },
28
+ rendererOptions: { collapse: false, clearOutput: true }
29
+ });
30
+
31
+ let ctx;
32
+ try {
33
+ ctx = await tasks.run();
34
+ } catch (e) {
35
+ logger.error(e.message || e);
36
+ process.exit(1);
37
+ }
38
+ const containers = ctx.config.docker.getContainers(ctx.ports);
39
+ const services = Object.keys(containers);
40
+
41
+ if (services.includes(argv.containername) || services.some((service) => service.includes(argv.containername))) {
42
+ /**
43
+ * @type {import('./docker/containers/container-api').ContainerRunOptions}
44
+ */
45
+ const container = containers[argv.containername]
46
+ ? containers[argv.containername]
47
+ : Object.entries(containers).find(([key]) => key.includes(argv.containername))[1];
48
+
49
+ if (argv.commands.length === 0) {
50
+ // if we have default connect command then use it
51
+ if (container.connectCommand) {
52
+ // eslint-disable-next-line no-param-reassign
53
+ argv.commands = container.connectCommand;
54
+ } else {
55
+ // otherwise fall back to bash (if it exists inside container)
56
+ argv.commands.push('bash');
57
+ }
58
+ }
59
+
60
+ const containerList = await containerApi.ls({
61
+ formatToJSON: true,
62
+ all: true,
63
+ filter: `name=${container.name}`
64
+ });
65
+
66
+ if (containerList.length > 0) {
67
+ logger.logN(`Executing container ${logger.style.misc(container._)} (command: ${logger.style.command(argv.commands.join(' '))})`);
68
+ const result = await executeInContainer({
69
+ containerName: container.name,
70
+ commands: argv.commands
71
+ });
72
+
73
+ return result;
74
+ }
75
+
76
+ if (container.name.endsWith('php')) {
77
+ logger.logN(`Starting container ${logger.style.misc(container._)} with command: ${logger.style.command(argv.commands.join(' '))}`);
78
+ const result = await runInContainer(
79
+ {
80
+ ...container,
81
+ name: `${container.name}_exec-${Date.now()}`
82
+ },
83
+ argv.commands
84
+ );
85
+
86
+ return result;
87
+ }
88
+
89
+ throw new KnownError(`Container ${container.name} is not running!`);
90
+ }
91
+
92
+ logger.error(`No container found "${argv.containername}"`);
93
+ };
94
+
95
+ module.exports = {
96
+ executeTask
97
+ };
@@ -31,7 +31,7 @@ const setupPHPWorkspaceProjectConfiguration = async (workspaceConfigs, ctx) => {
31
31
  hasChanges = true;
32
32
  workspaceConfigs.push({
33
33
  [nameKey]: PHP_WORKSPACE_PROJECT_CONFIGURATION_COMPONENT_NAME,
34
- [currentInterpreterImage]: currentInterpreterImage,
34
+ [interpreterNameKey]: currentInterpreterImage,
35
35
  include_path: []
36
36
  });
37
37
  }
@@ -4,7 +4,6 @@ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
4
4
  const semver = require('semver');
5
5
  const pathExists = require('../../util/path-exists');
6
6
  const getJsonfileData = require('../../util/get-jsonfile-data');
7
- const KnownError = require('../../errors/known-error');
8
7
 
9
8
  const vendorPath = path.join(process.cwd(), 'vendor');
10
9
  const composerJsonPath = path.join(process.cwd(), 'composer.json');
@@ -86,29 +85,80 @@ const enableMagentoComposerPlugins = () => ({
86
85
  } = composerJsonData;
87
86
  const allowPluginsKeys = Object.keys(allowPlugins);
88
87
 
88
+ const missingPluginsFromAllowPlugins = composerPlugins.filter((plugin) => {
89
+ const [pluginVendor, pluginName] = plugin.split('/');
90
+ return !allowPluginsKeys.some((allowedPlugin) => {
91
+ const [allowedPluginVendor, allowedPluginName] = allowedPlugin.split('/');
92
+ if (allowedPluginVendor === pluginVendor) {
93
+ if (allowedPluginName === '*') {
94
+ return true;
95
+ }
96
+
97
+ return allowedPluginName === pluginName;
98
+ }
99
+
100
+ return false;
101
+ });
102
+ });
103
+
89
104
  if (
90
105
  allowPluginsKeys.length === 0
91
- || composerPlugins.some((p) => !allowPluginsKeys.includes(p))
106
+ || missingPluginsFromAllowPlugins.length > 0
92
107
  ) {
93
- const missingPlugins = composerPlugins.filter((p) => !allowPluginsKeys.includes(p));
108
+ const missingVendors = missingPluginsFromAllowPlugins.reduce((acc, val) => {
109
+ const [pluginVendor] = val.split('/');
110
+
111
+ if (acc.length === 0) {
112
+ return [pluginVendor];
113
+ }
114
+
115
+ if (!acc.includes(pluginVendor)) {
116
+ return [...acc, pluginVendor];
117
+ }
118
+
119
+ return acc;
120
+ }, []);
121
+
122
+ const pluginOptions = [
123
+ {
124
+ name: 'all-individual',
125
+ message: 'Enable all individually'
126
+ },
127
+ {
128
+ name: 'manual',
129
+ message: 'Configure manually'
130
+ },
131
+ {
132
+ name: 'skip',
133
+ message: 'Skip this step'
134
+ }
135
+ ];
136
+
137
+ if (missingVendors.length === 1) {
138
+ pluginOptions.unshift({
139
+ name: 'all',
140
+ message: `Enable all (${logger.style.code(`"${missingVendors[0]}/*"`)})`
141
+ });
142
+ }
143
+
94
144
  const answerForEnablingPlugins = await task.prompt({
95
145
  type: 'Select',
96
146
  message: `Composer 2.2 requires manually allowing composer-plugins to run.
97
147
  Magento requires the following plugins to correctly operate:
98
148
 
99
- ${missingPlugins.map((p) => logger.style.code(p)).join('\n')}
149
+ ${missingPluginsFromAllowPlugins.map((p) => logger.style.code(p)).join('\n')}
100
150
 
101
151
  Do you want to enable them all or disable some of them?`,
102
- choices: ['Enable all', 'Configure manually', 'Skip this step']
152
+ choices: pluginOptions
103
153
  });
104
154
 
105
155
  switch (answerForEnablingPlugins.toLowerCase()) {
106
- case 'enable all': {
156
+ case 'all': {
107
157
  composerJsonData.config = {
108
158
  ...(composerJsonData.config || {}),
109
159
  'allow-plugins': {
110
160
  ...allowPlugins,
111
- ...missingPlugins.reduce((acc, val) => ({ ...acc, [val]: true }), {})
161
+ [`${missingVendors[0]}/*`]: true
112
162
  }
113
163
  };
114
164
 
@@ -117,36 +167,41 @@ Do you want to enable them all or disable some of them?`,
117
167
  });
118
168
  break;
119
169
  }
120
- case 'configure manually': {
170
+ case 'all-individual': {
171
+ composerJsonData.config = {
172
+ ...(composerJsonData.config || {}),
173
+ 'allow-plugins': {
174
+ ...allowPlugins,
175
+ ...missingPluginsFromAllowPlugins.reduce((acc, val) => ({ ...acc, [val]: true }), {})
176
+ }
177
+ };
178
+
179
+ await fs.promises.writeFile(composerJsonPath, JSON.stringify(composerJsonData, null, 4), {
180
+ encoding: 'utf-8'
181
+ });
182
+ break;
183
+ }
184
+ case 'manual': {
121
185
  const userEnabledPlugins = await task.prompt({
122
186
  type: 'MultiSelect',
123
187
  message: 'Please pick plugins you want to enable!',
124
- choices: missingPlugins.map((p) => ({ name: p }))
188
+ choices: missingPluginsFromAllowPlugins.map((p) => ({ name: p }))
125
189
  });
126
190
 
127
- const userConfirmation = await task.prompt({
128
- type: 'Confirm',
129
- message: `Please confirm enabling of the following plugins:\n\n${userEnabledPlugins.map((p) => logger.style.code(p)).join('\n')}\n`
130
- });
191
+ const disabledPlugins = composerPlugins.filter((p) => !userEnabledPlugins.includes(p));
131
192
 
132
- if (userConfirmation) {
133
- const disabledPlugins = composerPlugins.filter((p) => !userEnabledPlugins.includes(p));
134
-
135
- composerJsonData.config = {
136
- ...(composerJsonData.config || {}),
137
- 'allow-plugins': {
138
- ...allowPlugins,
139
- ...disabledPlugins.reduce((acc, val) => ({ ...acc, [val]: false }), {}),
140
- ...userEnabledPlugins.reduce((acc, val) => ({ ...acc, [val]: true }), {})
141
- }
142
- };
193
+ composerJsonData.config = {
194
+ ...(composerJsonData.config || {}),
195
+ 'allow-plugins': {
196
+ ...allowPlugins,
197
+ ...disabledPlugins.reduce((acc, val) => ({ ...acc, [val]: false }), {}),
198
+ ...userEnabledPlugins.reduce((acc, val) => ({ ...acc, [val]: true }), {})
199
+ }
200
+ };
143
201
 
144
- await fs.promises.writeFile(composerJsonPath, JSON.stringify(composerJsonData, null, 4), {
145
- encoding: 'utf-8'
146
- });
147
- } else {
148
- throw new KnownError('Please confirm your choice or choose other option.');
149
- }
202
+ await fs.promises.writeFile(composerJsonPath, JSON.stringify(composerJsonData, null, 4), {
203
+ encoding: 'utf-8'
204
+ });
150
205
 
151
206
  break;
152
207
  }
@@ -97,8 +97,9 @@ const createMagentoProject = async (ctx, task, {
97
97
  `"${tempDir}"`
98
98
  ];
99
99
 
100
- await runPHPContainerCommand(ctx, `composer ${installCommand.join(' ')} \n
101
- && mv ${tempDir}/composer.json ${ctx.config.baseConfig.containerMagentoDir}/composer.json`);
100
+ await runPHPContainerCommand(ctx, `bash -c 'mkdir ${tempDir} && \
101
+ composer ${installCommand.join(' ')} && \
102
+ mv ${tempDir}/composer.json ${ctx.config.baseConfig.containerMagentoDir}/composer.json'`);
102
103
  };
103
104
 
104
105
  /**
@@ -17,7 +17,7 @@ module.exports = () => ({
17
17
  databaseConnection
18
18
  } = ctx;
19
19
  const isNgrok = host.endsWith('ngrok.io');
20
- const enableSecureFrontend = ssl.enabled ? '1' : '0';
20
+ const enableSecureFrontend = (ctx.config.overridenConfiguration.configuration.varnish.enabled && ssl.enabled) ? '1' : '0';
21
21
  const location = `${host}${ !isNgrok && ports.sslTerminator !== 80 ? `:${ports.sslTerminator }` : '' }/`;
22
22
  const secureLocation = `${host}/`; // SSL will work only on port 443, so you cannot run multiple projects with SSL at the same time.
23
23
  const httpUrl = `http://${location}`;
@@ -37,7 +37,9 @@ const getIsHealthCheckRequestBroken = async (ctx) => {
37
37
  */
38
38
  const waitingForVarnish = () => ({
39
39
  title: 'Waiting for Varnish to return code 200',
40
- skip: (ctx) => ctx.debug || !ctx.config.overridenConfiguration.configuration.varnish.enabled,
40
+ skip: (ctx) => ctx.debug
41
+ || !ctx.config.overridenConfiguration.configuration.varnish.enabled
42
+ || ctx.config.overridenConfiguration.ssl.enabled,
41
43
  task: async (ctx, task) => {
42
44
  const pureMagentoVersion = ctx.magentoVersion.match(/^([0-9]+\.[0-9]+\.[0-9]+)/)[1];
43
45
 
@@ -10,9 +10,13 @@ const { containerApi } = require('../docker/containers');
10
10
  const runPHPContainerCommand = async (ctx, command, options = {}) => {
11
11
  const { php } = ctx.config.docker.getContainers(ctx.ports);
12
12
 
13
- const containers = await containerApi.ls({ formatToJSON: true, all: true });
13
+ const containers = await containerApi.ls({
14
+ formatToJSON: true,
15
+ all: true,
16
+ filter: `name=${php.name}`
17
+ });
14
18
 
15
- if (containers.some((c) => c.Names === php.name)) {
19
+ if (containers.length > 0) {
16
20
  return execPHPContainerCommand(ctx, command, options);
17
21
  }
18
22
 
@@ -30,6 +30,7 @@ NOTE: After installation it's recommended to log out and log back in so your gro
30
30
  if (automaticallyInstallDocker) {
31
31
  return task.newListr([
32
32
  installDocker(),
33
+ checkDockerSocketPermissions(),
33
34
  getDockerVersion(),
34
35
  {
35
36
  task: (ctx) => {
@@ -80,6 +81,7 @@ Would you like to install it automatically using brew cask or you prefer to inst
80
81
  if (confirmationToInstallDocker === 'automatic') {
81
82
  return task.newListr([
82
83
  installDockerOnMac(),
84
+ checkDockerSocketPermissions(),
83
85
  checkDockerStatus(),
84
86
  getDockerVersion(),
85
87
  setVersionInContextTask(task)
@@ -122,6 +124,7 @@ const checkDocker = () => ({
122
124
  }
123
125
 
124
126
  return task.newListr([
127
+ checkDockerSocketPermissions(),
125
128
  checkDockerStatus(),
126
129
  getDockerVersion(),
127
130
  setVersionInContextTask(task)
@@ -134,7 +137,6 @@ const checkDocker = () => ({
134
137
  */
135
138
  module.exports = () => ({
136
139
  task: (ctx, task) => task.newListr([
137
- checkDockerSocketPermissions(),
138
140
  checkDocker(),
139
141
  checkDockerPerformance()
140
142
  ], {
@@ -39,7 +39,6 @@ const retrieveProjectConfiguration = () => ({
39
39
  checkConfigurationFile(),
40
40
  getProjectConfiguration(),
41
41
  convertLegacyVolumes(),
42
- convertMySQLDatabaseToMariaDB(),
43
42
  createCacheFolder(),
44
43
  getSystemConfigTask(),
45
44
  getCachedPorts()
@@ -93,6 +92,7 @@ const retrieveFreshProjectConfiguration = () => ({
93
92
  const configureProject = () => ({
94
93
  title: 'Configuring project',
95
94
  task: (ctx, task) => task.newListr([
95
+ convertMySQLDatabaseToMariaDB(),
96
96
  pullImages(),
97
97
  dockerNetwork.tasks.createNetwork(),
98
98
  volumes.createVolumes(),
@@ -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[] }} param0
7
+ */
8
+ const executeInContainer = ({ containerName, commands }) => {
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' && `--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
+ };
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.1",
6
+ "version": "2.0.0-alpha.10",
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": "0b205dcab6056cf07988525ce053c5299af840e9"
57
+ "gitHead": "8b34ad44642dc8b4decf57df42f45ab2cdd18e16"
57
58
  }
@@ -1,26 +0,0 @@
1
- const os = require('os');
2
- const { spawn } = require('child_process');
3
-
4
- const executeInContainer = ({ containerName, commands }) => {
5
- if (!process.stdin.isTTY) {
6
- process.stderr.write('This app works only in TTY mode');
7
- process.exit(1);
8
- }
9
-
10
- const userArg = os.platform() === 'linux' && `--user=${os.userInfo().uid}:${os.userInfo().gid}`;
11
-
12
- spawn('docker', [
13
- 'exec',
14
- '-it',
15
- userArg,
16
- containerName
17
- ].filter(Boolean).concat(...commands.map((command) => command.split(' '))), {
18
- stdio: [0, 1, 2]
19
- });
20
-
21
- return new Promise((_resolve) => {
22
- // never resolve
23
- });
24
- };
25
-
26
- module.exports = executeInContainer;