@scandipwa/magento-scripts 1.15.2 → 1.15.5

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 (32) hide show
  1. package/lib/config/index.js +1 -3
  2. package/lib/config/templates/dataSources.local.template.xml +1 -1
  3. package/lib/config/templates/dataSources.template.xml +1 -1
  4. package/lib/config/templates/magentorc.template +5 -0
  5. package/lib/tasks/file-system/create-phpstorm-config/database-config.js +31 -34
  6. package/lib/tasks/file-system/create-phpstorm-config/eslint-config.js +39 -20
  7. package/lib/tasks/file-system/create-phpstorm-config/exclude-folder-config.js +37 -33
  8. package/lib/tasks/file-system/create-phpstorm-config/inspection-tools-config/default-properties-config.js +3 -3
  9. package/lib/tasks/file-system/create-phpstorm-config/inspection-tools-config/index.js +47 -10
  10. package/lib/tasks/file-system/create-phpstorm-config/inspection-tools-config/inspection-tools-config.js +11 -0
  11. package/lib/tasks/file-system/create-phpstorm-config/php-config/index.js +10 -26
  12. package/lib/tasks/file-system/create-phpstorm-config/php-config/php-config.js +20 -0
  13. package/lib/tasks/file-system/create-phpstorm-config/setup-xml-structure.js +40 -0
  14. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/composer-settings-config.js +1 -11
  15. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/index.js +16 -26
  16. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-debug-general-config.js +6 -7
  17. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-server-config.js +5 -6
  18. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/run-manager-config.js +7 -7
  19. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/workspace-config.js +20 -0
  20. package/lib/tasks/magento/setup-magento/disable-2fa.js +1 -1
  21. package/lib/tasks/magento/setup-magento/install-magento.js +48 -0
  22. package/lib/tasks/magento/setup-magento/upgrade-magento.js +1 -1
  23. package/lib/tasks/mysql/connect-to-mysql.js +61 -17
  24. package/lib/tasks/mysql/create-magento-database.js +18 -0
  25. package/lib/tasks/php/install-sodium.js +1 -1
  26. package/lib/tasks/requirements/phpbrew/install.js +1 -1
  27. package/lib/util/env-php-json.js +6 -1
  28. package/lib/util/exec-async-command.d.ts +0 -10
  29. package/lib/util/exec-async.d.ts +10 -0
  30. package/lib/util/open-browser.js +1 -1
  31. package/package.json +2 -2
  32. package/lib/config/phpstorm/debug-config.js +0 -46
@@ -7,7 +7,6 @@ const {
7
7
  const getPhpConfig = require('./php-config');
8
8
  const getComposerConfig = require('./composer');
9
9
  const { getMagentoConfig } = require('./magento-config');
10
- const { getPhpStormConfig } = require('./phpstorm/debug-config');
11
10
  const resolveConfigurationWithOverrides = require('../util/resolve-configuration-with-overrides');
12
11
  const { getPrefix, folderName } = require('../util/prefix');
13
12
  const UnknownError = require('../errors/unknown-error');
@@ -59,8 +58,7 @@ module.exports = {
59
58
  baseConfig: newBaseConfig,
60
59
  overridenConfiguration,
61
60
  userConfiguration,
62
- nonOverridenConfiguration: configurations[magentoVersion],
63
- phpStorm: getPhpStormConfig(overridenConfiguration, newBaseConfig)
61
+ nonOverridenConfiguration: configurations[magentoVersion]
64
62
  };
65
63
  },
66
64
  baseConfig,
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <project version="4">
3
3
  <component name="dataSourceStorageLocal" created-in="PS-212.5284.49">
4
- <data-source name="<%~ it.phpStorm.database.dataSourceManagerName %>" uuid="a2eadb3c-6fc9-4d85-b5f4-d8114906ce2f">
4
+ <data-source name="<%~ it.databaseConfiguration.dataSourceManagerName %>" uuid="a2eadb3c-6fc9-4d85-b5f4-d8114906ce2f">
5
5
  <database-info product="" version="" jdbc-version="" driver-name="" driver-version="" dbms="MYSQL" exact-version="0" />
6
6
  <secret-storage>master_key</secret-storage>
7
7
  <user-name>magento</user-name>
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <project version="4">
3
3
  <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
4
- <data-source source="LOCAL" name="<%~ it.phpStorm.database.dataSourceManagerName %>" uuid="a2eadb3c-6fc9-4d85-b5f4-d8114906ce2f">
4
+ <data-source source="LOCAL" name="<%~ it.databaseConfiguration.dataSourceManagerName %>" uuid="a2eadb3c-6fc9-4d85-b5f4-d8114906ce2f">
5
5
  <driver-ref>mysql.8</driver-ref>
6
6
  <synchronize>true</synchronize>
7
7
  <jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
@@ -1,5 +1,10 @@
1
+ RED='\033[0;31m'
2
+ GREEN='\033[0;32m'
3
+ NC='\033[0m' # No Color
4
+
1
5
  alias php="$HOME/.phpbrew/php/php-<%= it.php.version %>/bin/php -c $PWD/node_modules/.create-magento-app-cache/php.ini"
2
6
  alias magento="php $PWD/bin/magento"
7
+ alias magneto="echo -e 'Not ${RED}magneto${NC} but ${GREEN}magento${NC} please! or at least ${GREEN}m${NC}!' && magento"
3
8
  alias m="magento"
4
9
  alias composer="php $PWD/node_modules/.create-magento-app-cache/composer/composer.phar"
5
10
  alias c="composer"
@@ -1,9 +1,24 @@
1
1
  /* eslint-disable no-param-reassign */
2
+ const path = require('path');
3
+ const { baseConfig } = require('../../../config');
2
4
  const { loadXmlFile, buildXmlFile } = require('../../../config/xml-parser');
3
5
  const UnknownError = require('../../../errors/unknown-error');
4
6
  const pathExists = require('../../../util/path-exists');
5
7
  const setConfigFile = require('../../../util/set-config');
6
8
 
9
+ const databaseConfiguration = {
10
+ driver: 'mysql',
11
+ dataSourceManagerName: 'mysql 8.0',
12
+ dataSourcesLocal: {
13
+ path: path.join(process.cwd(), '.idea', 'dataSources.local.xml'),
14
+ templatePath: path.join(baseConfig.templateDir, 'dataSources.local.template.xml')
15
+ },
16
+ dataSources: {
17
+ path: path.join(process.cwd(), '.idea', 'dataSources.xml'),
18
+ templatePath: path.join(baseConfig.templateDir, 'dataSources.template.xml')
19
+ }
20
+ };
21
+
7
22
  /**
8
23
  * Get link to data-source field, create fields if necessary
9
24
  *
@@ -32,18 +47,9 @@ const getToDataSource = (data, defaultData) => {
32
47
  const setupDataSourceLocalConfig = () => ({
33
48
  title: 'Set up datasource local configuration',
34
49
  task: async (ctx, task) => {
35
- const {
36
- config: {
37
- phpStorm,
38
- phpStorm: {
39
- database
40
- }
41
- }
42
- } = ctx;
43
-
44
- if (await pathExists(database.dataSourcesLocal.path)) {
50
+ if (await pathExists(databaseConfiguration.dataSourcesLocal.path)) {
45
51
  let hasChanges = false;
46
- const dataSourcesLocalData = await loadXmlFile(database.dataSourcesLocal.path);
52
+ const dataSourcesLocalData = await loadXmlFile(databaseConfiguration.dataSourcesLocal.path);
47
53
  const dataSource = getToDataSource(
48
54
  dataSourcesLocalData,
49
55
  {
@@ -62,7 +68,7 @@ const setupDataSourceLocalConfig = () => ({
62
68
 
63
69
  if (!dataSource['@_name']) {
64
70
  hasChanges = true;
65
- dataSource['@_name'] = database.dataSourceManagerName;
71
+ dataSource['@_name'] = databaseConfiguration.dataSourceManagerName;
66
72
  }
67
73
 
68
74
  if (!dataSource['@_uuid']) {
@@ -115,24 +121,24 @@ const setupDataSourceLocalConfig = () => ({
115
121
  });
116
122
  }
117
123
 
118
- if (!('schema-mapping' in dataSource)) {
124
+ if (dataSource && dataSource['schema-mapping'] === undefined) {
119
125
  hasChanges = true;
120
126
  dataSource['schema-mapping'] = '';
121
127
  }
122
128
 
123
129
  if (hasChanges) {
124
- await buildXmlFile(database.dataSourcesLocal.path, dataSourcesLocalData);
130
+ await buildXmlFile(databaseConfiguration.dataSourcesLocal.path, dataSourcesLocalData);
125
131
  } else {
126
132
  task.skip();
127
133
  }
128
134
  } else {
129
135
  try {
130
136
  await setConfigFile({
131
- configPathname: phpStorm.database.dataSourcesLocal.path,
132
- template: phpStorm.database.dataSourcesLocal.templatePath,
137
+ configPathname: databaseConfiguration.dataSourcesLocal.path,
138
+ template: databaseConfiguration.dataSourcesLocal.templatePath,
133
139
  overwrite: true,
134
140
  templateArgs: {
135
- phpStorm
141
+ databaseConfiguration
136
142
  }
137
143
  });
138
144
  } catch (e) {
@@ -147,20 +153,11 @@ const setupDataSourceLocalConfig = () => ({
147
153
  */
148
154
  const setupDataSourceConfig = () => ({
149
155
  task: async (ctx, task) => {
150
- const {
151
- config: {
152
- phpStorm,
153
- phpStorm: {
154
- database
155
- }
156
- },
157
- ports
158
- } = ctx;
159
- const jdbcUrl = `jdbc:mysql://localhost:${ports.mysql}/magento`;
156
+ const jdbcUrl = `jdbc:mysql://localhost:${ctx.ports.mysql}/magento`;
160
157
 
161
- if (await pathExists(database.dataSources.path)) {
158
+ if (await pathExists(databaseConfiguration.dataSources.path)) {
162
159
  let hasChanges = false;
163
- const dataSourcesData = await loadXmlFile(database.dataSources.path);
160
+ const dataSourcesData = await loadXmlFile(databaseConfiguration.dataSources.path);
164
161
  const dataSource = getToDataSource(
165
162
  dataSourcesData,
166
163
  {
@@ -185,7 +182,7 @@ const setupDataSourceConfig = () => ({
185
182
  }
186
183
 
187
184
  const expectedDataSourceData = {
188
- '@_name': database.dataSourceManagerName,
185
+ '@_name': databaseConfiguration.dataSourceManagerName,
189
186
  'driver-ref': 'mysql.8',
190
187
  synchronize: true,
191
188
  'jdbc-driver': 'com.mysql.cj.jdbc.Driver',
@@ -213,18 +210,18 @@ const setupDataSourceConfig = () => ({
213
210
  }
214
211
 
215
212
  if (hasChanges) {
216
- await buildXmlFile(database.dataSources.path, dataSourcesData);
213
+ await buildXmlFile(databaseConfiguration.dataSources.path, dataSourcesData);
217
214
  } else {
218
215
  task.skip();
219
216
  }
220
217
  } else {
221
218
  try {
222
219
  await setConfigFile({
223
- configPathname: phpStorm.database.dataSources.path,
224
- template: phpStorm.database.dataSources.templatePath,
220
+ configPathname: databaseConfiguration.dataSources.path,
221
+ template: databaseConfiguration.dataSources.templatePath,
225
222
  overwrite: true,
226
223
  templateArgs: {
227
- phpStorm,
224
+ databaseConfiguration,
228
225
  jdbcUrl
229
226
  }
230
227
  });
@@ -17,10 +17,39 @@ const defaultESLintComponentConfiguration = {
17
17
  }
18
18
  };
19
19
 
20
+ const setupESlintConfig = async (esLintConfigurationData) => {
21
+ let hasChanges = false;
22
+ const themes = await getCSAThemes();
23
+
24
+ if (themes.length > 0) {
25
+ const theme = themes[0];
26
+ if (await pathExists(theme.themePath)) {
27
+ if (esLintConfigurationData['work-dir-pattern'] === undefined) {
28
+ hasChanges = true;
29
+ esLintConfigurationData['work-dir-pattern'] = {
30
+ [valueKey]: formatPathForPHPStormConfig(theme.themePath)
31
+ };
32
+ }
33
+ const packageJsonPath = path.join(process.cwd(), theme.themePath, 'package.json');
34
+ if (await pathExists(packageJsonPath)) {
35
+ if (esLintConfigurationData['custom-configuration-file'] === undefined) {
36
+ hasChanges = true;
37
+ esLintConfigurationData['custom-configuration-file'] = {
38
+ '@_used': 'true',
39
+ '@_path': formatPathForPHPStormConfig(packageJsonPath)
40
+ };
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ return hasChanges;
47
+ };
48
+
20
49
  /**
21
50
  * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
22
51
  */
23
- const setupESLintConfig = () => ({
52
+ const setupESLintConfigTask = () => ({
24
53
  title: 'Set up ESLint configuration',
25
54
  task: async (ctx, task) => {
26
55
  if (await pathExists(pathToESLintConfig)) {
@@ -41,6 +70,11 @@ const setupESLintConfig = () => ({
41
70
  esLintConfigurationData.project.component.push(defaultESLintComponentConfiguration);
42
71
  }
43
72
 
73
+ const hasThemeEslintChanges = await setupESlintConfig(esLintConfigurationComponent);
74
+ if (hasThemeEslintChanges) {
75
+ hasChanges = hasThemeEslintChanges;
76
+ }
77
+
44
78
  if (hasChanges) {
45
79
  await buildXmlFile(pathToESLintConfig, esLintConfigurationData);
46
80
  } else {
@@ -50,7 +84,7 @@ const setupESLintConfig = () => ({
50
84
  return;
51
85
  }
52
86
 
53
- const styleLintConfigurationData = {
87
+ const esLintConfigurationData = {
54
88
  '?xml': {
55
89
  '@_version': '1.0',
56
90
  '@_encoding': 'UTF-8'
@@ -60,26 +94,11 @@ const setupESLintConfig = () => ({
60
94
  component: defaultESLintComponentConfiguration
61
95
  }
62
96
  };
63
- const themes = await getCSAThemes();
64
97
 
65
- if (themes.length > 0) {
66
- const theme = themes[0];
67
- if (await pathExists(theme.themePath)) {
68
- styleLintConfigurationData.project.component['work-dir-pattern'] = {
69
- [valueKey]: formatPathForPHPStormConfig(theme.themePath)
70
- };
71
- const packageJsonPath = path.join(process.cwd(), theme.themePath, 'package.json');
72
- if (await pathExists(packageJsonPath)) {
73
- styleLintConfigurationData.project.component['custom-configuration-file'] = {
74
- '@_used': 'true',
75
- '@_path': formatPathForPHPStormConfig(packageJsonPath)
76
- };
77
- }
78
- }
79
- }
98
+ await setupESlintConfig(esLintConfigurationData);
80
99
 
81
- await buildXmlFile(pathToESLintConfig, styleLintConfigurationData);
100
+ await buildXmlFile(pathToESLintConfig, esLintConfigurationData);
82
101
  }
83
102
  });
84
103
 
85
- module.exports = setupESLintConfig;
104
+ module.exports = setupESLintConfigTask;
@@ -86,33 +86,35 @@ const setupExcludedFolders = (excludedFoldersConfig) => {
86
86
  return hasChanges;
87
87
  };
88
88
 
89
- const createModulesXML = async () => {
89
+ const getIMLFilePath = async () => {
90
90
  const filePath = path.join(process.cwd(), '.idea', `${path.parse(process.cwd()).base}.iml`);
91
- const fileFormattedPath = formatPathForPHPStormConfig(filePath);
92
- const fileFormattedUrl = `file://${fileFormattedPath}`;
93
-
94
- const modulesConfig = {
95
- '?xml': {
96
- '@_version': '1.0',
97
- '@_encoding': 'UTF-8'
98
- },
99
- project: {
100
- '@_version': '4',
101
- component: {
102
- '@_name': 'ProjectModuleManager',
103
- modules: [
104
- {
105
- module: {
106
- '@_fileurl': fileFormattedUrl,
107
- '@_filepath': fileFormattedPath
91
+ if (!await pathExists(pathToModulesConfig)) {
92
+ const fileFormattedPath = formatPathForPHPStormConfig(filePath);
93
+ const fileFormattedUrl = `file://${fileFormattedPath}`;
94
+
95
+ const modulesConfig = {
96
+ '?xml': {
97
+ '@_version': '1.0',
98
+ '@_encoding': 'UTF-8'
99
+ },
100
+ project: {
101
+ '@_version': '4',
102
+ component: {
103
+ '@_name': 'ProjectModuleManager',
104
+ modules: [
105
+ {
106
+ module: {
107
+ '@_fileurl': fileFormattedUrl,
108
+ '@_filepath': fileFormattedPath
109
+ }
108
110
  }
109
- }
110
- ]
111
+ ]
112
+ }
111
113
  }
112
- }
113
- };
114
+ };
114
115
 
115
- await buildXmlFile(pathToModulesConfig, modulesConfig);
116
+ await buildXmlFile(pathToModulesConfig, modulesConfig);
117
+ }
116
118
 
117
119
  return filePath;
118
120
  };
@@ -125,19 +127,21 @@ const setupExcludedFoldersConfig = () => ({
125
127
  task: async (ctx, task) => {
126
128
  if (await pathExists(pathToModulesConfig)) {
127
129
  const projectFilePath = await getProjectConfigFilePath();
128
- const projectConfigData = await loadXmlFile(projectFilePath);
129
- const excludedFoldersConfig = getExcludedFoldersConfig(projectConfigData);
130
- const hasChanges = setupExcludedFolders(excludedFoldersConfig);
131
- if (hasChanges) {
132
- await buildXmlFile(projectFilePath, projectConfigData);
133
- } else {
134
- task.skip();
135
- }
130
+ if (await pathExists(projectFilePath)) {
131
+ const projectConfigData = await loadXmlFile(projectFilePath);
132
+ const excludedFoldersConfig = getExcludedFoldersConfig(projectConfigData);
133
+ const hasChanges = setupExcludedFolders(excludedFoldersConfig);
134
+ if (hasChanges) {
135
+ await buildXmlFile(projectFilePath, projectConfigData);
136
+ } else {
137
+ task.skip();
138
+ }
136
139
 
137
- return;
140
+ return;
141
+ }
138
142
  }
139
143
 
140
- const projectFilePath = await createModulesXML();
144
+ const projectFilePath = await getIMLFilePath();
141
145
  const projectConfigData = {
142
146
  '?xml': {
143
147
  '@_version': '1.0',
@@ -16,17 +16,17 @@ const properties = {
16
16
  */
17
17
  const setupDefaultProperties = (inspectionTool, defaultProperties = properties) => {
18
18
  let hasChanges = false;
19
- if (!inspectionTool['@_enabled']) {
19
+ if (inspectionTool['@_enabled'] === undefined) {
20
20
  hasChanges = true;
21
21
  inspectionTool['@_enabled'] = defaultProperties.enabled;
22
22
  }
23
23
 
24
- if (!inspectionTool['@_enabled_by_default']) {
24
+ if (inspectionTool['@_enabled_by_default'] === undefined) {
25
25
  hasChanges = true;
26
26
  inspectionTool['@_enabled_by_default'] = defaultProperties.enabled_by_default;
27
27
  }
28
28
 
29
- if (!inspectionTool['@_level']) {
29
+ if (inspectionTool['@_level'] === undefined) {
30
30
  hasChanges = true;
31
31
  inspectionTool['@_level'] = defaultProperties.level;
32
32
  }
@@ -6,25 +6,62 @@ const {
6
6
  classKey
7
7
  } = require('../keys');
8
8
  const setupESLintInspection = require('./eslint-inspection-config');
9
+ const { getInspectionToolsConfig } = require('./inspection-tools-config');
9
10
  const setupMessDetectorValidationInspection = require('./mess-detector-validation-inspection-config');
10
11
  const setupPhpCSFixerValidationInspection = require('./php-cs-fixer-validation-inspection-config');
11
12
  const setupPhpCSValidationInspection = require('./php-cs-validation-inspection-config');
12
13
  const setupStyleLintInspection = require('./stylelint-inspection-config');
13
14
 
15
+ const inspectionProfileDefaults = {
16
+ component: {
17
+ [nameKey]: 'InspectionProjectProfileManager',
18
+ profile: {
19
+ '@_version': '1.0',
20
+ option: {
21
+ [nameKey]: 'myName',
22
+ [valueKey]: 'Project Default'
23
+ },
24
+ inspection_tool: [
25
+ {
26
+ [classKey]: 'PhpStanGlobal',
27
+ '@_enabled': 'true',
28
+ '@_level': 'ERROR',
29
+ '@_enabled_by_default': 'true'
30
+ }
31
+ ]
32
+ }
33
+ }
34
+ };
35
+
14
36
  /**
15
37
  * @type {() => import('listr2').ListrTask<import('../../../../../typings/context').ListrContext>}
16
38
  */
17
- const setupInspectionToolsConfig = () => ({
39
+ const setupInspectionToolsConfigTask = () => ({
18
40
  title: 'Set up inspection tools configuration',
19
41
  task: async (ctx, task) => {
20
- const {
21
- config: {
22
- phpStorm
42
+ const inspectionToolsConfig = getInspectionToolsConfig();
43
+ if (await pathExists(inspectionToolsConfig.path)) {
44
+ const inspectionToolsData = await loadXmlFile(inspectionToolsConfig.path);
45
+
46
+ if (!inspectionToolsData.component) {
47
+ inspectionToolsData.component = inspectionProfileDefaults.component;
48
+ }
49
+
50
+ if (!inspectionToolsData.component.profile) {
51
+ inspectionToolsData.component.profile = inspectionProfileDefaults.component.profile;
52
+ }
53
+
54
+ if (!inspectionToolsData.component.profile.inspection_tool) {
55
+ inspectionToolsData.component.profile.inspection_tool = [];
56
+ }
57
+
58
+ // eslint-disable-next-line max-len
59
+ if (!Array.isArray(inspectionToolsData.component.profile.inspection_tool) && Boolean(inspectionToolsData.component.profile.inspection_tool)) {
60
+ inspectionToolsData.component.profile.inspection_tool = [
61
+ inspectionToolsData.component.profile.inspection_tool
62
+ ];
23
63
  }
24
- } = ctx;
25
64
 
26
- if (await pathExists(phpStorm.inspectionTools.path)) {
27
- const inspectionToolsData = await loadXmlFile(phpStorm.inspectionTools.path);
28
65
  const inspectionTools = inspectionToolsData.component.profile.inspection_tool;
29
66
  const hasChanges = await Promise.all([
30
67
  setupPhpCSFixerValidationInspection(inspectionTools),
@@ -34,7 +71,7 @@ const setupInspectionToolsConfig = () => ({
34
71
  ]);
35
72
 
36
73
  if (hasChanges.includes(true)) {
37
- await buildXmlFile(phpStorm.inspectionTools.path, inspectionToolsData);
74
+ await buildXmlFile(inspectionToolsConfig.path, inspectionToolsData);
38
75
  } else {
39
76
  task.skip();
40
77
  }
@@ -73,8 +110,8 @@ const setupInspectionToolsConfig = () => ({
73
110
  setupESLintInspection(inspectionTools)
74
111
  ]);
75
112
 
76
- await buildXmlFile(phpStorm.inspectionTools.path, inspectionToolsData);
113
+ await buildXmlFile(inspectionToolsConfig.path, inspectionToolsData);
77
114
  }
78
115
  });
79
116
 
80
- module.exports = setupInspectionToolsConfig;
117
+ module.exports = setupInspectionToolsConfigTask;
@@ -0,0 +1,11 @@
1
+ const path = require('path');
2
+ const { baseConfig } = require('../../../../config');
3
+
4
+ const getInspectionToolsConfig = () => ({
5
+ path: path.join(process.cwd(), '.idea', 'inspectionProfiles', 'Project_Default.xml'),
6
+ templatePath: path.join(baseConfig.templateDir, 'Project_Default.template.xml')
7
+ });
8
+
9
+ module.exports = {
10
+ getInspectionToolsConfig
11
+ };
@@ -1,7 +1,9 @@
1
1
  const { loadXmlFile, buildXmlFile } = require('../../../../config/xml-parser');
2
2
  const pathExists = require('../../../../util/path-exists');
3
+ const { setupXMLStructure } = require('../setup-xml-structure');
3
4
  const setupMessDetector = require('./mess-detector-config');
4
5
  const setupPHPCodeSniffer = require('./php-code-sniffer-config');
6
+ const { getPhpConfig } = require('./php-config');
5
7
  const setupPHPCSFixer = require('./php-cs-fixer-config');
6
8
  const setupPHPProjectSharedConfiguration = require('./php-project-shared-configuration-config');
7
9
 
@@ -11,29 +13,20 @@ const setupPHPProjectSharedConfiguration = require('./php-project-shared-configu
11
13
  const setupPhpConfig = () => ({
12
14
  title: 'Set up PHP configuration',
13
15
  task: async (ctx, task) => {
14
- const {
15
- config: {
16
- phpStorm,
17
- phpStorm: {
18
- php: {
19
- phpLanguageLevel
20
- }
21
- }
22
- }
23
- } = ctx;
16
+ const phpConfig = getPhpConfig(ctx.config.overridenConfiguration);
24
17
 
25
- if (await pathExists(phpStorm.php.path)) {
26
- const phpConfigContent = await loadXmlFile(phpStorm.php.path);
18
+ if (await pathExists(phpConfig.path)) {
19
+ const phpConfigContent = setupXMLStructure(await loadXmlFile(phpConfig.path));
27
20
  const phpConfigs = phpConfigContent.project.component;
28
21
  const hasChanges = await Promise.all([
29
22
  setupMessDetector(phpConfigs),
30
23
  setupPHPCodeSniffer(phpConfigs),
31
24
  setupPHPCSFixer(phpConfigs),
32
- setupPHPProjectSharedConfiguration(phpConfigs, phpLanguageLevel)
25
+ setupPHPProjectSharedConfiguration(phpConfigs, phpConfig.phpLanguageLevel)
33
26
  ]);
34
27
 
35
28
  if (hasChanges.includes(true)) {
36
- await buildXmlFile(phpStorm.php.path, phpConfigContent);
29
+ await buildXmlFile(phpConfig.path, phpConfigContent);
37
30
  } else {
38
31
  task.skip();
39
32
  }
@@ -41,26 +34,17 @@ const setupPhpConfig = () => ({
41
34
  return;
42
35
  }
43
36
 
44
- const phpConfigContent = {
45
- '?xml': {
46
- '@_version': '1.0',
47
- '@_encoding': 'UTF-8'
48
- },
49
- project: {
50
- '@_version': '4',
51
- component: []
52
- }
53
- };
37
+ const phpConfigContent = setupXMLStructure();
54
38
  const phpConfigs = phpConfigContent.project.component;
55
39
 
56
40
  await Promise.all([
57
41
  setupMessDetector(phpConfigs),
58
42
  setupPHPCodeSniffer(phpConfigs),
59
43
  setupPHPCSFixer(phpConfigs),
60
- setupPHPProjectSharedConfiguration(phpConfigs, phpLanguageLevel)
44
+ setupPHPProjectSharedConfiguration(phpConfigs, phpConfig.phpLanguageLevel)
61
45
  ]);
62
46
 
63
- await buildXmlFile(phpStorm.php.path, phpConfigContent);
47
+ await buildXmlFile(phpConfig.path, phpConfigContent);
64
48
  }
65
49
  });
66
50
 
@@ -0,0 +1,20 @@
1
+ const path = require('path');
2
+ const { baseConfig } = require('../../../../config');
3
+
4
+ /**
5
+ * @param {import('../../../../../typings/index').CMAConfiguration} app
6
+ */
7
+ const getPhpConfig = (app) => {
8
+ const [majorPHPVersion, minorPHPVersion] = app.configuration.php.version.split('.');
9
+ const phpLanguageLevel = `${ majorPHPVersion }.${ minorPHPVersion }`;
10
+
11
+ return {
12
+ phpLanguageLevel,
13
+ path: path.join(process.cwd(), '.idea', 'php.xml'),
14
+ templatePath: path.join(baseConfig.templateDir, 'php.template.xml')
15
+ };
16
+ };
17
+
18
+ module.exports = {
19
+ getPhpConfig
20
+ };
@@ -0,0 +1,40 @@
1
+ const xmlConfiguration = {
2
+ '?xml': {
3
+ '@_version': '1.0',
4
+ '@_encoding': 'UTF-8'
5
+ },
6
+ project: {
7
+ '@_version': '4',
8
+ component: []
9
+ }
10
+ };
11
+
12
+ const setupXMLStructure = (data) => {
13
+ if (!data) {
14
+ data = xmlConfiguration;
15
+ }
16
+
17
+ if (data['?xml'] === undefined) {
18
+ data['?xml'] = xmlConfiguration['?xml'];
19
+ }
20
+
21
+ if (data.project === undefined) {
22
+ data.project = xmlConfiguration.project;
23
+ }
24
+
25
+ if (data.project.component === undefined) {
26
+ data.project.component = xmlConfiguration.project.component;
27
+ }
28
+
29
+ if (!Array.isArray(data.project.component) && Boolean(data.project.component)) {
30
+ data.project.component = [
31
+ data.project.component
32
+ ];
33
+ }
34
+
35
+ return data;
36
+ };
37
+
38
+ module.exports = {
39
+ setupXMLStructure
40
+ };
@@ -48,7 +48,7 @@ const setupComposerSettings = async (workspaceConfigs) => {
48
48
 
49
49
  if (composerSettingsComponent) {
50
50
  if (
51
- !('pharConfigPath' in composerSettingsComponent)
51
+ composerSettingsComponent.pharConfigPath === undefined
52
52
  && isComposerJsonExists
53
53
  ) {
54
54
  hasChanges = true;
@@ -67,16 +67,6 @@ const setupComposerSettings = async (workspaceConfigs) => {
67
67
  [pharPathKey]: composerPharFormattedPath
68
68
  };
69
69
  }
70
-
71
- const composerSettingsMissingProperties = Object.entries(defaultComposerSettingsProperties)
72
- .filter(([key]) => !(key in composerSettingsComponent));
73
-
74
- if (composerSettingsMissingProperties.length > 0) {
75
- hasChanges = true;
76
- composerSettingsMissingProperties.forEach(([key, value]) => {
77
- composerSettingsComponent[key] = value;
78
- });
79
- }
80
70
  } else {
81
71
  hasChanges = true;
82
72
  workspaceConfigs.push({
@@ -1,11 +1,14 @@
1
1
  const { loadXmlFile, buildXmlFile } = require('../../../../config/xml-parser');
2
2
  const pathExists = require('../../../../util/path-exists');
3
+ const { getPhpConfig } = require('../php-config/php-config');
4
+ const { setupXMLStructure } = require('../setup-xml-structure');
3
5
  const setupComposerSettings = require('./composer-settings-config');
4
6
  const setupFormatOnSave = require('./format-setting-config');
5
7
  const setupPHPDebugGeneral = require('./php-debug-general-config');
6
8
  const setupPHPServers = require('./php-server-config');
7
9
  const setupPropertiesComponent = require('./properties-component-config');
8
10
  const setupRunManager = require('./run-manager-config');
11
+ const { getWorkspaceConfig } = require('./workspace-config');
9
12
 
10
13
  /**
11
14
  * @type {() => import('listr2').ListrTask<import('../../../../../typings/context').ListrContext>}
@@ -13,24 +16,20 @@ const setupRunManager = require('./run-manager-config');
13
16
  const setupWorkspaceConfig = () => ({
14
17
  title: 'Set up Workspace configuration',
15
18
  task: async (ctx, task) => {
16
- const {
17
- config: {
18
- phpStorm
19
- }
20
- } = ctx;
21
-
22
- if (await pathExists(phpStorm.xdebug.path)) {
23
- const workspaceConfiguration = await loadXmlFile(phpStorm.xdebug.path);
19
+ const workspaceConfig = getWorkspaceConfig(ctx.config.overridenConfiguration);
20
+ const phpConfig = getPhpConfig(ctx.config.overridenConfiguration);
21
+ if (await pathExists(workspaceConfig.path)) {
22
+ const workspaceConfiguration = setupXMLStructure(await loadXmlFile(workspaceConfig.path));
24
23
  const workspaceConfigs = workspaceConfiguration.project.component;
25
24
  const hasChanges = await Promise.all([
26
- setupPHPDebugGeneral(workspaceConfigs, phpStorm),
27
- setupPHPServers(workspaceConfigs, phpStorm),
28
- setupRunManager(workspaceConfigs, phpStorm),
25
+ setupPHPDebugGeneral(workspaceConfigs, workspaceConfig),
26
+ setupPHPServers(workspaceConfigs, workspaceConfig),
27
+ setupRunManager(workspaceConfigs, workspaceConfig),
29
28
  setupPropertiesComponent(workspaceConfigs)
30
29
  ]);
31
30
 
32
31
  if (hasChanges.includes(true)) {
33
- await buildXmlFile(phpStorm.php.path, workspaceConfiguration);
32
+ await buildXmlFile(phpConfig.path, workspaceConfiguration);
34
33
  } else {
35
34
  task.skip();
36
35
  }
@@ -38,28 +37,19 @@ const setupWorkspaceConfig = () => ({
38
37
  return;
39
38
  }
40
39
 
41
- const workspaceConfiguration = {
42
- '?xml': {
43
- '@_version': '1.0',
44
- '@_encoding': 'UTF-8'
45
- },
46
- project: {
47
- '@_version': '4',
48
- component: []
49
- }
50
- };
40
+ const workspaceConfiguration = setupXMLStructure();
51
41
  const workspaceConfigs = workspaceConfiguration.project.component;
52
42
 
53
43
  await Promise.all([
54
- setupPHPDebugGeneral(workspaceConfigs, phpStorm),
55
- setupPHPServers(workspaceConfigs, phpStorm),
56
- setupRunManager(workspaceConfigs, phpStorm),
44
+ setupPHPDebugGeneral(workspaceConfigs, workspaceConfig),
45
+ setupPHPServers(workspaceConfigs, workspaceConfig),
46
+ setupRunManager(workspaceConfigs, workspaceConfig),
57
47
  setupPropertiesComponent(workspaceConfigs),
58
48
  setupComposerSettings(workspaceConfigs),
59
49
  setupFormatOnSave(workspaceConfigs)
60
50
  ]);
61
51
 
62
- await buildXmlFile(phpStorm.xdebug.path, workspaceConfiguration);
52
+ await buildXmlFile(workspaceConfig.path, workspaceConfiguration);
63
53
  }
64
54
  });
65
55
 
@@ -10,11 +10,10 @@ const ignoreConnectionsThroughUnregisteredServersKey = '@_ignore_connections_thr
10
10
 
11
11
  /**
12
12
  * @param {Array} workspaceConfigs
13
- * @param {import('../../../../../typings/phpstorm').PHPStormConfig} phpStormConfiguration
13
+ * @param {ReturnType<typeof import('./workspace-config').getWorkspaceConfig>} workspaceConfig
14
14
  * @returns {Promise<Boolean>}
15
15
  */
16
- const setupPHPDebugGeneral = async (workspaceConfigs, phpStormConfiguration) => {
17
- const { xdebug } = phpStormConfiguration;
16
+ const setupPHPDebugGeneral = async (workspaceConfigs, workspaceConfig) => {
18
17
  let hasChanges = false;
19
18
  const phpDebugGeneralComponent = workspaceConfigs.find(
20
19
  (workspaceConfig) => workspaceConfig[nameKey] === PHP_DEBUG_GENERAL_COMPONENT_NAME
@@ -31,10 +30,10 @@ const setupPHPDebugGeneral = async (workspaceConfigs, phpStormConfiguration) =>
31
30
 
32
31
  if (!(xdebugDebugPortKey in phpDebugGeneralComponent)) {
33
32
  hasChanges = true;
34
- phpDebugGeneralComponent[xdebugDebugPortKey] = xdebug.v3Port;
33
+ phpDebugGeneralComponent[xdebugDebugPortKey] = workspaceConfig.v3Port;
35
34
  }
36
35
 
37
- const missingXDebugPorts = [xdebug.v3Port, xdebug.v2Port].filter(
36
+ const missingXDebugPorts = [workspaceConfig.v3Port, workspaceConfig.v2Port].filter(
38
37
  (port) => !phpDebugGeneralComponent.xdebug_debug_ports.some((xPort) => xPort[portKey] === port)
39
38
  );
40
39
 
@@ -50,9 +49,9 @@ const setupPHPDebugGeneral = async (workspaceConfigs, phpStormConfiguration) =>
50
49
  hasChanges = true;
51
50
  workspaceConfigs.push({
52
51
  [nameKey]: PHP_DEBUG_GENERAL_COMPONENT_NAME,
53
- [xdebugDebugPortKey]: xdebug.v3Port,
52
+ [xdebugDebugPortKey]: workspaceConfig.v3Port,
54
53
  [ignoreConnectionsThroughUnregisteredServersKey]: 'true',
55
- xdebug_debug_ports: [xdebug.v3Port, xdebug.v2Port].map((port) => ({
54
+ xdebug_debug_ports: [workspaceConfig.v3Port, workspaceConfig.v2Port].map((port) => ({
56
55
  [portKey]: port
57
56
  }))
58
57
  });
@@ -6,20 +6,19 @@ const hostKey = '@_host';
6
6
 
7
7
  /**
8
8
  * @param {Array} workspaceConfigs
9
- * @param {import('../../../../../typings/phpstorm').PHPStormConfig} phpStormConfiguration
9
+ * @param {ReturnType<typeof import('./workspace-config').getWorkspaceConfig>} workspaceConfig
10
10
  * @returns {Promise<Boolean>}
11
11
  */
12
- const setupPHPServers = async (workspaceConfigs, phpStormConfiguration) => {
13
- const { xdebug } = phpStormConfiguration;
12
+ const setupPHPServers = async (workspaceConfigs, workspaceConfig) => {
14
13
  let hasChanges = false;
15
14
  const phpServersComponent = workspaceConfigs.find(
16
15
  (workspaceConfig) => workspaceConfig[nameKey] === PHP_SERVERS_COMPONENT_NAME
17
16
  );
18
17
 
19
18
  const defaultServerConfig = {
20
- [hostKey]: xdebug.debugServerAddress,
19
+ [hostKey]: workspaceConfig.debugServerAddress,
21
20
  id: '7e16e907-9ce3-4559-9d26-a30a5650d11f',
22
- [nameKey]: xdebug.serverName
21
+ [nameKey]: workspaceConfig.serverName
23
22
  };
24
23
 
25
24
  if (phpServersComponent) {
@@ -31,7 +30,7 @@ const setupPHPServers = async (workspaceConfigs, phpStormConfiguration) => {
31
30
  phpServersComponent.servers = [];
32
31
  }
33
32
 
34
- const serverConfiguration = phpServersComponent.servers.find((server) => server.server[nameKey] === xdebug.serverName);
33
+ const serverConfiguration = phpServersComponent.servers.find((server) => server.server[nameKey] === workspaceConfig.serverName);
35
34
 
36
35
  if (!serverConfiguration) {
37
36
  hasChanges = true;
@@ -9,23 +9,22 @@ const sessionIdKey = '@_session_id';
9
9
 
10
10
  /**
11
11
  * @param {Array} workspaceConfigs
12
- * @param {import('../../../../../typings/phpstorm').PHPStormConfig} phpStormConfiguration
12
+ * @param {ReturnType<typeof import('./workspace-config').getWorkspaceConfig>} workspaceConfig
13
13
  * @returns {Promise<Boolean>}
14
14
  */
15
- const setupRunManager = async (workspaceConfigs, phpStormConfiguration) => {
16
- const { xdebug } = phpStormConfiguration;
15
+ const setupRunManager = async (workspaceConfigs, workspaceConfig) => {
17
16
  let hasChanges = false;
18
17
  const runManagerComponent = workspaceConfigs.find(
19
18
  (workspaceConfig) => workspaceConfig[nameKey] === RUN_MANAGER_COMPONENT_NAME
20
19
  );
21
20
 
22
21
  const defaultRunManagerConfiguration = {
23
- [nameKey]: xdebug.runManagerName,
22
+ [nameKey]: workspaceConfig.runManagerName,
24
23
  '@_type': PHP_REMOTE_DEBUG_RUN_CONFIGURATION_TYPE,
25
24
  '@_factoryName': 'PHP Remote Debug',
26
25
  '@_filter_connections': 'FILTER',
27
- [serverNameKey]: xdebug.serverName,
28
- [sessionIdKey]: xdebug.sessionId,
26
+ [serverNameKey]: workspaceConfig.serverName,
27
+ [sessionIdKey]: workspaceConfig.sessionId,
29
28
  method: {
30
29
  '@_v': '2'
31
30
  }
@@ -41,7 +40,8 @@ const setupRunManager = async (workspaceConfigs, phpStormConfiguration) => {
41
40
  }
42
41
 
43
42
  const phpRemoteDebugRunConfiguration = runManagerComponent.configuration.find(
44
- (configuration) => configuration['@_type'] === PHP_REMOTE_DEBUG_RUN_CONFIGURATION_TYPE && configuration[nameKey] === xdebug.runManagerName
43
+ // eslint-disable-next-line max-len
44
+ (configuration) => configuration['@_type'] === PHP_REMOTE_DEBUG_RUN_CONFIGURATION_TYPE && configuration[nameKey] === workspaceConfig.runManagerName
45
45
  );
46
46
 
47
47
  if (!phpRemoteDebugRunConfiguration) {
@@ -0,0 +1,20 @@
1
+ const path = require('path');
2
+ const { baseConfig } = require('../../../../config');
3
+
4
+ /**
5
+ * @param {import('../../../../../typings/index').CMAConfiguration} app
6
+ */
7
+ const getWorkspaceConfig = (app) => ({
8
+ v2Port: '9111',
9
+ v3Port: '9003',
10
+ debugServerAddress: `http://${ app.host }`,
11
+ serverName: 'create-magento-app',
12
+ runManagerName: 'create-magento-app',
13
+ sessionId: 'PHPSTORM',
14
+ path: path.join(process.cwd(), '.idea', 'workspace.xml'),
15
+ templatePath: path.join(baseConfig.templateDir, 'workspace.template.xml')
16
+ });
17
+
18
+ module.exports = {
19
+ getWorkspaceConfig
20
+ };
@@ -9,7 +9,7 @@ module.exports = () => ({
9
9
  task: async ({ magentoVersion }, task) => {
10
10
  const { modules } = await configPhpToJson(process.cwd(), { magentoVersion });
11
11
 
12
- if (modules.Magento_TwoFactorAuth !== 0) {
12
+ if (modules.Magento_TwoFactorAuth !== undefined && modules.Magento_TwoFactorAuth !== 0) {
13
13
  await runMagentoCommand('module:disable Magento_TwoFactorAuth', {
14
14
  magentoVersion
15
15
  });
@@ -1,6 +1,10 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
1
3
  const semver = require('semver');
2
4
  const UnknownError = require('../../../errors/unknown-error');
3
5
  const runMagentoCommand = require('../../../util/run-magento');
6
+ const envPhpToJson = require('../../../util/env-php-json');
7
+ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
4
8
 
5
9
  /**
6
10
  * @type {({ isDbEmpty }: { isDbEmpty: boolean }) => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
@@ -20,6 +24,21 @@ const installMagento = ({ isDbEmpty = false } = {}) => ({
20
24
  ports
21
25
  } = ctx;
22
26
  const { mysql: { env } } = docker.getContainers(ports);
27
+ const envPhpData = await envPhpToJson(process.cwd(), {
28
+ magentoVersion: ctx.magentoVersion
29
+ });
30
+
31
+ const envPhpHaveEncryptionKey = envPhpData && envPhpData.crypt && envPhpData.crypt.key && envPhpData.crypt.key;
32
+
33
+ let encryptionKeyOption = null;
34
+
35
+ if (ctx.encryptionKey) {
36
+ encryptionKeyOption = `--key='${ctx.encryptionKey}'`;
37
+ }
38
+
39
+ if (envPhpHaveEncryptionKey && !encryptionKeyOption) {
40
+ encryptionKeyOption = `--key='${envPhpData.crypt.key}'`;
41
+ }
23
42
 
24
43
  let installed = false;
25
44
 
@@ -46,6 +65,7 @@ const installMagento = ({ isDbEmpty = false } = {}) => ({
46
65
  --admin-user='${ magentoConfiguration.user }' \
47
66
  --admin-password='${ magentoConfiguration.password }' \
48
67
  ${ !isMagento23 ? elasticsearchConfiguration : '' } \
68
+ ${encryptionKeyOption || ''} \
49
69
  --session-save=redis \
50
70
  --session-save-redis-host='127.0.0.1' \
51
71
  --session-save-redis-port='${ ports.redis }' \
@@ -85,6 +105,34 @@ const installMagento = ({ isDbEmpty = false } = {}) => ({
85
105
  }
86
106
  }
87
107
 
108
+ if (errors.length > 0) {
109
+ if (envPhpHaveEncryptionKey && errors.some(
110
+ (e) => e.message.includes('The default website isn\'t defined. Set the website and try again.')
111
+ )
112
+ ) {
113
+ const confirmToWipeEnvPhp = await task.prompt({
114
+ type: 'Confirm',
115
+ message: `We detected that your encryption key in ${logger.style.file('app/etc/env.php')} file is not accepted by Magento installer.
116
+ To fix this issue we will need to ${logger.style.misc('DELETE')} ${logger.style.file('app/etc/env.php')} file. It will be recreated but existing encryption key but if you any custom configuration in it will be lost.
117
+
118
+ Without this you will not be able to install Magento at this moment.
119
+
120
+ Do you want to continue?`
121
+ });
122
+
123
+ if (confirmToWipeEnvPhp) {
124
+ try {
125
+ await fs.promises.unlink(path.join(process.cwd(), 'app', 'etc', 'env.php'));
126
+ } catch (e) {
127
+ throw new UnknownError(`Unexpected error occurred during deleting of app/etc/env.php file!\n\n${e}`);
128
+ }
129
+ ctx.encryptionKey = envPhpData.crypt.key;
130
+
131
+ return task.run(ctx);
132
+ }
133
+ }
134
+ }
135
+
88
136
  if (!installed) {
89
137
  const errorMessages = errors.map((e) => e.message).join('\n\n');
90
138
  throw new UnknownError(`Unable to install Magento!\n${errorMessages}`);
@@ -7,7 +7,7 @@ const KnownError = require('../../../errors/known-error');
7
7
  */
8
8
  const upgradeMagento = () => ({
9
9
  skip: (ctx) => {
10
- if ('isSetupUpgradeNeeded' in ctx) {
10
+ if (ctx.isSetupUpgradeNeeded !== undefined) {
11
11
  return !ctx.isSetupUpgradeNeeded;
12
12
  }
13
13
 
@@ -2,31 +2,57 @@ const mysql = require('mysql2/promise');
2
2
  const UnknownError = require('../../errors/unknown-error');
3
3
  const { execAsyncSpawn } = require('../../util/exec-async-command');
4
4
  const sleep = require('../../util/sleep');
5
+ const { createMagentoDatabase } = require('./create-magento-database');
5
6
 
6
7
  /**
7
- * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
8
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
8
9
  */
9
- const connectToMySQL = () => ({
10
- title: 'Connecting to MySQL server...',
11
- skip: (ctx) => ctx.skipSetup,
10
+ const waitForMySQLInitialization = () => ({
11
+ title: 'Waiting for MySQL to initialize',
12
+ task: async (ctx, task) => {
13
+ const { mysql: { name } } = ctx.config.docker.getContainers();
14
+ let mysqlReadyForConnections = false;
15
+ while (!mysqlReadyForConnections) {
16
+ const mysqlOutput = await execAsyncSpawn(`docker logs ${name}`);
17
+ if (mysqlOutput.includes('ready for connections')) {
18
+ mysqlReadyForConnections = true;
19
+ break;
20
+ } else if (mysqlOutput.includes('Initializing database files')) {
21
+ task.output = `MySQL is initializing database files!
22
+ Please wait, this will take some time and do not restart the MySQL container until initialization is finished!`;
23
+
24
+ let mysqlFinishedInitialization = false;
25
+ while (!mysqlFinishedInitialization) {
26
+ const mysqlOutput = await execAsyncSpawn(`docker logs ${name}`);
27
+ if (mysqlOutput.includes('MySQL init process done.') && !mysqlFinishedInitialization) {
28
+ mysqlFinishedInitialization = true;
29
+ break;
30
+ }
31
+ await sleep(2000);
32
+ }
33
+ }
34
+
35
+ await sleep(2000);
36
+ }
37
+ },
38
+ options: {
39
+ bottomBar: 10
40
+ }
41
+ });
42
+
43
+ /**
44
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
45
+ */
46
+ const gettingMySQLConnection = () => ({
47
+ title: 'Getting MySQL connection',
12
48
  task: async (ctx, task) => {
13
49
  const { config: { docker }, ports } = ctx;
14
- const { mysql: { env, name } } = docker.getContainers();
50
+ const { mysql: { env } } = docker.getContainers();
15
51
  let tries = 0;
16
- let maxTries = 20;
52
+ const maxTries = 20;
17
53
  const errors = [];
18
54
  while (tries < maxTries) {
19
55
  tries++;
20
-
21
- if (maxTries !== 120) {
22
- const mysqlOutput = await execAsyncSpawn(`docker logs ${name}`);
23
- if (mysqlOutput.includes('Initializing database files')) {
24
- maxTries = 120;
25
- task.output = `MySQL is initializing database files!
26
- Please wait, this will take some time and do not restart the MySQL container until initialization is finished!`;
27
- }
28
- await sleep(2000);
29
- }
30
56
  try {
31
57
  const connection = await mysql.createConnection({
32
58
  host: '127.0.0.1',
@@ -49,7 +75,25 @@ Please wait, this will take some time and do not restart the MySQL container unt
49
75
  }
50
76
 
51
77
  task.title = 'MySQL server connected!';
52
- },
78
+ }
79
+ });
80
+
81
+ /**
82
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
83
+ */
84
+ const connectToMySQL = () => ({
85
+ title: 'Connecting to MySQL server',
86
+ skip: (ctx) => ctx.skipSetup,
87
+ task: (ctx, task) => task.newListr([
88
+ waitForMySQLInitialization(),
89
+ createMagentoDatabase(),
90
+ gettingMySQLConnection()
91
+ ], {
92
+ concurrent: false,
93
+ rendererOptions: {
94
+ collapse: true
95
+ }
96
+ }),
53
97
  options: {
54
98
  bottomBar: 10
55
99
  }
@@ -0,0 +1,18 @@
1
+ const { execAsyncSpawn } = require('../../util/exec-async-command');
2
+
3
+ /**
4
+ * Will create database 'magento' in MySQL if it does not exist for some reason
5
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
6
+ */
7
+ const createMagentoDatabase = () => ({
8
+ title: 'Creating Magento database in MySQL',
9
+ task: async (ctx) => {
10
+ const { mysql } = ctx.config.docker.getContainers();
11
+
12
+ await execAsyncSpawn(`docker exec ${mysql.name} mysql -umagento -pmagento -h 127.0.0.1 -e "CREATE DATABASE IF NOT EXISTS magento;"`);
13
+ }
14
+ });
15
+
16
+ module.exports = {
17
+ createMagentoDatabase
18
+ };
@@ -33,7 +33,7 @@ const installSodiumExtension = () => ({
33
33
  const extractedArchivePath = path.join(tempDir, 'libsodium-stable');
34
34
  const enabledExtensions = await getEnabledExtensions(ctx.config);
35
35
 
36
- if ('sodium' in enabledExtensions) {
36
+ if (enabledExtensions.sodium !== undefined) {
37
37
  cmaGlobalConfig.set(HAS_LIBSODIUM_BEEN_INSTALLED, true);
38
38
  task.skip();
39
39
  return;
@@ -17,7 +17,7 @@ const installPHPBrewDependencies = () => ({
17
17
  if (process.platform === 'darwin') {
18
18
  const installedDependencies = (await execAsyncSpawn(`${await getBrewCommand({ native: true })} list`)).split('\n');
19
19
 
20
- const dependenciesToInstall = ['php', 'autoconf', 'pkg-config'].filter((dep) => !installedDependencies.includes(dep));
20
+ const dependenciesToInstall = ['php', 'autoconf', 'pkg-config', 'gd'].filter((dep) => !installedDependencies.includes(dep));
21
21
 
22
22
  if (dependenciesToInstall.length === 0) {
23
23
  task.skip();
@@ -1,9 +1,14 @@
1
1
  const path = require('path');
2
2
  const UnknownError = require('../errors/unknown-error');
3
+ const pathExists = require('./path-exists');
3
4
  const runPhpCode = require('./run-php');
4
5
 
5
6
  const envPhpToJson = async (projectPath = process.cwd(), { magentoVersion }) => {
6
- const { code, result } = await runPhpCode(`-r "echo json_encode(require '${path.join(projectPath, 'app', 'etc', 'env.php')}');"`, {
7
+ const envPhpPath = path.join(projectPath, 'app', 'etc', 'env.php');
8
+ if (!await pathExists(envPhpPath)) {
9
+ return null;
10
+ }
11
+ const { code, result } = await runPhpCode(`-r "echo json_encode(require '${envPhpPath}');"`, {
7
12
  magentoVersion
8
13
  });
9
14
 
@@ -25,16 +25,6 @@ export function execAsyncSpawn (
25
25
  options?: ExecAsyncSpawnOptions<true>
26
26
  ): Promise<{ code: number, result: string }>;
27
27
 
28
- /**
29
- * Execute bash command
30
- * @param command Bash command
31
- * @param options Child process exec options ([docs](https://nodejs.org/dist/latest-v14.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback))
32
- */
33
- export function execAsync(
34
- command: string,
35
- options?: { encoding: BufferEncoding } & ExecOptions
36
- ): Promise<string>
37
-
38
28
  export function execCommandTask(
39
29
  command: string,
40
30
  options?: Omit<ExecAsyncSpawnOptions<false>, 'callback'>
@@ -0,0 +1,10 @@
1
+ /* eslint-disable max-len */
2
+ /**
3
+ * Execute bash command
4
+ * @param command Bash command
5
+ * @param options Child process exec options ([docs](https://nodejs.org/dist/latest-v14.x/docs/api/child_process.html#child_process_child_process_exec_command_options_callback))
6
+ */
7
+ export function execAsync(
8
+ command: string,
9
+ options?: { encoding: BufferEncoding } & ExecOptions
10
+ ): Promise<string>
@@ -1,4 +1,4 @@
1
- const { execAsync } = require('./exec-async-command');
1
+ const { execAsync } = require('./exec-async');
2
2
 
3
3
  const openBrowser = async (url) => {
4
4
  const start = process.platform === 'darwin' ? 'open' : 'xdg-open';
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": "1.15.2",
6
+ "version": "1.15.5",
7
7
  "main": "./index.js",
8
8
  "types": "./typings/index.d.ts",
9
9
  "license": "OSL-3.0",
@@ -53,5 +53,5 @@
53
53
  "mysql",
54
54
  "scandipwa"
55
55
  ],
56
- "gitHead": "6ddbd68e15d1868386f559f7edd6610dbc80a8e4"
56
+ "gitHead": "b90809f36891441aa93a685b69cc3d5e8e922c15"
57
57
  }
@@ -1,46 +0,0 @@
1
- const path = require('path');
2
-
3
- const getPhpStormConfig = (app, config) => {
4
- const [majorPHPVersion, minorPHPVersion] = app.configuration.php.version.split('.');
5
- const phpLanguageLevel = `${ majorPHPVersion }.${ minorPHPVersion }`;
6
- const { templateDir } = config;
7
- const phpStormConfiguration = {
8
- xdebug: {
9
- v2Port: '9111',
10
- v3Port: '9003',
11
- debugServerAddress: `http://${ app.host }`,
12
- serverName: 'create-magento-app',
13
- runManagerName: 'create-magento-app',
14
- sessionId: 'PHPSTORM',
15
- path: path.join(process.cwd(), '.idea', 'workspace.xml'),
16
- templatePath: path.join(templateDir, 'workspace.template.xml')
17
- },
18
- php: {
19
- phpLanguageLevel,
20
- path: path.join(process.cwd(), '.idea', 'php.xml'),
21
- templatePath: path.join(templateDir, 'php.template.xml')
22
- },
23
- database: {
24
- driver: 'mysql',
25
- dataSourceManagerName: 'mysql 8.0',
26
- dataSourcesLocal: {
27
- path: path.join(process.cwd(), '.idea', 'dataSources.local.xml'),
28
- templatePath: path.join(templateDir, 'dataSources.local.template.xml')
29
- },
30
- dataSources: {
31
- path: path.join(process.cwd(), '.idea', 'dataSources.xml'),
32
- templatePath: path.join(templateDir, 'dataSources.template.xml')
33
- }
34
- },
35
- inspectionTools: {
36
- path: path.join(process.cwd(), '.idea', 'inspectionProfiles', 'Project_Default.xml'),
37
- templatePath: path.join(templateDir, 'Project_Default.template.xml')
38
- }
39
- };
40
-
41
- return phpStormConfiguration;
42
- };
43
-
44
- module.exports = {
45
- getPhpStormConfig
46
- };