@scandipwa/magento-scripts 1.16.0-alpha.2 → 1.16.0
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.
- package/lib/config/docker.js +4 -3
- package/lib/config/php/extensions/libsodium.js +2 -4
- package/lib/config/php-config.js +2 -4
- package/lib/tasks/composer/install-prestissimo.js +15 -0
- package/lib/tasks/docker/containers.js +44 -3
- package/lib/tasks/docker/index.js +2 -1
- package/lib/tasks/magento/install-magento-project.js +8 -1
- package/lib/tasks/magento/setup-magento/install-magento.js +41 -2
- package/lib/tasks/magento/setup-magento/migrate-database.js +5 -3
- package/lib/tasks/mysql/connect-to-mysql.js +12 -0
- package/lib/tasks/mysql/import-dump-to-mysql.js +115 -22
- package/lib/tasks/php/compile.js +7 -1
- package/lib/tasks/php/extensions/disable.js +7 -1
- package/lib/tasks/php/extensions/enable.js +7 -1
- package/lib/tasks/php/extensions/index.js +9 -1
- package/lib/tasks/php/extensions/install.js +7 -1
- package/lib/tasks/php/update-phpbrew.js +12 -2
- package/lib/tasks/requirements/index.js +2 -2
- package/lib/tasks/requirements/phpbrew/index.js +7 -1
- package/lib/tasks/requirements/phpbrew/install.js +23 -7
- package/lib/tasks/start.js +1 -1
- package/lib/util/exec-async-command.d.ts +1 -0
- package/lib/util/exec-async-command.js +7 -2
- package/lib/util/get-php-for-phpbrew.js +30 -0
- package/package.json +2 -2
package/lib/config/docker.js
CHANGED
|
@@ -206,9 +206,10 @@ module.exports = async ({ configuration, ssl, host }, config) => {
|
|
|
206
206
|
'--log_bin_trust_function_creators=1',
|
|
207
207
|
'--default-authentication-plugin=mysql_native_password',
|
|
208
208
|
'--max_allowed_packet=1GB',
|
|
209
|
-
'--bind-address=0.0.0.0'
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
'--bind-address=0.0.0.0'
|
|
210
|
+
]
|
|
211
|
+
.concat(!isArm ? ['--secure-file-priv=NULL'] : [])
|
|
212
|
+
.join(' '),
|
|
212
213
|
securityOptions: [
|
|
213
214
|
'seccomp=unconfined'
|
|
214
215
|
],
|
|
@@ -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
|
-
|
|
16
|
-
'.phpbrew',
|
|
17
|
-
'php',
|
|
15
|
+
phpbrewConfig.phpPath,
|
|
18
16
|
`php-${php.version}`,
|
|
19
17
|
'var',
|
|
20
18
|
'db',
|
package/lib/config/php-config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const
|
|
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
|
-
|
|
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,5 +1,8 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
2
|
const { execAsyncSpawn } = require('../../util/exec-async-command');
|
|
3
|
+
const sleep = require('../../util/sleep');
|
|
4
|
+
const logger = require('@scandipwa/scandipwa-dev-utils/logger');
|
|
5
|
+
const KnownError = require('../../errors/known-error');
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* @param {Object} options
|
|
@@ -89,7 +92,8 @@ const pullContainers = () => ({
|
|
|
89
92
|
.join(' ');
|
|
90
93
|
const existingImages = await execAsyncSpawn(`docker images ${containerFilters}`);
|
|
91
94
|
const missingContainerImages = containers.filter((container) => !existingImages.split('\n')
|
|
92
|
-
.some((line) => line.includes(container.imageDetails.name) && line.includes(container.imageDetails.tag)))
|
|
95
|
+
.some((line) => line.includes(container.imageDetails.name) && line.includes(container.imageDetails.tag)))
|
|
96
|
+
.reduce((acc, val) => acc.concat(acc.some((c) => c.imageDetails.name === val.imageDetails.name && c.imageDetails.tag === val.imageDetails.tag) ? [] : val), []);
|
|
93
97
|
|
|
94
98
|
if (missingContainerImages.length === 0) {
|
|
95
99
|
task.skip();
|
|
@@ -98,7 +102,7 @@ const pullContainers = () => ({
|
|
|
98
102
|
|
|
99
103
|
return task.newListr(
|
|
100
104
|
missingContainerImages.map((container) => ({
|
|
101
|
-
title: `Pulling ${container.
|
|
105
|
+
title: `Pulling ${ logger.style.file(`${container.imageDetails.name}:${container.imageDetails.tag}`) } image`,
|
|
102
106
|
task: () => pull(`${container.imageDetails.name}:${container.imageDetails.tag}`)
|
|
103
107
|
})), {
|
|
104
108
|
concurrent: true,
|
|
@@ -162,6 +166,41 @@ const getContainerStatus = async (containerName) => {
|
|
|
162
166
|
}
|
|
163
167
|
};
|
|
164
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
|
+
|
|
165
204
|
/**
|
|
166
205
|
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
167
206
|
*/
|
|
@@ -186,5 +225,7 @@ module.exports = {
|
|
|
186
225
|
startContainers,
|
|
187
226
|
stopContainers,
|
|
188
227
|
pullContainers,
|
|
189
|
-
statusContainers
|
|
228
|
+
statusContainers,
|
|
229
|
+
checkContainersAreRunning,
|
|
230
|
+
getContainerStatus
|
|
190
231
|
};
|
|
@@ -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
|
{
|
|
@@ -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
|
|
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,47 @@ const installMagento = ({ isDbEmpty = false } = {}) => ({
|
|
|
23
23
|
docker,
|
|
24
24
|
magentoConfiguration
|
|
25
25
|
},
|
|
26
|
-
ports
|
|
26
|
+
ports,
|
|
27
|
+
mysqlConnection
|
|
27
28
|
} = ctx;
|
|
29
|
+
|
|
30
|
+
const response = await mysqlConnection.query(
|
|
31
|
+
'select * from admin_user where username=\'admin\';'
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const usersWithUsernameAdmin = response && response.length > 0 && response[0];
|
|
35
|
+
|
|
36
|
+
if (usersWithUsernameAdmin && usersWithUsernameAdmin.length > 0) {
|
|
37
|
+
const confirmDeleteAdminUsers = await task.prompt({
|
|
38
|
+
type: 'Select',
|
|
39
|
+
message: `In order to install Magento in database you will need to delete admin user with username ${logger.style.command('admin')}`,
|
|
40
|
+
choices: [
|
|
41
|
+
{
|
|
42
|
+
name: 'delete-all',
|
|
43
|
+
message: `Delete all admin users (${logger.style.code('Recommended')})`
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'delete-only-admin',
|
|
47
|
+
message: `Delete only admin user with ${logger.style.command('admin')} username`
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await mysqlConnection.query('SET FOREIGN_KEY_CHECKS = 0;');
|
|
53
|
+
|
|
54
|
+
if (confirmDeleteAdminUsers === 'delete-all') {
|
|
55
|
+
await mysqlConnection.query(`
|
|
56
|
+
TRUNCATE TABLE admin_user;
|
|
57
|
+
`);
|
|
58
|
+
} else {
|
|
59
|
+
await mysqlConnection.query(`
|
|
60
|
+
DELETE FROM admin_user WHERE username='admin';
|
|
61
|
+
`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await mysqlConnection.query('SET FOREIGN_KEY_CHECKS = 1;');
|
|
65
|
+
}
|
|
66
|
+
|
|
28
67
|
const { mysql: { env } } = docker.getContainers(ports);
|
|
29
68
|
const envPhpData = await envPhpToJson(process.cwd(), {
|
|
30
69
|
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(),
|
|
@@ -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
|
|
12
|
-
title: '
|
|
12
|
+
const copyDatabaseDumpIntoContainer = () => ({
|
|
13
|
+
title: 'Copying database dump into container',
|
|
13
14
|
task: async (ctx, task) => {
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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;
|
package/lib/tasks/php/compile.js
CHANGED
|
@@ -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
|
-
{
|
|
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: '
|
|
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 (
|
|
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: '
|
|
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
|
|
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 (
|
|
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.`);
|
package/lib/tasks/start.js
CHANGED
|
@@ -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
|
|
6
|
+
"version": "1.16.0",
|
|
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": "
|
|
56
|
+
"gitHead": "c070162301e655d6b768449d641736fbaf0ebe4b"
|
|
57
57
|
}
|