@scandipwa/magento-scripts 2.0.0-alpha.12 → 2.0.0-alpha.15
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 +9 -1
- package/lib/config/docker.js +6 -4
- package/lib/config/get-project-configuration.js +5 -0
- package/lib/config/index.js +9 -2
- package/lib/config/templates/php.template.ini +1 -1
- package/lib/tasks/cli/create-bashrc-config.js +1 -1
- package/lib/tasks/docker/containers/container-api.d.ts +3 -0
- package/lib/tasks/docker/containers/container-api.js +15 -9
- package/lib/tasks/docker/containers/tasks.js +12 -12
- package/lib/tasks/docker/convert-mysql-to-mariadb.js +2 -2
- package/lib/tasks/docker/image/image-api.d.ts +44 -0
- package/lib/tasks/docker/image/image-api.js +30 -2
- package/lib/tasks/docker/project-image-builder.js +10 -0
- package/lib/tasks/docker/volume/tasks.js +13 -0
- package/lib/tasks/docker/volume/volume-api.d.ts +30 -0
- package/lib/tasks/docker/volume/volume-api.js +30 -1
- package/lib/tasks/{prefix → project-config}/index.js +6 -6
- package/lib/tasks/requirements/docker/index.js +8 -5
- package/lib/tasks/start.js +4 -8
- package/lib/tasks/status/index.js +16 -9
- package/package.json +2 -2
- package/typings/context.d.ts +2 -0
package/lib/commands/cli.js
CHANGED
|
@@ -5,7 +5,6 @@ const getMagentoVersionConfig = require('../config/get-magento-version-config');
|
|
|
5
5
|
const logger = require('@scandipwa/scandipwa-dev-utils/logger');
|
|
6
6
|
const getProjectConfiguration = require('../config/get-project-configuration');
|
|
7
7
|
const checkConfigurationFile = require('../config/check-configuration-file');
|
|
8
|
-
// const { installComposer, installPrestissimo } = require('../tasks/composer');
|
|
9
8
|
const ConsoleBlock = require('../util/console-block');
|
|
10
9
|
const { checkComposerCredentials } = require('../tasks/requirements/composer-credentials');
|
|
11
10
|
|
|
@@ -70,6 +69,15 @@ module.exports = (yargs) => {
|
|
|
70
69
|
.addLine(`Connect to MariaDB server as root: ${logger.style.command('mariadbroot')}`)
|
|
71
70
|
.addEmptyLine();
|
|
72
71
|
|
|
72
|
+
if (ctx.debug) {
|
|
73
|
+
block
|
|
74
|
+
.addLine('Debug PHP in CLI:')
|
|
75
|
+
.addLine('1. Start debugger in VSCode or PHPStorm')
|
|
76
|
+
.addLine(`2. Go to PHP container: ${ logger.style.command('exec php') }`)
|
|
77
|
+
.addLine(`3. Run CLI command with ${ logger.style.code('XDEBUG_SESSION=phpstorm') } environmental variable: ${ logger.style.command('XDEBUG_SESSION=phpstorm magento <command>') }`)
|
|
78
|
+
.addLine('4. Enjoy');
|
|
79
|
+
}
|
|
80
|
+
|
|
73
81
|
block.log();
|
|
74
82
|
|
|
75
83
|
return cli();
|
package/lib/config/docker.js
CHANGED
|
@@ -7,6 +7,7 @@ const systeminformation = require('systeminformation');
|
|
|
7
7
|
const { deepmerge } = require('../util/deepmerge');
|
|
8
8
|
const defaultEsEnv = require('./services/elasticsearch/default-es-env');
|
|
9
9
|
const logger = require('@scandipwa/scandipwa-dev-utils/logger');
|
|
10
|
+
const defaultMagentoUser = require('../tasks/database/default-magento-user');
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
*
|
|
@@ -248,8 +249,8 @@ module.exports = async (ctx, overridenConfiguration, baseConfig) => {
|
|
|
248
249
|
image: `${ mariadb.version ? `mariadb:${ mariadb.version }` : mariadb.image }`,
|
|
249
250
|
name: `${ prefix }_mariadb`,
|
|
250
251
|
description: `To connect to MariaDB you can use the following users:
|
|
251
|
-
- ${ logger.style.command('root') }
|
|
252
|
-
- ${ logger.style.command(
|
|
252
|
+
- User ${ logger.style.command('root') } with password ${ logger.style.command('scandipwa') }
|
|
253
|
+
- User ${ logger.style.command(defaultMagentoUser.user) } with password ${ logger.style.command(defaultMagentoUser.password) }`
|
|
253
254
|
},
|
|
254
255
|
elasticsearch: {
|
|
255
256
|
_: 'ElasticSearch',
|
|
@@ -271,7 +272,7 @@ module.exports = async (ctx, overridenConfiguration, baseConfig) => {
|
|
|
271
272
|
}
|
|
272
273
|
};
|
|
273
274
|
|
|
274
|
-
if (ssl.enabled) {
|
|
275
|
+
if (ssl.enabled && isDockerDesktop) {
|
|
275
276
|
dockerConfig.sslTerminator.ports.push(
|
|
276
277
|
`${isIpAddress(host) ? host : '127.0.0.1'}:443:443`
|
|
277
278
|
);
|
|
@@ -302,7 +303,8 @@ module.exports = async (ctx, overridenConfiguration, baseConfig) => {
|
|
|
302
303
|
command: `/bin/bash -c "varnishd -a :${ isDockerDesktop ? 80 : ports.varnish } -t 600 -f /etc/varnish/default.vcl -s Cache=malloc,2048m -s Transient=malloc,512m -p http_resp_hdr_len=70000 -p http_resp_size=100000 && varnishlog"`,
|
|
303
304
|
tmpfs: [
|
|
304
305
|
'/var/lib/varnish:exec'
|
|
305
|
-
]
|
|
306
|
+
],
|
|
307
|
+
description: `Varnish HealthCheck status: ${ logger.style.command(varnish.healthCheck ? 'enabled' : 'disabled') }`
|
|
306
308
|
};
|
|
307
309
|
}
|
|
308
310
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { getProjectConfig } = require('./config');
|
|
1
2
|
const { getConfigFromMagentoVersion } = require('./index');
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -8,6 +9,10 @@ const getProjectConfiguration = () => ({
|
|
|
8
9
|
task: async (ctx) => {
|
|
9
10
|
const { magentoVersion } = ctx;
|
|
10
11
|
|
|
12
|
+
if (typeof ctx.debug !== 'boolean') {
|
|
13
|
+
ctx.debug = getProjectConfig().debug;
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
ctx.config = await getConfigFromMagentoVersion(ctx, {
|
|
12
17
|
magentoVersion
|
|
13
18
|
});
|
package/lib/config/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const { getMagentoConfig } = require('./magento-config');
|
|
|
9
9
|
const resolveConfigurationWithOverrides = require('../util/resolve-configuration-with-overrides');
|
|
10
10
|
const { getPrefix, folderName } = require('../util/prefix');
|
|
11
11
|
const UnknownError = require('../errors/unknown-error');
|
|
12
|
+
const { getProjectConfig } = require('./config');
|
|
12
13
|
|
|
13
14
|
const platforms = ['linux', 'darwin'];
|
|
14
15
|
const darwinMinimalVersion = '10.5';
|
|
@@ -33,7 +34,11 @@ const magento = {
|
|
|
33
34
|
|
|
34
35
|
module.exports = {
|
|
35
36
|
/**
|
|
36
|
-
* @param {
|
|
37
|
+
* @param {import('../../typings/context')} ctx
|
|
38
|
+
* @param {Object} param1
|
|
39
|
+
* @param {String} [param1.magentoVersion]
|
|
40
|
+
* @param {String} [param1.projectPath]
|
|
41
|
+
* @param {String} [param1.prefix]
|
|
37
42
|
*/
|
|
38
43
|
async getConfigFromMagentoVersion(ctx, {
|
|
39
44
|
magentoVersion,
|
|
@@ -45,6 +50,7 @@ module.exports = {
|
|
|
45
50
|
if (!configurations[magentoVersion]) {
|
|
46
51
|
throw new UnknownError(`No config found for magento version ${magentoVersion}`);
|
|
47
52
|
}
|
|
53
|
+
const projectConfig = getProjectConfig();
|
|
48
54
|
|
|
49
55
|
const {
|
|
50
56
|
overridenConfiguration,
|
|
@@ -62,7 +68,8 @@ module.exports = {
|
|
|
62
68
|
baseConfig: newBaseConfig,
|
|
63
69
|
overridenConfiguration,
|
|
64
70
|
userConfiguration,
|
|
65
|
-
nonOverridenConfiguration: configurations[magentoVersion]
|
|
71
|
+
nonOverridenConfiguration: configurations[magentoVersion],
|
|
72
|
+
projectConfig
|
|
66
73
|
};
|
|
67
74
|
},
|
|
68
75
|
baseConfig,
|
|
@@ -1813,7 +1813,7 @@ ldap.max_links = -1
|
|
|
1813
1813
|
[opcache]
|
|
1814
1814
|
opcache.enable=1
|
|
1815
1815
|
opcache.revalidate_freq=0
|
|
1816
|
-
opcache.validate_timestamps=
|
|
1816
|
+
opcache.validate_timestamps=1
|
|
1817
1817
|
opcache.max_accelerated_files=100000
|
|
1818
1818
|
opcache.memory_consumption=192
|
|
1819
1819
|
opcache.max_wasted_percentage=10
|
|
@@ -21,7 +21,7 @@ const createBashrcConfigFile = () => ({
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
} catch (e) {
|
|
24
|
-
throw new UnknownError(`Unexpected error accrued during
|
|
24
|
+
throw new UnknownError(`Unexpected error accrued during .magentorc config creation\n\n${e}`);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
});
|
|
@@ -144,3 +144,6 @@ export interface ContainerLogsOptions<T = never> {
|
|
|
144
144
|
|
|
145
145
|
export function logs(options?: ContainerLogsOptions, execOptions?: ExecAsyncSpawnOptions<false>): Promise<string>
|
|
146
146
|
export function logs<T>(options?: ContainerLogsOptions<T>, execOptions?: ExecAsyncSpawnOptions<false>): Promise<T[]>
|
|
147
|
+
|
|
148
|
+
export function stop(containers: string[], execOptions: ExecAsyncSpawnOptions<false>): Promise<string>
|
|
149
|
+
export function rm(containers: string[], execOptions: ExecAsyncSpawnOptions<false>): Promise<string>
|
|
@@ -34,15 +34,15 @@ const runCommand = (options) => {
|
|
|
34
34
|
const exposeArg = expose && expose.map((e) => `--expose=${ e }`);
|
|
35
35
|
const restartArg = !rm && restart && `--restart=${ restart }`;
|
|
36
36
|
const networkArg = network && `--network=${ network }`;
|
|
37
|
-
const portsArgs = ports && ports.length > 0 && ports.map((port) => `-p=${ port }`)
|
|
38
|
-
const mountsArgs = mounts && mounts.map((mount) => `--mount=${ mount }`)
|
|
39
|
-
const mountVolumesArgs = mountVolumes && mountVolumes.map((mount) => `-v=${mount}`)
|
|
40
|
-
const envArgs = !env ? '' : Object.entries(env).map(([key, value]) => `--env=${ key }='${ value }'`)
|
|
37
|
+
const portsArgs = ports && ports.length > 0 && ports.map((port) => `-p=${ port }`);
|
|
38
|
+
const mountsArgs = mounts && mounts.map((mount) => `--mount=${ mount }`);
|
|
39
|
+
const mountVolumesArgs = mountVolumes && mountVolumes.map((mount) => `-v=${mount}`);
|
|
40
|
+
const envArgs = !env ? '' : Object.entries(env).map(([key, value]) => `--env=${ key }='${ value }'`);
|
|
41
41
|
const nameArg = name && `--name=${name}`;
|
|
42
42
|
const entrypointArg = entrypoint && `--entrypoint="${entrypoint}"`;
|
|
43
|
-
const healthCheckArg = healthCheck && Object.entries(healthCheck).map(([key, value]) => `--health-${key}='${value}'`)
|
|
44
|
-
const securityArg = securityOptions.length > 0 && securityOptions.map((opt) => `--security-opt=${opt}`)
|
|
45
|
-
const tmpfsArg = tmpfs.length > 0 && tmpfs.map((t) => `--tmpfs=${t}`)
|
|
43
|
+
const healthCheckArg = healthCheck && Object.entries(healthCheck).map(([key, value]) => `--health-${key}='${value}'`);
|
|
44
|
+
const securityArg = securityOptions.length > 0 && securityOptions.map((opt) => `--security-opt=${opt}`);
|
|
45
|
+
const tmpfsArg = tmpfs.length > 0 && tmpfs.map((t) => `--tmpfs=${t}`);
|
|
46
46
|
const userArg = user && `--user=${user}`;
|
|
47
47
|
const addHostArg = addHost && `--add-host=${addHost}`;
|
|
48
48
|
|
|
@@ -68,7 +68,7 @@ const runCommand = (options) => {
|
|
|
68
68
|
addHostArg,
|
|
69
69
|
image,
|
|
70
70
|
command
|
|
71
|
-
].filter(Boolean).filter((arg) => typeof arg === 'string');
|
|
71
|
+
].flat().filter(Boolean).filter((arg) => typeof arg === 'string');
|
|
72
72
|
|
|
73
73
|
return dockerCommand;
|
|
74
74
|
};
|
|
@@ -203,10 +203,16 @@ const logs = async (options = {}, execOptions = {}) => {
|
|
|
203
203
|
return execAsyncSpawn(logsCommand, execOptions);
|
|
204
204
|
};
|
|
205
205
|
|
|
206
|
+
const stop = (containers, execOptions = {}) => execAsyncSpawn(`docker container stop ${containers.join(' ')}`, execOptions);
|
|
207
|
+
|
|
208
|
+
const rm = (containers, execOptions = {}) => execAsyncSpawn(`docker container rm ${containers.join(' ')}`, execOptions);
|
|
209
|
+
|
|
206
210
|
module.exports = {
|
|
207
211
|
run,
|
|
208
212
|
runCommand,
|
|
209
213
|
exec,
|
|
210
214
|
ls,
|
|
211
|
-
logs
|
|
215
|
+
logs,
|
|
216
|
+
stop,
|
|
217
|
+
rm
|
|
212
218
|
};
|
|
@@ -6,9 +6,9 @@ const containerApi = require('./container-api');
|
|
|
6
6
|
const { imageApi } = require('../image');
|
|
7
7
|
const { execAsyncSpawn } = require('../../../util/exec-async-command');
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
await
|
|
11
|
-
await
|
|
9
|
+
const stopAndRemoveContainers = async (containers) => {
|
|
10
|
+
await containerApi.stop(containers);
|
|
11
|
+
await containerApi.rm(containers);
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const pull = async (image) => execAsyncSpawn(`docker pull ${image}`);
|
|
@@ -116,10 +116,10 @@ const pullImages = () => ({
|
|
|
116
116
|
const startContainers = () => ({
|
|
117
117
|
title: 'Starting containers',
|
|
118
118
|
task: async ({ ports, config: { docker }, debug }, task) => {
|
|
119
|
-
const containerList =
|
|
119
|
+
const containerList = await containerApi.ls({ formatToJSON: true, all: true });
|
|
120
120
|
|
|
121
121
|
const missingContainers = Object.values(docker.getContainers(ports)).filter(
|
|
122
|
-
({ name }) => !containerList.
|
|
122
|
+
({ name }) => !containerList.some((c) => c.Names === name)
|
|
123
123
|
);
|
|
124
124
|
|
|
125
125
|
if (missingContainers.length === 0) {
|
|
@@ -160,22 +160,22 @@ const startContainers = () => ({
|
|
|
160
160
|
const stopContainers = () => ({
|
|
161
161
|
title: 'Stopping Docker containers',
|
|
162
162
|
task: async ({ config: { baseConfig: { prefix } } }, task) => {
|
|
163
|
-
const containerList =
|
|
163
|
+
const containerList = await containerApi.ls({ formatToJSON: true, all: true });
|
|
164
164
|
|
|
165
|
-
const runningContainers = containerList.filter((containerName) => containerName.startsWith(prefix));
|
|
165
|
+
const runningContainers = containerList.filter((containerName) => containerName.Names.startsWith(prefix));
|
|
166
166
|
|
|
167
167
|
if (runningContainers.length === 0) {
|
|
168
168
|
task.skip();
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
await
|
|
172
|
+
await stopAndRemoveContainers(runningContainers.map(({ Names }) => Names));
|
|
173
173
|
}
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
const getContainerStatus = async (containerName) => {
|
|
177
177
|
try {
|
|
178
|
-
return JSON.parse(await execAsyncSpawn(`docker inspect --format='{{json .
|
|
178
|
+
return JSON.parse(await execAsyncSpawn(`docker inspect --format='{{json .}}' ${containerName}`));
|
|
179
179
|
} catch {
|
|
180
180
|
return null;
|
|
181
181
|
}
|
|
@@ -198,11 +198,11 @@ const checkContainersAreRunning = () => ({
|
|
|
198
198
|
}))
|
|
199
199
|
);
|
|
200
200
|
|
|
201
|
-
if (containersWithStatus.some((c) => c.status.Status !== 'running')) {
|
|
201
|
+
if (containersWithStatus.some((c) => c.status.State.Status !== 'running')) {
|
|
202
202
|
if (tries === 2) {
|
|
203
|
-
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!`);
|
|
203
|
+
throw new KnownError(`${containersWithStatus.filter((c) => c.status.State.Status !== 'running').map((c) => c._).join(', ')} containers are not running! Please check container logs for more details!`);
|
|
204
204
|
} else {
|
|
205
|
-
task.output = `${containersWithStatus.filter((c) => c.status.Status !== 'running').map((c) => c._).join(', ')} are not running, waiting if something will change...`;
|
|
205
|
+
task.output = `${containersWithStatus.filter((c) => c.status.State.Status !== 'running').map((c) => c._).join(', ')} are not running, waiting if something will change...`;
|
|
206
206
|
await sleep(2000);
|
|
207
207
|
tries++;
|
|
208
208
|
}
|
|
@@ -5,7 +5,6 @@ const { volumeApi, createVolumes } = require('./volume');
|
|
|
5
5
|
const { execAsyncSpawn } = require('../../util/exec-async-command');
|
|
6
6
|
const { containerApi, stopContainers, pullImages } = require('./containers');
|
|
7
7
|
const { importDumpToDatabase, connectToDatabase } = require('../database');
|
|
8
|
-
const { setPrefix } = require('../prefix');
|
|
9
8
|
const getProjectConfiguration = require('../../config/get-project-configuration');
|
|
10
9
|
const { getAvailablePorts, getCachedPorts } = require('../../config/get-port-config');
|
|
11
10
|
const { saveConfiguration } = require('../../config/save-config');
|
|
@@ -21,6 +20,7 @@ const KnownError = require('../../errors/known-error');
|
|
|
21
20
|
const { createCacheFolder } = require('../cache');
|
|
22
21
|
const { getSystemConfigTask } = require('../../config/system-config');
|
|
23
22
|
const sleep = require('../../util/sleep');
|
|
23
|
+
const { setProjectConfigTask } = require('../project-config');
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
@@ -203,7 +203,7 @@ Please wait, this will take some time and do not restart the MySQL container unt
|
|
|
203
203
|
getSystemConfigTask(),
|
|
204
204
|
getCachedPorts(),
|
|
205
205
|
stopContainers(),
|
|
206
|
-
|
|
206
|
+
setProjectConfigTask(),
|
|
207
207
|
getProjectConfiguration(),
|
|
208
208
|
// get fresh ports
|
|
209
209
|
getAvailablePorts(),
|
|
@@ -32,3 +32,47 @@ export function ls(
|
|
|
32
32
|
options?: ImagesLsOptions<true>,
|
|
33
33
|
execOptions?: ExecAsyncSpawnOptions<false>
|
|
34
34
|
): Promise<ImagesLsResult[]>
|
|
35
|
+
|
|
36
|
+
export interface ImagesInspectOptions<T extends boolean = false> {
|
|
37
|
+
image: string
|
|
38
|
+
format?: string
|
|
39
|
+
formatToJSON?: T
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ImagesInspectResult {
|
|
43
|
+
Id: string
|
|
44
|
+
RepoTags: string[]
|
|
45
|
+
RepoDigests: string[]
|
|
46
|
+
Parent: string
|
|
47
|
+
Comment: string
|
|
48
|
+
Created: string
|
|
49
|
+
Container: string
|
|
50
|
+
ContainerConfig: unknown
|
|
51
|
+
DockerVersion: string
|
|
52
|
+
Author: string
|
|
53
|
+
Config: {
|
|
54
|
+
Env: string[],
|
|
55
|
+
Cmd: string[]
|
|
56
|
+
WorkingDir: string
|
|
57
|
+
Entrypoint: string[]
|
|
58
|
+
StopSignal: string
|
|
59
|
+
}
|
|
60
|
+
Architecture: string
|
|
61
|
+
Os: string
|
|
62
|
+
Size: number
|
|
63
|
+
VirtualSize: number
|
|
64
|
+
GraphDriver: unknown
|
|
65
|
+
RootFs: unknown
|
|
66
|
+
Metadata: Record<string, unknown>
|
|
67
|
+
CreatedTime: number
|
|
68
|
+
Container: Record<string, unknown>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function inspect(
|
|
72
|
+
options?: ImagesInspectOptions,
|
|
73
|
+
execOptions?: ExecAsyncSpawnOptions<false>
|
|
74
|
+
): Promise<string>
|
|
75
|
+
export function inspect(
|
|
76
|
+
options?: ImagesInspectOptions<true>,
|
|
77
|
+
execOptions?: ExecAsyncSpawnOptions<false>
|
|
78
|
+
): Promise<ImagesInspectResult>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const { execAsyncSpawn } = require('../../../util/exec-async-command');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
4
|
* @param {import('./image-api').ImagesLsOptions} options
|
|
6
5
|
* @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
|
|
7
6
|
*/
|
|
@@ -44,6 +43,35 @@ const ls = async (options, execOptions = {}) => {
|
|
|
44
43
|
return execAsyncSpawn(`docker image ls ${args}`, execOptions);
|
|
45
44
|
};
|
|
46
45
|
|
|
46
|
+
/**
|
|
47
|
+
* @param {import('./image-api').ImagesInspectOptions} options
|
|
48
|
+
* @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
|
|
49
|
+
*/
|
|
50
|
+
const inspect = async (options, execOptions = {}) => {
|
|
51
|
+
const {
|
|
52
|
+
image,
|
|
53
|
+
format,
|
|
54
|
+
formatToJSON = false
|
|
55
|
+
} = options;
|
|
56
|
+
|
|
57
|
+
const formatArg = !formatToJSON && format
|
|
58
|
+
? `--format=${format}`
|
|
59
|
+
: formatToJSON && '--format=\'{{json .}}\'';
|
|
60
|
+
|
|
61
|
+
const args = [
|
|
62
|
+
formatArg,
|
|
63
|
+
image
|
|
64
|
+
].filter(Boolean).join(' ');
|
|
65
|
+
|
|
66
|
+
if (formatToJSON) {
|
|
67
|
+
const result = await execAsyncSpawn(`docker image inspect ${args}`, execOptions);
|
|
68
|
+
return JSON.parse(result);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return execAsyncSpawn(`docker image inspect ${args}`, execOptions);
|
|
72
|
+
};
|
|
73
|
+
|
|
47
74
|
module.exports = {
|
|
48
|
-
ls
|
|
75
|
+
ls,
|
|
76
|
+
inspect
|
|
49
77
|
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
const path = require('path');
|
|
1
2
|
const { DockerFileBuilder } = require('../../util/dockerfile-builder');
|
|
2
3
|
const semver = require('semver');
|
|
3
4
|
const { execAsyncSpawn } = require('../../util/exec-async-command');
|
|
4
5
|
const KnownError = require('../../errors/known-error');
|
|
5
6
|
const { runContainerImage } = require('../../util/run-container-image');
|
|
7
|
+
const { imageApi } = require('./image');
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Get enabled extensions list with versions
|
|
@@ -49,6 +51,7 @@ const addExtensionToBuilder = (builder, ctx) => async ([extensionName, extension
|
|
|
49
51
|
const buildDockerFileInstructions = async (ctx, { image, tag }) => {
|
|
50
52
|
const { composer } = ctx.config.overridenConfiguration.configuration;
|
|
51
53
|
const existingPHPExtensions = await getEnabledExtensionsFromImage(`${image}:${tag}`);
|
|
54
|
+
const imageDetails = await imageApi.inspect({ image: `${image}:${tag}`, formatToJSON: true });
|
|
52
55
|
|
|
53
56
|
const missingExtensions = Object.entries(
|
|
54
57
|
ctx.config.overridenConfiguration.configuration.php.extensions
|
|
@@ -101,6 +104,13 @@ const buildDockerFileInstructions = async (ctx, { image, tag }) => {
|
|
|
101
104
|
dockerFileInstructions
|
|
102
105
|
.workDir(ctx.config.baseConfig.containerMagentoDir);
|
|
103
106
|
|
|
107
|
+
const imagePathEnv = imageDetails.Config.Env.find((env) => env.startsWith('PATH'));
|
|
108
|
+
|
|
109
|
+
dockerFileInstructions
|
|
110
|
+
.env({
|
|
111
|
+
PATH: `${ imagePathEnv.split('=').pop() }:${ path.join(ctx.config.baseConfig.containerMagentoDir, 'bin') }`
|
|
112
|
+
});
|
|
113
|
+
|
|
104
114
|
return dockerFileInstructions;
|
|
105
115
|
};
|
|
106
116
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const pathExists = require('../../../util/path-exists');
|
|
3
|
+
const { containerApi } = require('../containers');
|
|
3
4
|
const volumeApi = require('./volume-api');
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -78,6 +79,18 @@ const removeLocalVolumes = () => ({
|
|
|
78
79
|
);
|
|
79
80
|
|
|
80
81
|
if (existingLocalVolumes.length > 0) {
|
|
82
|
+
const existingLocalVolumesDetails = await Promise.all(
|
|
83
|
+
existingLocalVolumes.map((v) => volumeApi.inspect({ volume: v.name, formatToJSON: true }))
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
await Promise.all(existingLocalVolumesDetails.map(async (v) => {
|
|
87
|
+
if (v.Containers && Object.entries(v.Containers).length > 0) {
|
|
88
|
+
await Promise.all(Object.values(v.Containers).map(async (c) => {
|
|
89
|
+
await containerApi.stop(c.Name);
|
|
90
|
+
await containerApi.rm(c.Name);
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
}));
|
|
81
94
|
await volumeApi.rm({
|
|
82
95
|
volumes: existingLocalVolumes.map((volume) => volume.name)
|
|
83
96
|
});
|
|
@@ -47,3 +47,33 @@ export function rm(
|
|
|
47
47
|
options?: VolumeRmOptions,
|
|
48
48
|
execOptions?: ExecAsyncSpawnOptions<false>
|
|
49
49
|
): Promise<string>
|
|
50
|
+
|
|
51
|
+
export interface VolumeInspectOptions<T extends boolean = false> {
|
|
52
|
+
volume: string
|
|
53
|
+
format?: string
|
|
54
|
+
formatToJSON?: T
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface VolumeInspectResult {
|
|
58
|
+
CreatedAt: string
|
|
59
|
+
Driver: string
|
|
60
|
+
Labels: unknown
|
|
61
|
+
Mountpoint: string
|
|
62
|
+
Name: string
|
|
63
|
+
Options: unknown
|
|
64
|
+
Scope: string
|
|
65
|
+
CreatedTime: number
|
|
66
|
+
Containers: Record<string, {
|
|
67
|
+
Name: string
|
|
68
|
+
Destination: string
|
|
69
|
+
}>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function inspect(
|
|
73
|
+
options?: VolumeInspectOptions,
|
|
74
|
+
execOptions?: ExecAsyncSpawnOptions<false>
|
|
75
|
+
): Promise<string>
|
|
76
|
+
export function inspect(
|
|
77
|
+
options?: VolumeInspectOptions<true>,
|
|
78
|
+
execOptions?: ExecAsyncSpawnOptions<false>
|
|
79
|
+
): Promise<VolumeInspectResult>
|
|
@@ -83,8 +83,37 @@ const rm = async (options, execOptions = {}) => {
|
|
|
83
83
|
return execAsyncSpawn(command, execOptions);
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
+
/**
|
|
87
|
+
* @param {import('./volume-api').VolumeInspectOptions} options
|
|
88
|
+
* @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
|
|
89
|
+
*/
|
|
90
|
+
const inspect = async (options, execOptions = {}) => {
|
|
91
|
+
const {
|
|
92
|
+
image: volume,
|
|
93
|
+
format,
|
|
94
|
+
formatToJSON = false
|
|
95
|
+
} = options;
|
|
96
|
+
|
|
97
|
+
const formatArg = !formatToJSON && format
|
|
98
|
+
? `--format=${format}`
|
|
99
|
+
: formatToJSON && '--format=\'{{json .}}\'';
|
|
100
|
+
|
|
101
|
+
const args = [
|
|
102
|
+
formatArg,
|
|
103
|
+
volume
|
|
104
|
+
].filter(Boolean).join(' ');
|
|
105
|
+
|
|
106
|
+
if (formatToJSON) {
|
|
107
|
+
const result = await execAsyncSpawn(`docker volume inspect ${args}`, execOptions);
|
|
108
|
+
return JSON.parse(result);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return execAsyncSpawn(`docker volume inspect ${args}`, execOptions);
|
|
112
|
+
};
|
|
113
|
+
|
|
86
114
|
module.exports = {
|
|
87
115
|
create,
|
|
88
116
|
ls,
|
|
89
|
-
rm
|
|
117
|
+
rm,
|
|
118
|
+
inspect
|
|
90
119
|
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
+
const { setProjectConfig } = require('../../config/config');
|
|
1
2
|
const { setPrefix: setPrefixUtil } = require('../../util/prefix');
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
5
6
|
*/
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
title: 'Settings project prefix',
|
|
7
|
+
const setProjectConfigTask = () => ({
|
|
8
|
+
title: 'Settings project config',
|
|
9
9
|
task: (ctx) => {
|
|
10
10
|
const { config: { overridenConfiguration: { prefix } } } = ctx;
|
|
11
11
|
|
|
12
12
|
setPrefixUtil(prefix);
|
|
13
|
+
|
|
14
|
+
setProjectConfig('debug', ctx.debug);
|
|
13
15
|
},
|
|
14
16
|
options: {
|
|
15
17
|
showTimer: false
|
|
16
18
|
}
|
|
17
19
|
});
|
|
18
20
|
|
|
19
|
-
module.exports = {
|
|
20
|
-
setPrefix
|
|
21
|
-
};
|
|
21
|
+
module.exports = { setProjectConfigTask };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const os = require('os');
|
|
1
2
|
const logger = require('@scandipwa/scandipwa-dev-utils/logger');
|
|
2
3
|
const { cmaGlobalConfig } = require('../../../config/cma-config');
|
|
3
4
|
const KnownError = require('../../../errors/known-error');
|
|
@@ -10,12 +11,13 @@ const { checkDockerPerformance } = require('./performance');
|
|
|
10
11
|
const { checkDockerSocketPermissions } = require('./permissions');
|
|
11
12
|
const { checkDockerStatus, getDockerEngineAndDesktopServiceStatus } = require('./running-status');
|
|
12
13
|
const getDockerVersion = require('./version');
|
|
14
|
+
const getIsWsl = require('../../../util/is-wsl');
|
|
13
15
|
|
|
14
16
|
const USE_DOCKER_ENGINE_WITH_DOCKER_DESKTOP_ANSWER = 'useDockerEngineWithDockerDesktop';
|
|
15
17
|
|
|
16
18
|
const setVersionInContextTask = (task) => ({
|
|
17
19
|
task: (ctx) => {
|
|
18
|
-
if (
|
|
20
|
+
if (os.platform() === 'darwin' && ctx.dockerServerData && ctx.dockerServerData.Platform && ctx.dockerServerData.Platform.Name) {
|
|
19
21
|
task.title = `Using ${ctx.dockerServerData.Platform.Name} for Mac`;
|
|
20
22
|
} else {
|
|
21
23
|
task.title = `Using Docker version ${ctx.dockerVersion}`;
|
|
@@ -152,8 +154,9 @@ const checkDocker = () => ({
|
|
|
152
154
|
});
|
|
153
155
|
|
|
154
156
|
if (code !== 0) {
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
+
if (os.platform() === 'linux') {
|
|
158
|
+
const isWsl = await getIsWsl();
|
|
159
|
+
if (!isWsl) {
|
|
157
160
|
const { engine } = await getDockerEngineAndDesktopServiceStatus();
|
|
158
161
|
if (!engine.exists) {
|
|
159
162
|
const result = await dockerInstallPromptLinux(task);
|
|
@@ -161,7 +164,7 @@ const checkDocker = () => ({
|
|
|
161
164
|
return result;
|
|
162
165
|
}
|
|
163
166
|
}
|
|
164
|
-
} else if (
|
|
167
|
+
} else if (isWsl) {
|
|
165
168
|
dockerInstallPromptWindows();
|
|
166
169
|
}
|
|
167
170
|
} else {
|
|
@@ -170,7 +173,7 @@ const checkDocker = () => ({
|
|
|
170
173
|
return result;
|
|
171
174
|
}
|
|
172
175
|
}
|
|
173
|
-
} else if (
|
|
176
|
+
} else if (os.platform() === 'linux') {
|
|
174
177
|
const { engine, desktop } = await getDockerEngineAndDesktopServiceStatus();
|
|
175
178
|
if (!engine.exists
|
|
176
179
|
&& desktop.exists
|
package/lib/tasks/start.js
CHANGED
|
@@ -11,7 +11,6 @@ const { prepareFileSystem } = require('./file-system');
|
|
|
11
11
|
const { installMagentoProject, setupMagento } = require('./magento');
|
|
12
12
|
const { pullImages, stopContainers } = require('./docker/containers');
|
|
13
13
|
const dockerNetwork = require('./docker/network');
|
|
14
|
-
const { setPrefix } = require('./prefix');
|
|
15
14
|
const { connectToDatabase } = require('./database');
|
|
16
15
|
const { buildProjectImage, buildDebugProjectImage } = require('./docker/project-image-builder');
|
|
17
16
|
const getProjectConfiguration = require('../config/get-project-configuration');
|
|
@@ -29,6 +28,7 @@ const checkPHPVersion = require('./requirements/php-version');
|
|
|
29
28
|
const volumes = require('./docker/volume/tasks');
|
|
30
29
|
const convertMySQLDatabaseToMariaDB = require('./docker/convert-mysql-to-mariadb');
|
|
31
30
|
const { cmaGlobalConfig } = require('../config/cma-config');
|
|
31
|
+
const { setProjectConfigTask } = require('./project-config');
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* @type {() => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
|
|
@@ -83,7 +83,7 @@ const stopProject = () => ({
|
|
|
83
83
|
const retrieveFreshProjectConfiguration = () => ({
|
|
84
84
|
title: 'Retrieving fresh project configuration',
|
|
85
85
|
task: (ctx, task) => task.newListr([
|
|
86
|
-
|
|
86
|
+
setProjectConfigTask(),
|
|
87
87
|
getProjectConfiguration(),
|
|
88
88
|
// get fresh ports
|
|
89
89
|
getAvailablePorts(),
|
|
@@ -111,12 +111,7 @@ const configureProject = () => ({
|
|
|
111
111
|
dockerNetwork.tasks.createNetwork()
|
|
112
112
|
], { concurrent: true })
|
|
113
113
|
},
|
|
114
|
-
|
|
115
|
-
task: (ctx, task) => task.newListr([
|
|
116
|
-
checkPHPVersion(),
|
|
117
|
-
getComposerVersionTask()
|
|
118
|
-
], { concurrent: true })
|
|
119
|
-
},
|
|
114
|
+
checkPHPVersion(),
|
|
120
115
|
{
|
|
121
116
|
task: (ctx, task) => task.newListr([
|
|
122
117
|
buildProjectImage(),
|
|
@@ -125,6 +120,7 @@ const configureProject = () => ({
|
|
|
125
120
|
concurrent: true
|
|
126
121
|
})
|
|
127
122
|
},
|
|
123
|
+
getComposerVersionTask(),
|
|
128
124
|
prepareFileSystem(),
|
|
129
125
|
volumes.createVolumes(),
|
|
130
126
|
installMagentoProject(),
|
|
@@ -28,7 +28,8 @@ const parsePort = (port) => {
|
|
|
28
28
|
const prettyStatus = async (ctx) => {
|
|
29
29
|
const {
|
|
30
30
|
config: {
|
|
31
|
-
baseConfig
|
|
31
|
+
baseConfig,
|
|
32
|
+
projectConfig
|
|
32
33
|
},
|
|
33
34
|
magentoVersion,
|
|
34
35
|
dockerVersion,
|
|
@@ -48,7 +49,7 @@ const prettyStatus = async (ctx) => {
|
|
|
48
49
|
block
|
|
49
50
|
.addHeader(`magento-scripts version: ${ logger.style.link(packageVersion) }`)
|
|
50
51
|
.addEmptyLine()
|
|
51
|
-
.addLine(`Project: ${logger.style.file(baseConfig.prefix)} ${prefix === folderName ? '(without prefix)' : '(with prefix)'} (with php container)`)
|
|
52
|
+
.addLine(`Project: ${logger.style.file(baseConfig.prefix)} ${prefix === folderName ? '(without prefix)' : '(with prefix)'} (with php container)${ projectConfig.debug ? ' (with debugging)' : '' }`)
|
|
52
53
|
.addLine(`Project location: ${logger.style.link(process.cwd())}`);
|
|
53
54
|
|
|
54
55
|
if (projectCreatedAt) {
|
|
@@ -74,19 +75,25 @@ const prettyStatus = async (ctx) => {
|
|
|
74
75
|
|
|
75
76
|
let containerStatus;
|
|
76
77
|
|
|
77
|
-
if (container.status && container.status.Health) {
|
|
78
|
-
containerStatus = `✓ ${ logger.style.file(container.status.Health.Status) } and ${ logger.style.file('running') }`;
|
|
79
|
-
} else if (container.status) {
|
|
80
|
-
containerStatus = logger.style.file(container.status.Status);
|
|
78
|
+
if (container.status && container.status.State && container.status.State.Health) {
|
|
79
|
+
containerStatus = `✓ ${ logger.style.file(container.status.State.Health.Status) } and ${ logger.style.file('running') }`;
|
|
80
|
+
} else if (container.status && container.status.State) {
|
|
81
|
+
containerStatus = logger.style.file(container.status.State.Status);
|
|
81
82
|
} else {
|
|
82
83
|
containerStatus = '✖ Not running';
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
block
|
|
86
87
|
.addLine(`Status: ${containerStatus}`)
|
|
87
|
-
.addLine(`Name: ${logger.style.misc(container.name)}`)
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
.addLine(`Name: ${logger.style.misc(container.name)}`);
|
|
89
|
+
|
|
90
|
+
if (container.status && container.status.Config && container.status.Config.Image) {
|
|
91
|
+
block.addLine(`Image: ${logger.style.file(container.status.Config.Image)}`);
|
|
92
|
+
} else {
|
|
93
|
+
block.addLine(`Image: ${logger.style.file(container.image)}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
block.addLine(`Network: ${logger.style.link(container.network)}`);
|
|
90
97
|
|
|
91
98
|
if (!containerStatus.includes('Not running') && container.forwardedPorts && container.forwardedPorts.length > 0) {
|
|
92
99
|
block.addLine('Port forwarding:');
|
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": "2.0.0-alpha.
|
|
6
|
+
"version": "2.0.0-alpha.15",
|
|
7
7
|
"main": "./index.js",
|
|
8
8
|
"types": "./typings/index.d.ts",
|
|
9
9
|
"license": "OSL-3.0",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"mysql",
|
|
55
55
|
"scandipwa"
|
|
56
56
|
],
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "df32030f4809af581a3ff909f215d31f74bc0207"
|
|
58
58
|
}
|
package/typings/context.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import mysql2 from 'mysql2';
|
|
2
2
|
|
|
3
|
+
import { ProjectConfig } from '../lib/config/config';
|
|
3
4
|
import { DockerVersionResult } from '../lib/tasks/docker/api';
|
|
4
5
|
import { CMAConfiguration, PHPExtensions } from './index';
|
|
5
6
|
import { PHPStormConfig } from './phpstorm';
|
|
@@ -86,6 +87,7 @@ export interface ListrContext {
|
|
|
86
87
|
userConfiguration: Omit<CMAConfiguration, 'prefix' | 'useNonOverlappingPorts'>
|
|
87
88
|
nonOverridenConfiguration: Omit<CMAConfiguration, 'prefix' | 'useNonOverlappingPorts'>
|
|
88
89
|
phpStorm: PHPStormConfig
|
|
90
|
+
projectConfig: ProjectConfig
|
|
89
91
|
}
|
|
90
92
|
systemConfiguration: {
|
|
91
93
|
analytics: boolean
|