@scandipwa/magento-scripts 1.16.0-alpha.3 → 1.16.1

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.
@@ -1,8 +1,8 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs');
3
- const os = require('os');
4
3
  const pathExists = require('../../../util/path-exists');
5
4
  const UnknownError = require('../../../errors/unknown-error');
5
+ const phpbrewConfig = require('../../phpbrew');
6
6
 
7
7
  /**
8
8
  * @type {import('../../../../typings/index').PHPExtension}
@@ -12,9 +12,7 @@ module.exports = {
12
12
  hooks: {
13
13
  postInstall: async ({ php }) => {
14
14
  const sodiumDynamicLibraryPath = path.join(
15
- os.homedir(),
16
- '.phpbrew',
17
- 'php',
15
+ phpbrewConfig.phpPath,
18
16
  `php-${php.version}`,
19
17
  'var',
20
18
  'db',
@@ -1,5 +1,5 @@
1
1
  const path = require('path');
2
- const os = require('os');
2
+ const phpbrewConfig = require('./phpbrew');
3
3
 
4
4
  module.exports = (app, config) => {
5
5
  const { php } = app;
@@ -7,9 +7,7 @@ module.exports = (app, config) => {
7
7
  const { cacheDir } = config;
8
8
 
9
9
  const phpVersionDir = path.join(
10
- os.homedir(),
11
- '.phpbrew',
12
- 'php',
10
+ phpbrewConfig.phpPath,
13
11
  `php-${ php.version }`
14
12
  );
15
13
 
@@ -46,6 +46,10 @@ Would you like to disable it in your project?`,
46
46
  name: 'disable',
47
47
  message: 'Disable it, thanks'
48
48
  },
49
+ {
50
+ name: 'remove',
51
+ message: `Remove ${prestissimoPluginName} from your system`
52
+ },
49
53
  {
50
54
  name: 'skip',
51
55
  message: 'Skip this step'
@@ -56,6 +60,17 @@ Would you like to disable it in your project?`,
56
60
  if (disableConfirmation === 'disable') {
57
61
  localComposerJsonData.config['allow-plugins'][prestissimoPluginName] = false;
58
62
  await fs.promises.writeFile(localComposerJsonPath, JSON.stringify(localComposerJsonData, null, 4), 'utf-8');
63
+
64
+ return;
65
+ }
66
+
67
+ if (disableConfirmation === 'remove') {
68
+ await runComposerCommand(`global remove ${prestissimoPluginName}`, {
69
+ throwNonZeroCode: false,
70
+ magentoVersion
71
+ });
72
+
73
+ return;
59
74
  }
60
75
  }
61
76
  }
@@ -1,6 +1,8 @@
1
1
  /* eslint-disable max-len */
2
2
  const { execAsyncSpawn } = require('../../util/exec-async-command');
3
+ const sleep = require('../../util/sleep');
3
4
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
5
+ const KnownError = require('../../errors/known-error');
4
6
 
5
7
  /**
6
8
  * @param {Object} options
@@ -164,6 +166,41 @@ const getContainerStatus = async (containerName) => {
164
166
  }
165
167
  };
166
168
 
169
+ /**
170
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
171
+ */
172
+ const checkContainersAreRunning = () => ({
173
+ title: 'Checking container statuses',
174
+ task: async (ctx, task) => {
175
+ const { config: { docker }, ports } = ctx;
176
+ const containers = Object.values(docker.getContainers(ports));
177
+ let tries = 0;
178
+ while (tries < 3) {
179
+ const containersWithStatus = await Promise.all(
180
+ containers.map(async (container) => ({
181
+ ...container,
182
+ status: await getContainerStatus(container.name)
183
+ }))
184
+ );
185
+
186
+ if (containersWithStatus.some((c) => c.status.Status !== 'running')) {
187
+ if (tries === 2) {
188
+ throw new KnownError(`${containersWithStatus.filter((c) => c.status.Status !== 'running').map((c) => c._).join(', ')} containers are not running! Please check container logs for more details!`);
189
+ } else {
190
+ task.output = `${containersWithStatus.filter((c) => c.status.Status !== 'running').map((c) => c._).join(', ')} are not running, waiting if something will change...`;
191
+ await sleep(2000);
192
+ tries++;
193
+ }
194
+ } else {
195
+ break;
196
+ }
197
+ }
198
+ },
199
+ options: {
200
+ bottomBar: 10
201
+ }
202
+ });
203
+
167
204
  /**
168
205
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
169
206
  */
@@ -188,5 +225,7 @@ module.exports = {
188
225
  startContainers,
189
226
  stopContainers,
190
227
  pullContainers,
191
- statusContainers
228
+ statusContainers,
229
+ checkContainersAreRunning,
230
+ getContainerStatus
192
231
  };
@@ -19,7 +19,8 @@ const startServices = () => ({
19
19
  ctx
20
20
  })
21
21
  },
22
- containers.startContainers()
22
+ containers.startContainers(),
23
+ containers.checkContainersAreRunning()
23
24
  ], {
24
25
  concurrent: false,
25
26
  exitOnError: true
@@ -1,4 +1,5 @@
1
1
  const path = require('path');
2
+ const fs = require('fs');
2
3
  const os = require('os');
3
4
  const runComposerCommand = require('../../util/run-composer');
4
5
  const matchFilesystem = require('../../util/match-filesystem');
@@ -128,7 +129,7 @@ const createMagentoProject = async ({
128
129
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
129
130
  */
130
131
  const installMagentoProject = () => ({
131
- title: 'Installing Magento',
132
+ title: 'Installing Magento Project',
132
133
  task: async (ctx, task) => {
133
134
  const { magentoVersion, config: { baseConfig, overridenConfiguration }, verbose } = ctx;
134
135
  const {
@@ -180,6 +181,12 @@ const installMagentoProject = () => ({
180
181
  verbose
181
182
  });
182
183
  }
184
+
185
+ if (!await pathExists(path.join(process.cwd(), 'app', 'etc'))) {
186
+ await fs.promises.mkdir(path.join(process.cwd(), 'app', 'etc'), {
187
+ recursive: true
188
+ });
189
+ }
183
190
  try {
184
191
  await runComposerCommand('install',
185
192
  {
@@ -10,7 +10,6 @@ const setUrlRewrite = require('./set-url-rewrite');
10
10
  const increaseAdminSessionLifetime = require('./increase-admin-session-lifetime');
11
11
  const magentoTask = require('../../../util/magento-task');
12
12
  const urnHighlighter = require('./urn-highlighter');
13
- const waitingForVarnish = require('./waiting-for-varnish');
14
13
  const adjustFullPageCache = require('./adjust-full-page-cache');
15
14
 
16
15
  /**
@@ -50,8 +49,7 @@ const setupMagento = (options = {}) => ({
50
49
  disable2fa(),
51
50
  urnHighlighter(),
52
51
  adjustFullPageCache(),
53
- magentoTask('cache:flush'),
54
- waitingForVarnish()
52
+ magentoTask('cache:flush')
55
53
  ], {
56
54
  concurrent: false,
57
55
  exitOnError: true,
@@ -12,7 +12,7 @@ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
12
12
  * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
13
13
  */
14
14
  const installMagento = ({ isDbEmpty = false } = {}) => ({
15
- title: 'Installing magento',
15
+ title: 'Installing Magento in Database',
16
16
  task: async (ctx, task) => {
17
17
  if (isDbEmpty) {
18
18
  task.output = 'No Magento is installed in DB!\nInstalling...';
@@ -23,8 +23,53 @@ const installMagento = ({ isDbEmpty = false } = {}) => ({
23
23
  docker,
24
24
  magentoConfiguration
25
25
  },
26
- ports
26
+ ports,
27
+ mysqlConnection
27
28
  } = ctx;
29
+
30
+ const [tableResponse] = await mysqlConnection.query(
31
+ 'SELECT * FROM information_schema.tables WHERE table_schema = \'magento\' AND table_name = \'admin_user\' LIMIT 1;'
32
+ );
33
+
34
+ if (tableResponse.length > 0) {
35
+ const response = await mysqlConnection.query(
36
+ 'select * from admin_user where username=\'admin\';'
37
+ );
38
+
39
+ const usersWithUsernameAdmin = response && response.length > 0 && response[0];
40
+
41
+ if (usersWithUsernameAdmin && usersWithUsernameAdmin.length > 0) {
42
+ const confirmDeleteAdminUsers = await task.prompt({
43
+ type: 'Select',
44
+ message: `In order to install Magento in database you will need to delete admin user with username ${logger.style.command('admin')}`,
45
+ choices: [
46
+ {
47
+ name: 'delete-all',
48
+ message: `Delete all admin users (${logger.style.code('Recommended')})`
49
+ },
50
+ {
51
+ name: 'delete-only-admin',
52
+ message: `Delete only admin user with ${logger.style.command('admin')} username`
53
+ }
54
+ ]
55
+ });
56
+
57
+ await mysqlConnection.query('SET FOREIGN_KEY_CHECKS = 0;');
58
+
59
+ if (confirmDeleteAdminUsers === 'delete-all') {
60
+ await mysqlConnection.query(`
61
+ TRUNCATE TABLE admin_user;
62
+ `);
63
+ } else {
64
+ await mysqlConnection.query(`
65
+ DELETE FROM admin_user WHERE username='admin';
66
+ `);
67
+ }
68
+
69
+ await mysqlConnection.query('SET FOREIGN_KEY_CHECKS = 1;');
70
+ }
71
+ }
72
+
28
73
  const { mysql: { env } } = docker.getContainers(ports);
29
74
  const envPhpData = await envPhpToJson(process.cwd(), {
30
75
  magentoVersion: ctx.magentoVersion
@@ -82,13 +82,15 @@ const migrateDatabase = (options = {}) => ({
82
82
  case 1: {
83
83
  if (options.onlyInstallMagento) {
84
84
  ctx.isSetupUpgradeNeeded = false;
85
- return task.newListr(
86
- installMagentoProject()
87
- );
85
+ return task.newListr([
86
+ installMagentoProject(),
87
+ installMagento()
88
+ ]);
88
89
  }
89
90
 
90
91
  return task.newListr([
91
92
  installMagentoProject(),
93
+ installMagento(),
92
94
  updateEnvPHP(),
93
95
  varnishConfigSetup(),
94
96
  configureElasticsearch(),
@@ -6,7 +6,7 @@ const getIsWsl = require('../../../util/is-wsl');
6
6
  * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
7
7
  */
8
8
  const varnishConfigSetup = () => ({
9
- title: 'Varnish setup',
9
+ title: 'Varnish Database setup',
10
10
  task: async (ctx, task) => {
11
11
  const {
12
12
  config: {
@@ -78,6 +78,17 @@ const gettingMySQLConnection = () => ({
78
78
  }
79
79
  });
80
80
 
81
+ /**
82
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
83
+ */
84
+ const terminatingExistingConnection = () => ({
85
+ title: 'Terminating existing MySQL connection',
86
+ skip: (ctx) => !ctx.mysqlConnection,
87
+ task: (ctx) => {
88
+ ctx.mysqlConnection.destroy();
89
+ }
90
+ });
91
+
81
92
  /**
82
93
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
83
94
  */
@@ -87,6 +98,7 @@ const connectToMySQL = () => ({
87
98
  task: (ctx, task) => task.newListr([
88
99
  waitForMySQLInitialization(),
89
100
  createMagentoDatabase(),
101
+ terminatingExistingConnection(),
90
102
  gettingMySQLConnection()
91
103
  ], {
92
104
  concurrent: false,
@@ -2,23 +2,100 @@
2
2
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
3
3
  const KnownError = require('../../errors/known-error');
4
4
  const UnknownError = require('../../errors/unknown-error');
5
- const { execAsyncSpawn } = require('../../util/exec-async-command');
5
+ const { execAsyncSpawn, execCommandTask } = require('../../util/exec-async-command');
6
6
  const pathExists = require('../../util/path-exists');
7
+ const connectToMySQL = require('./connect-to-mysql');
7
8
 
8
9
  /**
9
10
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
10
11
  */
11
- const importDumpToMySQL = () => ({
12
- title: 'Importing Database Dump To MySQL',
12
+ const copyDatabaseDumpIntoContainer = () => ({
13
+ title: 'Copying database dump into container',
13
14
  task: async (ctx, task) => {
14
- if (!await pathExists(ctx.importDb)) {
15
- throw new KnownError(`Dump file at ${ctx.importDb} does not exist. Please provide correct relative path to the file`);
16
- }
15
+ const { config: { docker }, ports } = ctx;
16
+ const { mysql } = docker.getContainers(ports);
17
17
 
18
+ return task.newListr(
19
+ execCommandTask(`docker cp ${ctx.importDb} ${mysql.name}:/dump.sql`, {
20
+ logOutput: true
21
+ })
22
+ );
23
+ }
24
+ });
25
+
26
+ /**
27
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
28
+ */
29
+ const runSetGlobalLogBinTrustFunctionCreatorsCommand = () => ({
30
+ task: async (ctx, task) => {
18
31
  const { config: { docker }, ports } = ctx;
32
+ const { mysql } = docker.getContainers(ports);
19
33
 
34
+ return task.newListr(
35
+ execCommandTask(`docker exec ${mysql.name} bash -c 'mysql -uroot -p${mysql.env.MYSQL_ROOT_PASSWORD} -e "SET GLOBAL log_bin_trust_function_creators = 1;"'`)
36
+ );
37
+ }
38
+ });
39
+
40
+ /**
41
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
42
+ */
43
+ const deleteDatabaseBeforeImportingDumpPrompt = () => ({
44
+ title: 'Deleting magento database before importing dump',
45
+ task: async (ctx, task) => {
46
+ const deleteDatabaseMagentoChoice = await task.prompt({
47
+ type: 'Select',
48
+ message: `Before importing database dump, would you like to delete existing database?
49
+
50
+ It is possible that dump might interfere with existing data in database.
51
+
52
+ Note that you will lose your existing database!`,
53
+ choices: [
54
+ {
55
+ name: 'delete',
56
+ message: 'YES I AM SURE I WANT TO DELETE magento DATABASE!'
57
+ },
58
+ {
59
+ name: 'skip',
60
+ message: 'Skip this step'
61
+ }
62
+ ]
63
+ });
64
+
65
+ if (deleteDatabaseMagentoChoice === 'delete') {
66
+ await ctx.mysqlConnection.query('DROP DATABASE IF EXISTS magento;');
67
+ await ctx.mysqlConnection.query('CREATE DATABASE magento;');
68
+ return;
69
+ }
70
+ task.skip();
71
+ }
72
+ });
73
+
74
+ /**
75
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
76
+ */
77
+ const executeImportDumpSQL = () => ({
78
+ task: async (ctx, task) => {
79
+ const { config: { docker }, ports } = ctx;
20
80
  const { mysql } = docker.getContainers(ports);
21
81
 
82
+ const userCredentialsForMySQLCLI = await task.prompt({
83
+ type: 'Select',
84
+ message: 'Which user do you want to use to import db in MySQL client?',
85
+ choices: [
86
+ {
87
+ name: `--user=root --password=${mysql.env.MYSQL_ROOT_PASSWORD}`,
88
+ message: `root (${logger.style.command('Probably safest option')})`
89
+ },
90
+ {
91
+ name: `--user=${mysql.env.MYSQL_USER} --password=${mysql.env.MYSQL_PASSWORD}`,
92
+ message: `${mysql.env.MYSQL_USER}`
93
+ }
94
+ ]
95
+ });
96
+
97
+ const importCommand = `docker exec ${mysql.name} bash -c "mysql ${userCredentialsForMySQLCLI} magento < ./dump.sql"`;
98
+
22
99
  const startImportTime = Date.now();
23
100
  const tickInterval = setInterval(() => {
24
101
  task.title = `Importing Database Dump To MySQL, ${Math.floor((Date.now() - startImportTime) / 1000)}s in progress...`;
@@ -26,18 +103,7 @@ const importDumpToMySQL = () => ({
26
103
 
27
104
  try {
28
105
  await execAsyncSpawn(
29
- `docker cp ${ctx.importDb} ${mysql.name}:/dump.sql`
30
- );
31
-
32
- await execAsyncSpawn(
33
- `docker exec ${mysql.name} bash -c 'mysql -uroot -p${mysql.env.MYSQL_ROOT_PASSWORD} -e "SET GLOBAL log_bin_trust_function_creators = 1;"'`
34
- );
35
-
36
- /**
37
- * Using `mysql` instead of `mysqlimport` because `mysqlimport` has permission issues during import
38
- */
39
- await execAsyncSpawn(
40
- `docker exec ${mysql.name} bash -c "mysql -umagento -pmagento magento < ./dump.sql"`,
106
+ importCommand,
41
107
  {
42
108
  callback: (t) => {
43
109
  task.output = t;
@@ -54,15 +120,42 @@ You can try replacing all occurrences of ${logger.style.misc('utf8mb4_0900_ai_ci
54
120
  }
55
121
 
56
122
  throw new UnknownError(`Unexpected error during dump import.\n\n${e}`);
123
+ } finally {
124
+ clearInterval(tickInterval);
57
125
  }
58
-
59
- clearInterval(tickInterval);
60
-
61
- task.title = 'Database imported!';
62
126
  },
63
127
  options: {
64
128
  bottomBar: 10
65
129
  }
66
130
  });
67
131
 
132
+ /**
133
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
134
+ */
135
+ const importDumpToMySQL = () => ({
136
+ title: 'Importing Database Dump To MySQL',
137
+ task: async (ctx, task) => {
138
+ if (!await pathExists(ctx.importDb)) {
139
+ throw new KnownError(`Dump file at ${ctx.importDb} does not exist. Please provide correct relative path to the file`);
140
+ }
141
+
142
+ return task.newListr([
143
+ copyDatabaseDumpIntoContainer(),
144
+ deleteDatabaseBeforeImportingDumpPrompt(),
145
+ runSetGlobalLogBinTrustFunctionCreatorsCommand(),
146
+ executeImportDumpSQL(),
147
+ connectToMySQL(),
148
+ {
149
+ task: () => {
150
+ task.title = 'Database imported!';
151
+ }
152
+ }
153
+ ], {
154
+ rendererOptions: {
155
+ collapse: false
156
+ }
157
+ });
158
+ }
159
+ });
160
+
68
161
  module.exports = importDumpToMySQL;
@@ -3,6 +3,7 @@ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
3
3
  const { execAsyncSpawn } = require('../../util/exec-async-command');
4
4
  const compileOptions = require('./compile-options');
5
5
  const UnknownError = require('../../errors/unknown-error');
6
+ const { getPHPForPHPBrewBin } = require('../../util/get-php-for-phpbrew');
6
7
 
7
8
  /**
8
9
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -10,6 +11,7 @@ const UnknownError = require('../../errors/unknown-error');
10
11
  const compilePHP = () => ({
11
12
  title: 'Compiling PHP',
12
13
  task: async ({ config: { php } }, task) => {
14
+ const phpBinForPHPBrew = await getPHPForPHPBrewBin();
13
15
  const platformCompileOptions = compileOptions[process.platform];
14
16
  if (process.platform === 'linux') {
15
17
  const { distro } = await systeminformation.osInfo();
@@ -29,7 +31,11 @@ const compilePHP = () => ({
29
31
  callback: (t) => {
30
32
  task.output = t;
31
33
  },
32
- useRosetta2: true
34
+ useRosetta2: true,
35
+ env: phpBinForPHPBrew ? {
36
+ ...process.env,
37
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
38
+ } : process.env
33
39
  }
34
40
  );
35
41
  } catch (e) {
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable max-len */
2
2
  const phpbrewConfig = require('../../../config/phpbrew');
3
3
  const { execAsyncSpawn } = require('../../../util/exec-async-command');
4
+ const { getPHPForPHPBrewBin } = require('../../../util/get-php-for-phpbrew');
4
5
 
5
6
  /**
6
7
  * @param {String} extensionName
@@ -9,6 +10,7 @@ const { execAsyncSpawn } = require('../../../util/exec-async-command');
9
10
  const disableExtension = (extensionName) => ({
10
11
  title: `Disabling ${extensionName} extension`,
11
12
  task: async (ctx, task) => {
13
+ const phpBinForPHPBrew = await getPHPForPHPBrewBin();
12
14
  const {
13
15
  config,
14
16
  config: { php }
@@ -28,7 +30,11 @@ const disableExtension = (extensionName) => ({
28
30
  callback: (t) => {
29
31
  task.output = t;
30
32
  },
31
- useRosetta2: true
33
+ useRosetta2: true,
34
+ env: phpBinForPHPBrew ? {
35
+ ...process.env,
36
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
37
+ } : process.env
32
38
  });
33
39
  if (hooks && hooks.postDisable) {
34
40
  await Promise.resolve(hooks.postDisable(config));
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable max-len */
2
2
  const phpbrewConfig = require('../../../config/phpbrew');
3
3
  const { execAsyncSpawn } = require('../../../util/exec-async-command');
4
+ const { getPHPForPHPBrewBin } = require('../../../util/get-php-for-phpbrew');
4
5
 
5
6
  /**
6
7
  * @param {String} extensionName
@@ -10,6 +11,7 @@ const { execAsyncSpawn } = require('../../../util/exec-async-command');
10
11
  const enableExtension = (extensionName, extensionOptions) => ({
11
12
  title: `Enabling ${extensionName} extension`,
12
13
  task: async (ctx, task) => {
14
+ const phpBinForPHPBrew = await getPHPForPHPBrewBin();
13
15
  const {
14
16
  config,
15
17
  config: { php }
@@ -30,7 +32,11 @@ const enableExtension = (extensionName, extensionOptions) => ({
30
32
  callback: (t) => {
31
33
  task.output = t;
32
34
  },
33
- useRosetta2: true
35
+ useRosetta2: true,
36
+ env: phpBinForPHPBrew ? {
37
+ ...process.env,
38
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
39
+ } : process.env
34
40
  });
35
41
 
36
42
  if (hooks && hooks.postEnable) {
@@ -4,6 +4,7 @@ const fs = require('fs');
4
4
  const { execAsyncSpawn } = require('../../../util/exec-async-command');
5
5
  const pathExists = require('../../../util/path-exists');
6
6
  const phpbrewConfig = require('../../../config/phpbrew');
7
+ const { getPHPForPHPBrewBin } = require('../../../util/get-php-for-phpbrew');
7
8
 
8
9
  /**
9
10
  * Get enabled extensions list with versions
@@ -11,9 +12,16 @@ const phpbrewConfig = require('../../../config/phpbrew');
11
12
  * @returns {Promise<{[key: string]: string}}>}
12
13
  */
13
14
  const getEnabledExtensions = async ({ php }) => {
15
+ const phpBinForPHPBrew = await getPHPForPHPBrewBin();
14
16
  const output = await execAsyncSpawn(
15
17
  `${ php.binPath } -c ${php.iniPath} -r 'foreach (get_loaded_extensions() as $extension) echo "$extension:" . phpversion($extension) . "\n";'`,
16
- { useRosetta2: true }
18
+ {
19
+ useRosetta2: true,
20
+ env: phpBinForPHPBrew ? {
21
+ ...process.env,
22
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
23
+ } : process.env
24
+ }
17
25
  );
18
26
 
19
27
  return output
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable max-len */
2
2
  const phpbrewConfig = require('../../../config/phpbrew');
3
3
  const { execAsyncSpawn } = require('../../../util/exec-async-command');
4
+ const { getPHPForPHPBrewBin } = require('../../../util/get-php-for-phpbrew');
4
5
 
5
6
  /**
6
7
  * @param {String} extensionName
@@ -10,6 +11,7 @@ const { execAsyncSpawn } = require('../../../util/exec-async-command');
10
11
  const installExtension = (extensionName, extensionOptions) => ({
11
12
  title: `Installing ${extensionName} extension`,
12
13
  task: async (ctx, task) => {
14
+ const phpBinForPHPBrew = await getPHPForPHPBrewBin();
13
15
  const {
14
16
  config,
15
17
  config: { php }
@@ -32,7 +34,11 @@ const installExtension = (extensionName, extensionOptions) => ({
32
34
  callback: (t) => {
33
35
  task.output = t;
34
36
  },
35
- useRosetta2: true
37
+ useRosetta2: true,
38
+ env: phpBinForPHPBrew ? {
39
+ ...process.env,
40
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
41
+ } : process.env
36
42
  });
37
43
 
38
44
  if (hooks && hooks.postInstall) {
@@ -1,5 +1,6 @@
1
1
  const UnknownError = require('../../errors/unknown-error');
2
2
  const { execAsyncSpawn } = require('../../util/exec-async-command');
3
+ const { getPHPForPHPBrewBin } = require('../../util/get-php-for-phpbrew');
3
4
 
4
5
  /**
5
6
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -7,9 +8,14 @@ const { execAsyncSpawn } = require('../../util/exec-async-command');
7
8
  const updatePhpBrew = () => ({
8
9
  title: 'Updating PHPBrew PHP versions',
9
10
  task: async ({ config: { php } }, task) => {
11
+ const phpBinForPHPBrew = await getPHPForPHPBrewBin();
10
12
  try {
11
13
  const knownPhpVersions = await execAsyncSpawn('phpbrew known', {
12
- useRosetta2: true
14
+ useRosetta2: true,
15
+ env: phpBinForPHPBrew ? {
16
+ ...process.env,
17
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
18
+ } : process.env
13
19
  });
14
20
 
15
21
  if (knownPhpVersions.includes(`${php.version}`)) {
@@ -21,7 +27,11 @@ const updatePhpBrew = () => ({
21
27
  callback: (t) => {
22
28
  task.output = t;
23
29
  },
24
- useRosetta2: true
30
+ useRosetta2: true,
31
+ env: phpBinForPHPBrew ? {
32
+ ...process.env,
33
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
34
+ } : process.env
25
35
  });
26
36
  } catch (e) {
27
37
  throw new UnknownError(`Unexpected error while updating phpbrew known php versions\n\n${e}`);
@@ -12,10 +12,10 @@ const checkRosetta = require('./rosetta');
12
12
  const checkRequirements = () => ({
13
13
  title: 'Checking requirements',
14
14
  task: (ctx, task) => task.newListr([
15
- // checking if user is on supported platform
16
- checkPlatform(),
17
15
  // check if rosetta 2 is installed or not on m1 macs
18
16
  checkRosetta(),
17
+ // checking if user is on supported platform
18
+ checkPlatform(),
19
19
  // check the Docker installation
20
20
  checkDocker(),
21
21
  // check for Node.js version
@@ -1,6 +1,7 @@
1
1
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
2
2
  const KnownError = require('../../../errors/known-error');
3
3
  const { execAsyncSpawn } = require('../../../util/exec-async-command');
4
+ const { getPHPForPHPBrewBin } = require('../../../util/get-php-for-phpbrew');
4
5
  const installPHPBrew = require('./install');
5
6
  const getPHPBrewVersion = require('./version');
6
7
 
@@ -10,8 +11,13 @@ const getPHPBrewVersion = require('./version');
10
11
  const checkPHPBrew = () => ({
11
12
  title: 'Checking phpbrew',
12
13
  task: async (ctx, task) => {
14
+ const phpBinForPHPBrew = await getPHPForPHPBrewBin();
13
15
  const { code } = await execAsyncSpawn('phpbrew --version', {
14
- withCode: true
16
+ withCode: true,
17
+ env: phpBinForPHPBrew ? {
18
+ ...process.env,
19
+ PATH: `${phpBinForPHPBrew}:${process.env.PATH}`
20
+ } : process.env
15
21
  });
16
22
 
17
23
  if (code !== 0) {
@@ -68,7 +68,6 @@ const installPHPBrewBinary = () => ({
68
68
  bottomBar: 10
69
69
  }
70
70
  });
71
-
72
71
  /**
73
72
  * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
74
73
  */
@@ -79,12 +78,19 @@ const addPHPBrewInitiatorLineToConfigFile = () => ({
79
78
  const shellConfigFileName = `.${shellName}rc`;
80
79
 
81
80
  const addLineToShellConfigFIle = await task.prompt({
82
- type: 'Confirm',
81
+ type: 'Select',
83
82
  message: `To finish configuring PHPBrew we need to add ${logger.style.code('[[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc')} line to your ${ shellConfigFileName } file.
84
- Do you want to do it now?`
83
+ Do you want to do it now?`,
84
+ choices: [{
85
+ name: 'yes',
86
+ message: 'Yeah, thanks'
87
+ }, {
88
+ name: 'no',
89
+ message: 'No, I will deal with this myself'
90
+ }]
85
91
  });
86
92
 
87
- if (!addLineToShellConfigFIle) {
93
+ if (addLineToShellConfigFIle === 'no') {
88
94
  task.skip();
89
95
  return;
90
96
  }
@@ -101,16 +107,26 @@ Do you want to do it now?`
101
107
  );
102
108
  } else {
103
109
  const continueInstall = await task.prompt({
104
- type: 'Confirm',
110
+ type: 'Select',
105
111
  message: `Unfortunately we cannot automatically add necessary configuration for your shell ${process.env.SHELL}!
106
112
  You will need to that manually!
107
113
 
108
114
  Add following string to your shells configuration file: ${logger.style.code('[[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc')}
109
115
 
110
- When you ready, press select Yes and installation will continue.`
116
+ When you ready, press Enter and installation will continue.`,
117
+ choices: [
118
+ {
119
+ name: 'yes',
120
+ message: 'YES'
121
+ },
122
+ {
123
+ name: 'no',
124
+ message: 'Exit installation'
125
+ }
126
+ ]
111
127
  });
112
128
 
113
- if (!continueInstall) {
129
+ if (continueInstall === 'no') {
114
130
  throw new KnownError(`Add following string to your shells configuration file: ${logger.style.code('[[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc')}
115
131
 
116
132
  Then you can continue installation.`);
@@ -32,6 +32,7 @@ const checkForXDGOpen = require('../util/xdg-open-exists');
32
32
  const { getInstanceMetadata, constants: { WEB_LOCATION_TITLE } } = require('../util/instance-metadata');
33
33
  const validatePHPInstallation = require('./php/validate-php');
34
34
  const installSodiumExtension = require('./php/install-sodium');
35
+ const waitingForVarnish = require('./magento/setup-magento/waiting-for-varnish');
35
36
 
36
37
  /**
37
38
  * @type {() => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
@@ -120,8 +121,8 @@ const configureProject = () => ({
120
121
  installPrestissimo(),
121
122
  installMagentoProject(),
122
123
  enableMagentoComposerPlugins(),
123
- startServices(),
124
124
  startPhpFpm(),
125
+ startServices(),
125
126
  connectToMySQL()
126
127
  ])
127
128
  });
@@ -149,7 +150,8 @@ const finishProjectConfiguration = () => ({
149
150
  });
150
151
  }
151
152
  },
152
- setupThemes()
153
+ setupThemes(),
154
+ waitingForVarnish()
153
155
  ], {
154
156
  rendererOptions: {
155
157
  collapse: false
@@ -11,6 +11,7 @@ interface ExecAsyncSpawnOptions<T extends boolean> {
11
11
  withCode?: T
12
12
  // only for mac
13
13
  useRosetta2?: boolean
14
+ env: NodeJS.ProcessEnv
14
15
  }
15
16
 
16
17
  /**
@@ -10,11 +10,16 @@ const execAsyncSpawn = (command, {
10
10
  logOutput = false,
11
11
  cwd,
12
12
  withCode = false,
13
- useRosetta2 = false
13
+ useRosetta2 = false,
14
+ env = process.env
14
15
  } = {}) => {
16
+ /**
17
+ * @type {import('child_process').SpawnOptionsWithoutStdio}
18
+ */
15
19
  const spawnOptions = {
16
20
  stdio: pipeInput ? ['inherit', 'pipe', 'pipe'] : 'pipe',
17
- cwd
21
+ cwd,
22
+ env
18
23
  };
19
24
 
20
25
  /**
@@ -0,0 +1,30 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const phpbrewConfig = require('../config/phpbrew');
4
+ const pathExists = require('./path-exists');
5
+
6
+ const getPHPForPHPBrewBin = async () => {
7
+ if (!await pathExists(phpbrewConfig.phpPath)) {
8
+ return '';
9
+ }
10
+
11
+ const buildedPHPs = await fs.promises.readdir(phpbrewConfig.phpPath, {
12
+ encoding: 'utf-8',
13
+ withFileTypes: true
14
+ });
15
+
16
+ const phpForPHPBrew = buildedPHPs.find((p) => p.isDirectory() && p.name.endsWith('phpbrew'));
17
+
18
+ if (phpForPHPBrew) {
19
+ const phpBinPath = path.join(phpbrewConfig.phpPath, phpForPHPBrew.name, 'bin');
20
+ if (await pathExists(phpBinPath)) {
21
+ return phpBinPath;
22
+ }
23
+ }
24
+
25
+ return '';
26
+ };
27
+
28
+ module.exports = {
29
+ getPHPForPHPBrewBin
30
+ };
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.16.0-alpha.3",
6
+ "version": "1.16.1",
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": "1801104ed104a124f8d08cc81008d21b792857e4"
56
+ "gitHead": "ced1b75c1b448ef198a658edf010f53179aaaeb0"
57
57
  }