@scandipwa/magento-scripts 1.16.0-alpha.4 → 2.0.0-alpha.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/commands/cli.js +2 -4
- package/lib/commands/execute.js +28 -3
- package/lib/commands/start.js +37 -15
- package/lib/commands/status.js +2 -0
- package/lib/config/docker.js +65 -42
- package/lib/config/get-project-configuration.js +3 -1
- package/lib/config/index.js +10 -7
- package/lib/config/magento/required-php-extensions/index.js +29 -0
- package/lib/config/magento/required-php-extensions/magento-2.3.js +19 -0
- package/lib/config/magento/required-php-extensions/magento-2.4.js +29 -0
- package/lib/config/php/base-repo.js +3 -0
- package/lib/config/php/extensions/apcu.js +12 -0
- package/lib/config/php/extensions/bcmath.js +7 -0
- package/lib/config/php/extensions/curl.js +11 -0
- package/lib/config/php/extensions/gd.js +14 -0
- package/lib/config/php/extensions/index.js +18 -2
- package/lib/config/php/extensions/intl.js +10 -0
- package/lib/config/php/extensions/opcache.js +10 -0
- package/lib/config/php/extensions/pdo_mysql.js +7 -0
- package/lib/config/php/extensions/soap.js +10 -0
- package/lib/config/php/extensions/sodium.js +10 -0
- package/lib/config/php/extensions/xdebug.js +8 -5
- package/lib/config/php/extensions/xsl.js +10 -0
- package/lib/config/php/extensions/zip.js +10 -0
- package/lib/config/php/{releases → versions}/index.js +0 -0
- package/lib/config/php/versions/php-7.2.js +23 -0
- package/lib/config/php/versions/php-7.3.js +23 -0
- package/lib/config/php/versions/php-7.4.js +23 -0
- package/lib/config/php/versions/php-8.1.js +23 -0
- package/lib/config/php-config.js +8 -12
- package/lib/config/port-config.js +1 -5
- package/lib/config/templates/magentorc.template +3 -3
- package/lib/config/templates/php-fpm.template.conf +3 -3
- package/lib/config/templates/php.template.ini +12 -6
- package/lib/config/templates/ssl-terminator.template.conf +1 -1
- package/lib/config/templates/vscode-launch.template.json +3 -1
- package/lib/config/versions/magento-2.3.0.js +8 -2
- package/lib/config/versions/magento-2.3.1.js +8 -2
- package/lib/config/versions/magento-2.3.2-p1.js +44 -0
- package/lib/config/versions/magento-2.3.2-p2.js +8 -2
- package/lib/config/versions/magento-2.3.2.js +8 -2
- package/lib/config/versions/magento-2.3.3-p1.js +8 -2
- package/lib/config/versions/magento-2.3.3.js +8 -2
- package/lib/config/versions/magento-2.3.4-p1.js +44 -0
- package/lib/config/versions/magento-2.3.4-p2.js +8 -2
- package/lib/config/versions/magento-2.3.4.js +8 -2
- package/lib/config/versions/magento-2.3.5-p1.js +8 -2
- package/lib/config/versions/magento-2.3.5-p2.js +8 -2
- package/lib/config/versions/magento-2.3.5.js +8 -2
- package/lib/config/versions/magento-2.3.6-p1.js +8 -2
- package/lib/config/versions/magento-2.3.6.js +8 -2
- package/lib/config/versions/magento-2.3.7-p1.js +8 -2
- package/lib/config/versions/magento-2.3.7-p2.js +8 -2
- package/lib/config/versions/magento-2.3.7-p3.js +8 -2
- package/lib/config/versions/magento-2.3.7.js +8 -2
- package/lib/config/versions/magento-2.4.0-p1.js +9 -3
- package/lib/config/versions/magento-2.4.0.js +9 -3
- package/lib/config/versions/magento-2.4.1-p1.js +6 -5
- package/lib/config/versions/magento-2.4.1.js +9 -2
- package/lib/config/versions/magento-2.4.2-p1.js +6 -5
- package/lib/config/versions/magento-2.4.2-p2.js +6 -6
- package/lib/config/versions/magento-2.4.2.js +6 -6
- package/lib/config/versions/magento-2.4.3-p1.js +7 -7
- package/lib/config/versions/magento-2.4.3-p2.js +7 -7
- package/lib/config/versions/magento-2.4.3.js +7 -7
- package/lib/config/versions/magento-2.4.4.js +9 -2
- package/lib/tasks/cleanup.js +2 -2
- package/lib/tasks/composer/index.js +14 -104
- package/lib/tasks/docker/api.d.ts +71 -0
- package/lib/tasks/docker/api.js +30 -0
- package/lib/tasks/docker/containers/container-api.d.ts +128 -0
- package/lib/tasks/docker/containers/container-api.js +153 -0
- package/lib/tasks/docker/containers/index.js +19 -0
- package/lib/tasks/docker/containers/tasks.js +215 -0
- package/lib/tasks/docker/convert-legacy-volumes.js +7 -3
- package/lib/tasks/docker/image/image-api.d.ts +34 -0
- package/lib/tasks/docker/image/image-api.js +49 -0
- package/lib/tasks/docker/image/index.js +5 -0
- package/lib/tasks/docker/index.js +1 -13
- package/lib/tasks/docker/network/index.js +7 -0
- package/lib/tasks/docker/network/network-api.d.ts +103 -0
- package/lib/tasks/docker/network/network-api.js +99 -0
- package/lib/tasks/docker/{network.js → network/tasks.js} +17 -10
- package/lib/tasks/docker/project-image-builder.js +167 -0
- package/lib/tasks/docker/volumes.js +1 -1
- package/lib/tasks/file-system/create-nginx-config.js +2 -3
- package/lib/tasks/file-system/create-php-config.js +20 -5
- package/lib/tasks/file-system/create-php-fpm-config.js +8 -4
- package/lib/tasks/file-system/create-phpstorm-config/exclude-folder-config.js +41 -29
- package/lib/tasks/file-system/create-phpstorm-config/index.js +2 -0
- package/lib/tasks/file-system/create-phpstorm-config/keys.js +15 -1
- package/lib/tasks/file-system/create-phpstorm-config/php-config/index.js +4 -1
- package/lib/tasks/file-system/create-phpstorm-config/php-config/php-config.js +3 -3
- package/lib/tasks/file-system/create-phpstorm-config/php-config/php-interpreters-config.js +81 -0
- package/lib/tasks/file-system/create-phpstorm-config/php-docker-settings-config/index.js +42 -0
- package/lib/tasks/file-system/create-phpstorm-config/php-docker-settings-config/php-docker-settings-config.js +9 -0
- package/lib/tasks/file-system/create-phpstorm-config/php-docker-settings-config/setup-php-docker-container-settings-config.js +66 -0
- package/lib/tasks/file-system/create-phpstorm-config/setup-xml-structure.js +11 -9
- package/lib/tasks/file-system/create-phpstorm-config/stylelint-config.js +2 -1
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/composer-settings-config.js +15 -30
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/index.js +24 -5
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/mess-detector-project-configuration-config.js +50 -0
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-code-sniffer-project-configuration-config.js +50 -0
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-cs-fixer-project-configuration-config.js +50 -0
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-debug-general-config.js +15 -15
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-server-config.js +29 -3
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-stan-project-configuration-config.js.js +50 -0
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-workspace-project-configuration-config.js +42 -0
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/psalm-project-configuration-config.js.js +50 -0
- package/lib/tasks/file-system/create-phpstorm-config/workspace-config/workspace-config.js +0 -2
- package/lib/tasks/file-system/create-ssl-terminator-config.js +4 -2
- package/lib/tasks/file-system/create-vscode-config.js +57 -42
- package/lib/tasks/file-system/index.js +2 -1
- package/lib/tasks/link.js +1 -2
- package/lib/tasks/magento/install-magento-project.js +39 -64
- package/lib/tasks/magento/setup-magento/adjust-full-page-cache.js +4 -4
- package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +6 -2
- package/lib/tasks/magento/setup-magento/create-admin.js +5 -6
- package/lib/tasks/magento/setup-magento/disable-2fa.js +3 -5
- package/lib/tasks/magento/setup-magento/disable-maintenance-mode.js +3 -4
- package/lib/tasks/magento/setup-magento/index.js +1 -3
- package/lib/tasks/magento/setup-magento/install-magento.js +57 -11
- package/lib/tasks/magento/setup-magento/migrate-database.js +12 -11
- package/lib/tasks/magento/setup-magento/set-deployment-mode.js +4 -4
- package/lib/tasks/magento/setup-magento/varnish-config.js +7 -5
- package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +128 -3
- package/lib/tasks/mysql/connect-to-mysql.js +44 -19
- package/lib/tasks/mysql/import-dump-to-mysql.js +161 -25
- package/lib/tasks/php/php-container.js +108 -0
- package/lib/tasks/php/update-env-php.js +35 -19
- package/lib/tasks/php/update-env.php +61 -56
- package/lib/tasks/php/working_health_check.php +85 -0
- package/lib/tasks/requirements/{composer.js → composer-credentials.js} +3 -1
- package/lib/tasks/requirements/docker/index.js +15 -12
- package/lib/tasks/requirements/docker/performance.js +54 -0
- package/lib/tasks/requirements/docker/version.js +8 -8
- package/lib/tasks/requirements/index.js +7 -10
- package/lib/tasks/requirements/php-version.js +8 -116
- package/lib/tasks/requirements/platform.js +12 -25
- package/lib/tasks/start.js +41 -48
- package/lib/tasks/status/index.js +4 -10
- package/lib/tasks/stop.js +0 -2
- package/lib/tasks/theme/install-theme.js +1 -1
- package/lib/tasks/theme/symlink-theme.js +2 -3
- package/lib/util/config-php-json.js +13 -4
- package/lib/util/dockerfile-builder/build-instructions.js +197 -0
- package/lib/util/dockerfile-builder/index.js +276 -0
- package/lib/util/dockerfile-builder/types.d.ts +123 -0
- package/lib/util/env-php-json.js +10 -6
- package/lib/util/exec-async-command.js +3 -9
- package/lib/util/macos-version.js +20 -0
- package/lib/util/magento-task.js +3 -4
- package/lib/util/nginx-logs-parser.js +122 -0
- package/lib/util/php-task.js +3 -6
- package/lib/util/prefix.js +1 -1
- package/lib/util/run-composer.js +6 -14
- package/lib/util/run-container-image.js +17 -0
- package/lib/util/run-magento.js +6 -14
- package/lib/util/run-php.js +6 -17
- package/package.json +9 -9
- package/typings/context.d.ts +3 -9
- package/typings/index.d.ts +38 -57
- package/lib/config/composer.js +0 -11
- package/lib/config/php/extensions/libsodium.js +0 -36
- package/lib/config/php/releases/php-7.2.js +0 -25
- package/lib/config/php/releases/php-7.3.js +0 -25
- package/lib/config/php/releases/php-7.4.js +0 -23
- package/lib/config/php/releases/php-8.1.js +0 -25
- package/lib/config/phpbrew.js +0 -12
- package/lib/tasks/composer/install-prestissimo.js +0 -88
- package/lib/tasks/docker/containers.js +0 -231
- package/lib/tasks/php/bundled-extensions.js +0 -27
- package/lib/tasks/php/compile-options.js +0 -56
- package/lib/tasks/php/compile.js +0 -55
- package/lib/tasks/php/configure.js +0 -89
- package/lib/tasks/php/extensions/disable.js +0 -49
- package/lib/tasks/php/extensions/enable.js +0 -52
- package/lib/tasks/php/extensions/index.js +0 -80
- package/lib/tasks/php/extensions/install.js +0 -54
- package/lib/tasks/php/index.js +0 -79
- package/lib/tasks/php/install-sodium.js +0 -93
- package/lib/tasks/php/update-phpbrew.js +0 -45
- package/lib/tasks/php/validate-php.js +0 -67
- package/lib/tasks/php-fpm/get-process-id.js +0 -14
- package/lib/tasks/php-fpm/index.js +0 -4
- package/lib/tasks/php-fpm/start-php-fpm.js +0 -49
- package/lib/tasks/php-fpm/stop-php-fpm.js +0 -48
- package/lib/tasks/requirements/phpbrew/index.js +0 -61
- package/lib/tasks/requirements/phpbrew/install.js +0 -159
- package/lib/tasks/requirements/phpbrew/version.js +0 -28
|
@@ -1,14 +1,48 @@
|
|
|
1
|
+
const logger = require('@scandipwa/scandipwa-dev-utils/logger');
|
|
2
|
+
const semver = require('semver');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
1
5
|
const { request } = require('smol-request');
|
|
2
6
|
const KnownError = require('../../../errors/known-error');
|
|
7
|
+
const { execAsyncSpawn } = require('../../../util/exec-async-command');
|
|
8
|
+
const { NginxParser } = require('../../../util/nginx-logs-parser');
|
|
3
9
|
const sleep = require('../../../util/sleep');
|
|
4
10
|
|
|
11
|
+
const pathToWorkingHealthCheckPhp = path.join(__dirname, '..', '..', 'php', 'working_health_check.php');
|
|
12
|
+
const pathToProjectsHealthCheckPhp = path.join(process.cwd(), 'pub', 'health_check.php');
|
|
13
|
+
const pathToHealthCheckBackupPhp = path.join(process.cwd(), 'pub', 'health_check-super-backup-file.php');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {import('../../../../typings/context').ListrContext} ctx
|
|
17
|
+
*/
|
|
18
|
+
const getIsHealthCheckRequestBroken = async (ctx) => {
|
|
19
|
+
const { nginx } = ctx.config.docker.getContainers(ctx.ports);
|
|
20
|
+
|
|
21
|
+
const nginxLogs = await execAsyncSpawn(`docker logs ${nginx.name}`);
|
|
22
|
+
|
|
23
|
+
const healthCheckRequests = nginxLogs
|
|
24
|
+
.split('\n')
|
|
25
|
+
.filter((line) => line.includes('"GET /health_check.php HTTP/1.1"'));
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line max-len
|
|
28
|
+
const parser = new NginxParser('$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"');
|
|
29
|
+
|
|
30
|
+
const parsedRequests = healthCheckRequests.map((line) => parser.parseLine(line));
|
|
31
|
+
|
|
32
|
+
return parsedRequests.every((parsedRequest) => parsedRequest.status !== '200');
|
|
33
|
+
};
|
|
34
|
+
|
|
5
35
|
/**
|
|
6
36
|
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
7
37
|
*/
|
|
8
38
|
const waitingForVarnish = () => ({
|
|
9
39
|
title: 'Waiting for Varnish to return code 200',
|
|
10
|
-
skip: (ctx) => !ctx.config.overridenConfiguration.configuration.varnish.enabled,
|
|
11
|
-
task: async (ctx) => {
|
|
40
|
+
skip: (ctx) => ctx.debug || !ctx.config.overridenConfiguration.configuration.varnish.enabled,
|
|
41
|
+
task: async (ctx, task) => {
|
|
42
|
+
const pureMagentoVersion = ctx.magentoVersion.match(/^([0-9]+\.[0-9]+\.[0-9]+)/)[1];
|
|
43
|
+
|
|
44
|
+
const isMagento23 = semver.satisfies(pureMagentoVersion, '<2.4');
|
|
45
|
+
|
|
12
46
|
let tries = 0;
|
|
13
47
|
while (tries < 10) {
|
|
14
48
|
try {
|
|
@@ -28,6 +62,94 @@ const waitingForVarnish = () => ({
|
|
|
28
62
|
}
|
|
29
63
|
}
|
|
30
64
|
|
|
65
|
+
if (tries === 10 && isMagento23) {
|
|
66
|
+
const isHealthCheckRequestBroken = await getIsHealthCheckRequestBroken(ctx);
|
|
67
|
+
if (isHealthCheckRequestBroken) {
|
|
68
|
+
const confirm = await task.prompt({
|
|
69
|
+
type: 'Select',
|
|
70
|
+
message: `We detected that your Magento instance is experiencing problems with Varnish server.
|
|
71
|
+
Health Check request is returning status 500.
|
|
72
|
+
|
|
73
|
+
Do you want to try resolving this issue by replacing ${logger.style.file('./pub/health_check.php')} file content with content from newer Magento version (2.4.4)?`,
|
|
74
|
+
choices: [
|
|
75
|
+
{
|
|
76
|
+
name: 'yes',
|
|
77
|
+
message: 'Okay, let\'s try that'
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'no',
|
|
81
|
+
message: 'I will try to fix this myself, thanks for the info!'
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (confirm === 'yes') {
|
|
87
|
+
await fs.promises.writeFile(
|
|
88
|
+
pathToHealthCheckBackupPhp,
|
|
89
|
+
await fs.promises.readFile(pathToProjectsHealthCheckPhp, 'utf-8'),
|
|
90
|
+
'utf-8'
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
task.output = `Backup made! Available at ${logger.style.file(pathToHealthCheckBackupPhp)}`;
|
|
94
|
+
|
|
95
|
+
await fs.promises.writeFile(
|
|
96
|
+
pathToProjectsHealthCheckPhp,
|
|
97
|
+
await fs.promises.readFile(pathToWorkingHealthCheckPhp, 'utf-8'),
|
|
98
|
+
'utf-8'
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
task.output = `${logger.style.file('./pub/health_check.php')} content is replaced, waiting for nginx logs...`;
|
|
102
|
+
|
|
103
|
+
let connectionFixed = false;
|
|
104
|
+
|
|
105
|
+
for (let i = 0; i < 10; i++) {
|
|
106
|
+
try {
|
|
107
|
+
const response = await request(`http://localhost:${ctx.ports.sslTerminator}/`, {
|
|
108
|
+
responseType: 'headers'
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (response.status !== 200) {
|
|
112
|
+
await sleep(2000);
|
|
113
|
+
} else {
|
|
114
|
+
connectionFixed = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
} catch (e) {
|
|
118
|
+
await sleep(200);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (connectionFixed) {
|
|
123
|
+
task.output = 'Connection looks good!';
|
|
124
|
+
const secondConfirm = await task.prompt({
|
|
125
|
+
type: 'Select',
|
|
126
|
+
message: `Okay, looks like it helped!
|
|
127
|
+
Do you want to keep backed up ${logger.style.file('health_check.php')} file?`,
|
|
128
|
+
choices: [
|
|
129
|
+
{
|
|
130
|
+
name: 'no',
|
|
131
|
+
message: 'I don\'t think I will need it anymore, thanks'
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'yes',
|
|
135
|
+
message: 'I will keep it, maybe it will be useful (X to doubt)'
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (secondConfirm === 'no') {
|
|
141
|
+
await fs.promises.rm(pathToHealthCheckBackupPhp);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
task.skip('User choose to fix issue himself');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
31
153
|
if (tries === 10) {
|
|
32
154
|
throw new KnownError(`After 20 seconds website is still responding with non-200 code, which might indicate issue with setup.
|
|
33
155
|
Or Varnish is still loading...
|
|
@@ -35,7 +157,10 @@ Or Varnish is still loading...
|
|
|
35
157
|
Please check the logs!`);
|
|
36
158
|
}
|
|
37
159
|
},
|
|
38
|
-
exitOnError: false
|
|
160
|
+
exitOnError: false,
|
|
161
|
+
options: {
|
|
162
|
+
bottomBar: 10
|
|
163
|
+
}
|
|
39
164
|
});
|
|
40
165
|
|
|
41
166
|
module.exports = waitingForVarnish;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const mysql2 = 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');
|
|
@@ -10,10 +10,14 @@ const { createMagentoDatabase } = require('./create-magento-database');
|
|
|
10
10
|
const waitForMySQLInitialization = () => ({
|
|
11
11
|
title: 'Waiting for MySQL to initialize',
|
|
12
12
|
task: async (ctx, task) => {
|
|
13
|
-
const { mysql
|
|
13
|
+
const { mysql } = ctx.config.docker.getContainers();
|
|
14
|
+
|
|
15
|
+
task.title = `Waiting for ${mysql._} to initialize`;
|
|
16
|
+
|
|
14
17
|
let mysqlReadyForConnections = false;
|
|
18
|
+
|
|
15
19
|
while (!mysqlReadyForConnections) {
|
|
16
|
-
const mysqlOutput = await execAsyncSpawn(`docker logs ${name}`);
|
|
20
|
+
const mysqlOutput = await execAsyncSpawn(`docker logs ${mysql.name}`);
|
|
17
21
|
if (mysqlOutput.includes('ready for connections')) {
|
|
18
22
|
mysqlReadyForConnections = true;
|
|
19
23
|
break;
|
|
@@ -23,7 +27,7 @@ Please wait, this will take some time and do not restart the MySQL container unt
|
|
|
23
27
|
|
|
24
28
|
let mysqlFinishedInitialization = false;
|
|
25
29
|
while (!mysqlFinishedInitialization) {
|
|
26
|
-
const mysqlOutput = await execAsyncSpawn(`docker logs ${name}`);
|
|
30
|
+
const mysqlOutput = await execAsyncSpawn(`docker logs ${mysql.name}`);
|
|
27
31
|
if (mysqlOutput.includes('init process done.') && !mysqlFinishedInitialization) {
|
|
28
32
|
mysqlFinishedInitialization = true;
|
|
29
33
|
break;
|
|
@@ -47,19 +51,22 @@ const gettingMySQLConnection = () => ({
|
|
|
47
51
|
title: 'Getting MySQL connection',
|
|
48
52
|
task: async (ctx, task) => {
|
|
49
53
|
const { config: { docker }, ports } = ctx;
|
|
50
|
-
const { mysql
|
|
54
|
+
const { mysql } = docker.getContainers(ctx.ports);
|
|
51
55
|
let tries = 0;
|
|
52
56
|
const maxTries = 20;
|
|
53
57
|
const errors = [];
|
|
58
|
+
|
|
59
|
+
task.title = `Getting ${mysql._} connection`;
|
|
60
|
+
|
|
54
61
|
while (tries < maxTries) {
|
|
55
62
|
tries++;
|
|
56
63
|
try {
|
|
57
|
-
const connection = await
|
|
64
|
+
const connection = await mysql2.createConnection({
|
|
58
65
|
host: '127.0.0.1',
|
|
59
66
|
port: ports.mysql,
|
|
60
|
-
user: env.MYSQL_USER,
|
|
61
|
-
password: env.MYSQL_PASSWORD,
|
|
62
|
-
database: env.MYSQL_DATABASE
|
|
67
|
+
user: mysql.env.MYSQL_USER,
|
|
68
|
+
password: mysql.env.MYSQL_PASSWORD,
|
|
69
|
+
database: mysql.env.MYSQL_DATABASE
|
|
63
70
|
});
|
|
64
71
|
|
|
65
72
|
ctx.mysqlConnection = connection;
|
|
@@ -78,22 +85,40 @@ const gettingMySQLConnection = () => ({
|
|
|
78
85
|
}
|
|
79
86
|
});
|
|
80
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
90
|
+
*/
|
|
91
|
+
const terminatingExistingConnection = () => ({
|
|
92
|
+
title: 'Terminating existing Database connection',
|
|
93
|
+
skip: (ctx) => !ctx.mysqlConnection,
|
|
94
|
+
task: (ctx) => {
|
|
95
|
+
ctx.mysqlConnection.destroy();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
81
99
|
/**
|
|
82
100
|
* @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
83
101
|
*/
|
|
84
102
|
const connectToMySQL = () => ({
|
|
85
103
|
title: 'Connecting to MySQL server',
|
|
86
104
|
skip: (ctx) => ctx.skipSetup,
|
|
87
|
-
task: (ctx, task) =>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
task: (ctx, task) => {
|
|
106
|
+
const { mysql } = ctx.config.docker.getContainers();
|
|
107
|
+
|
|
108
|
+
task.title = `Connecting to ${mysql._} server`;
|
|
109
|
+
|
|
110
|
+
return task.newListr([
|
|
111
|
+
waitForMySQLInitialization(),
|
|
112
|
+
createMagentoDatabase(),
|
|
113
|
+
terminatingExistingConnection(),
|
|
114
|
+
gettingMySQLConnection()
|
|
115
|
+
], {
|
|
116
|
+
concurrent: false,
|
|
117
|
+
rendererOptions: {
|
|
118
|
+
collapse: true
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
},
|
|
97
122
|
options: {
|
|
98
123
|
bottomBar: 10
|
|
99
124
|
}
|
|
@@ -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
|
+
|
|
18
|
+
return task.newListr(
|
|
19
|
+
execCommandTask(`docker cp ${ctx.importDb} ${mysql.name}:/dump.sql`, {
|
|
20
|
+
logOutput: true
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
17
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;
|
|
@@ -45,24 +111,94 @@ const importDumpToMySQL = () => ({
|
|
|
45
111
|
}
|
|
46
112
|
);
|
|
47
113
|
} catch (e) {
|
|
48
|
-
if (e.includes('Unknown collation: \'utf8mb4_0900_ai_ci\'')) {
|
|
49
|
-
|
|
114
|
+
if (e.message.includes('Unknown collation: \'utf8mb4_0900_ai_ci\'')) {
|
|
115
|
+
const confirmFixingCollation = await task.prompt({
|
|
116
|
+
type: 'Select',
|
|
117
|
+
message: `We got the following error while trying to import ${logger.style.file('dump.sql')}!
|
|
118
|
+
|
|
119
|
+
${e.message}
|
|
120
|
+
|
|
121
|
+
To fix this error we suggest running the following commands:
|
|
122
|
+
${logger.style.command('sed -i \'s/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g\' dump.sql')}
|
|
123
|
+
`,
|
|
124
|
+
choices: [
|
|
125
|
+
{
|
|
126
|
+
name: 'yes',
|
|
127
|
+
message: 'Yes, run the following commands, I reaaaalllyy want dump to work! (this will not edit original dump.sql)'
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'no',
|
|
131
|
+
message: 'Okay, I got it. Will try to fix myself'
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
if (confirmFixingCollation === 'yes') {
|
|
137
|
+
task.output = 'Running fix command...';
|
|
138
|
+
await execAsyncSpawn(`docker exec ${mysql.name} bash -c "sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g' dump.sql"`);
|
|
50
139
|
|
|
51
|
-
|
|
140
|
+
task.output = 'Trying to import dump again...';
|
|
141
|
+
try {
|
|
142
|
+
await execAsyncSpawn(
|
|
143
|
+
importCommand,
|
|
144
|
+
{
|
|
145
|
+
callback: (t) => {
|
|
146
|
+
task.output = t;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
return;
|
|
152
|
+
} catch (e) {
|
|
153
|
+
throw new KnownError(`Fixing ${logger.style.file('dump.sql')} collations did not helped, we got the following error:
|
|
154
|
+
${e.message}`);
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
throw new KnownError(`Database dump import unsuccessful!
|
|
158
|
+
|
|
159
|
+
${e.message}
|
|
52
160
|
|
|
53
161
|
You can try replacing all occurrences of ${logger.style.misc('utf8mb4_0900_ai_ci')} with ${logger.style.misc('utf8mb4_general_ci')} in your ${logger.style.file(ctx.importDb)} file!`);
|
|
162
|
+
}
|
|
54
163
|
}
|
|
55
164
|
|
|
56
165
|
throw new UnknownError(`Unexpected error during dump import.\n\n${e}`);
|
|
166
|
+
} finally {
|
|
167
|
+
clearInterval(tickInterval);
|
|
57
168
|
}
|
|
58
|
-
|
|
59
|
-
clearInterval(tickInterval);
|
|
60
|
-
|
|
61
|
-
task.title = 'Database imported!';
|
|
62
169
|
},
|
|
63
170
|
options: {
|
|
64
171
|
bottomBar: 10
|
|
65
172
|
}
|
|
66
173
|
});
|
|
67
174
|
|
|
175
|
+
/**
|
|
176
|
+
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
177
|
+
*/
|
|
178
|
+
const importDumpToMySQL = () => ({
|
|
179
|
+
title: 'Importing Database Dump To MySQL',
|
|
180
|
+
task: async (ctx, task) => {
|
|
181
|
+
if (!await pathExists(ctx.importDb)) {
|
|
182
|
+
throw new KnownError(`Dump file at ${ctx.importDb} does not exist. Please provide correct relative path to the file`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return task.newListr([
|
|
186
|
+
copyDatabaseDumpIntoContainer(),
|
|
187
|
+
deleteDatabaseBeforeImportingDumpPrompt(),
|
|
188
|
+
runSetGlobalLogBinTrustFunctionCreatorsCommand(),
|
|
189
|
+
executeImportDumpSQL(),
|
|
190
|
+
connectToMySQL(),
|
|
191
|
+
{
|
|
192
|
+
task: () => {
|
|
193
|
+
task.title = 'Database imported!';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
], {
|
|
197
|
+
rendererOptions: {
|
|
198
|
+
collapse: false
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
|
|
68
204
|
module.exports = importDumpToMySQL;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* eslint-disable no-use-before-define */
|
|
2
|
+
const { deepmerge } = require('../../util/deepmerge');
|
|
3
|
+
const { containerApi } = require('../docker/containers');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {import('../../../typings/context').ListrContext} ctx
|
|
7
|
+
* @param {import('../../util/exec-async-command').ExecAsyncSpawnOptions<false> & { useXDebugContainer?: boolean }} [options]
|
|
8
|
+
* @param {string} command
|
|
9
|
+
*/
|
|
10
|
+
const runPHPContainerCommand = async (ctx, command, options = {}) => {
|
|
11
|
+
const { php } = ctx.config.docker.getContainers(ctx.ports);
|
|
12
|
+
|
|
13
|
+
const containers = await containerApi.ls({ formatToJSON: true, all: true });
|
|
14
|
+
|
|
15
|
+
if (containers.some((c) => c.Names === php.name)) {
|
|
16
|
+
return execPHPContainerCommand(ctx, command, options);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return containerApi.run(
|
|
20
|
+
deepmerge(
|
|
21
|
+
php,
|
|
22
|
+
{
|
|
23
|
+
detach: false,
|
|
24
|
+
rm: true
|
|
25
|
+
},
|
|
26
|
+
options.useXDebugContainer
|
|
27
|
+
? {
|
|
28
|
+
image: `${ php.image }.xdebug`
|
|
29
|
+
}
|
|
30
|
+
: {},
|
|
31
|
+
{
|
|
32
|
+
command
|
|
33
|
+
},
|
|
34
|
+
),
|
|
35
|
+
options
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {string} command
|
|
41
|
+
* @param {import('../../util/exec-async-command').ExecAsyncSpawnOptions<false> & { useXDebugContainer?: boolean }} [options]
|
|
42
|
+
* @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
43
|
+
*/
|
|
44
|
+
const runPHPContainerCommandTask = (command, options = {}) => ({
|
|
45
|
+
title: `Running command "${command}"`,
|
|
46
|
+
task: (ctx, task) => runPHPContainerCommand(ctx, command, {
|
|
47
|
+
callback: !ctx.verbose ? undefined : (t) => {
|
|
48
|
+
task.output = t;
|
|
49
|
+
},
|
|
50
|
+
...options
|
|
51
|
+
}),
|
|
52
|
+
option: {
|
|
53
|
+
bottomBar: 10
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @param {import('../../../typings/context').ListrContext} ctx
|
|
60
|
+
* @param {import('../../util/exec-async-command').ExecAsyncSpawnOptions<false> & { useXDebugContainer?: boolean }} [options]
|
|
61
|
+
* @param {string} command
|
|
62
|
+
*/
|
|
63
|
+
const execPHPContainerCommand = async (ctx, command, options = {}) => {
|
|
64
|
+
const { php } = ctx.config.docker.getContainers(ctx.ports);
|
|
65
|
+
|
|
66
|
+
const containers = await containerApi.ls({ formatToJSON: true, all: true });
|
|
67
|
+
|
|
68
|
+
if (!containers.some((c) => c.Names === php.name)) {
|
|
69
|
+
return runPHPContainerCommand(ctx, command, options);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return containerApi.exec(
|
|
73
|
+
command,
|
|
74
|
+
php.name,
|
|
75
|
+
deepmerge(
|
|
76
|
+
php,
|
|
77
|
+
options.env ? {
|
|
78
|
+
env: options.env
|
|
79
|
+
} : {}
|
|
80
|
+
),
|
|
81
|
+
options
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {string} command
|
|
87
|
+
* @param {import('../../util/exec-async-command').ExecAsyncSpawnOptions<false> & { useXDebugContainer?: boolean, title?: string }} [options]
|
|
88
|
+
* @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
89
|
+
*/
|
|
90
|
+
const execPHPContainerCommandTask = (command, options = {}) => ({
|
|
91
|
+
title: typeof options.title === 'string' && options.title === '' ? undefined : options.title || `Running command "${command}"`,
|
|
92
|
+
task: (ctx, task) => execPHPContainerCommand(ctx, command, {
|
|
93
|
+
callback: !ctx.verbose ? undefined : (t) => {
|
|
94
|
+
task.output = t;
|
|
95
|
+
},
|
|
96
|
+
...options
|
|
97
|
+
}),
|
|
98
|
+
option: {
|
|
99
|
+
bottomBar: 10
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
module.exports = {
|
|
104
|
+
runPHPContainerCommand,
|
|
105
|
+
runPHPContainerCommandTask,
|
|
106
|
+
execPHPContainerCommand,
|
|
107
|
+
execPHPContainerCommandTask
|
|
108
|
+
};
|