@scandipwa/magento-scripts 2.4.0-alpha.1 → 2.4.0-alpha.2
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 +164 -56
- package/lib/config/port-config.js +46 -10
- package/lib/config/services/elasticsearch/default-es-env.js +1 -1
- package/lib/config/services/mariadb/versions/mariadb-10.2.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-10.3.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-10.4.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-10.6.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-11.4.js +3 -1
- package/lib/config/services/mariadb/versions/mariadb-11.6.js +3 -1
- package/lib/config/services/opensearch/default-os-env.js +1 -1
- package/lib/config/services/php/extensions/xdebug.js +1 -0
- package/lib/config/templates/nginx.template.conf +2 -2
- package/lib/config/templates/php-fpm.template.conf +1 -1
- package/lib/config/templates/ssl-terminator.template.conf +1 -1
- package/lib/tasks/database/create-magento-database.js +2 -1
- package/lib/tasks/database/import-remote-db/ssh/index.js +1 -1
- package/lib/tasks/database/import-remote-db/ssh/readymage.js +1 -1
- package/lib/tasks/database/import-remote-db/ssh/regular-server.js +1 -1
- package/lib/tasks/docker/containers/container-api.d.ts +5 -0
- package/lib/tasks/docker/containers/container-api.js +3 -1
- package/lib/tasks/docker/containers/tasks.js +86 -21
- package/lib/tasks/docker/project-image-builder.js +55 -45
- package/lib/tasks/docker/system/system-api.d.ts +66 -0
- package/lib/tasks/docker/system/system-api.js +28 -1
- package/lib/tasks/execute.js +1 -1
- package/lib/tasks/file-system/create-nginx-config.js +22 -8
- package/lib/tasks/file-system/create-ssl-terminator-config.js +20 -7
- package/lib/tasks/magento/install-magento-project.js +40 -24
- package/lib/tasks/magento/setup-magento/check-file-permissions.php +32 -0
- package/lib/tasks/magento/setup-magento/index.js +2 -0
- package/lib/tasks/magento/setup-magento/make-magento-binaries-executable.js +44 -0
- package/lib/tasks/magento/setup-magento/setup-file-permissions.js +160 -0
- package/lib/tasks/php/php-container.js +20 -6
- package/lib/tasks/php/update-env-php.js +3 -9
- package/lib/tasks/requirements/cgroup-version.js +69 -0
- package/lib/tasks/requirements/elasticsearch-version.js +19 -3
- package/lib/tasks/requirements/index.js +3 -0
- package/lib/tasks/requirements/opensearch-version.js +1 -1
- package/lib/tasks/requirements/searchengine-version.js +1 -2
- package/lib/util/dockerfile-builder/build-instructions.js +5 -1
- package/lib/util/dockerfile-builder/types.d.ts +1 -1
- package/lib/util/execute-in-container.js +3 -1
- package/lib/util/get-installed-magento-version.js +60 -2
- package/lib/util/portscanner.js +3 -3
- package/lib/util/run-composer.js +1 -1
- package/lib/util/run-magento.js +2 -1
- package/lib/util/run-php.js +2 -1
- package/lib/util/set-config.js +4 -2
- package/package.json +16 -16
- package/typings/context.d.ts +4 -2
- package/typings/index.d.ts +10 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
const os = require('os')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const {
|
|
5
|
+
runPHPContainerCommandTask,
|
|
6
|
+
runPHPContainerCommand
|
|
7
|
+
} = require('../../php/php-container')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
11
|
+
*/
|
|
12
|
+
const makeNewFilesCreatedInFolderUseDirectoryGroup = () => ({
|
|
13
|
+
title: 'Make new files created in folder use directory group',
|
|
14
|
+
task: (ctx, task) =>
|
|
15
|
+
task.newListr([
|
|
16
|
+
runPHPContainerCommandTask(
|
|
17
|
+
'find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +',
|
|
18
|
+
{
|
|
19
|
+
// should prevent command from failing the task
|
|
20
|
+
// if the folder does not exist
|
|
21
|
+
withCode: true
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
])
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
29
|
+
*/
|
|
30
|
+
const makeFilesWritableForGroupMembers = () => ({
|
|
31
|
+
title: 'Make files writable for group members',
|
|
32
|
+
task: (ctx, task) =>
|
|
33
|
+
task.newListr([
|
|
34
|
+
runPHPContainerCommandTask(
|
|
35
|
+
'find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +',
|
|
36
|
+
{
|
|
37
|
+
// should prevent command from failing the task
|
|
38
|
+
// if the folder does not exist
|
|
39
|
+
withCode: true
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
])
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {string} folder
|
|
47
|
+
* @param {string | number} user
|
|
48
|
+
* @param {string | number} [group]
|
|
49
|
+
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
50
|
+
*/
|
|
51
|
+
const makeFolderOwnedByUser = (folder, user, group) => ({
|
|
52
|
+
title: `Make folder ${folder} owned by ${user} user${
|
|
53
|
+
group ? ` and ${group} group` : ''
|
|
54
|
+
}`,
|
|
55
|
+
task: (ctx, task) =>
|
|
56
|
+
task.newListr([
|
|
57
|
+
runPHPContainerCommandTask(
|
|
58
|
+
`chown -R ${user}${group ? `:${group}` : ''} ${folder}`,
|
|
59
|
+
{
|
|
60
|
+
user: 'root:root'
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {import('../../../../typings/context').ListrContext} ctx
|
|
68
|
+
*/
|
|
69
|
+
const doesFileSystemNeedsPermissionsSetup = async (ctx) => {
|
|
70
|
+
const checkPHPPermissionsFileName = 'check-file-permissions.php'
|
|
71
|
+
const cacheDirFilePath = path.join(
|
|
72
|
+
ctx.config.baseConfig.cacheDir,
|
|
73
|
+
checkPHPPermissionsFileName
|
|
74
|
+
)
|
|
75
|
+
await fs.promises.copyFile(
|
|
76
|
+
path.join(__dirname, checkPHPPermissionsFileName),
|
|
77
|
+
cacheDirFilePath
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
const result = await runPHPContainerCommand(
|
|
81
|
+
ctx,
|
|
82
|
+
`php ${path.relative(process.cwd(), cacheDirFilePath)}`,
|
|
83
|
+
{
|
|
84
|
+
user: 'www-data:www-data',
|
|
85
|
+
cwd: ctx.config.baseConfig.containerMagentoDir
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
await fs.promises.unlink(cacheDirFilePath)
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @type {{directory: string, exists: boolean, writable: boolean, permissions: string, directory_owner: {name: string, passwd: string, uid: number, gid: number, gecos: string, dir: string, shell: string} | boolean, directory_group: boolean, current_user: {name: string, passwd: string, uid: number, gid: number, gecos: string, dir: string, shell: string} | boolean, is_current_user_directory_owner: boolean}[]}
|
|
93
|
+
*/
|
|
94
|
+
const parsedResult = JSON.parse(result)
|
|
95
|
+
|
|
96
|
+
if (parsedResult.some(({ exists, writable }) => exists && !writable)) {
|
|
97
|
+
return true
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return false
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
105
|
+
*/
|
|
106
|
+
const setupMagentoFilePermissions = () => ({
|
|
107
|
+
title: 'Setting Magento file permissions',
|
|
108
|
+
// skip: true,
|
|
109
|
+
skip: async (ctx) =>
|
|
110
|
+
ctx.magentoFirstInstall ||
|
|
111
|
+
!(await doesFileSystemNeedsPermissionsSetup(ctx)),
|
|
112
|
+
task: (ctx, task) =>
|
|
113
|
+
task.newListr(
|
|
114
|
+
[
|
|
115
|
+
makeNewFilesCreatedInFolderUseDirectoryGroup(),
|
|
116
|
+
makeFilesWritableForGroupMembers()
|
|
117
|
+
].concat(
|
|
118
|
+
ctx.isDockerDesktop
|
|
119
|
+
? [
|
|
120
|
+
makeFolderOwnedByUser(
|
|
121
|
+
ctx.config.baseConfig.containerMagentoDir,
|
|
122
|
+
'www-data',
|
|
123
|
+
'www-data'
|
|
124
|
+
)
|
|
125
|
+
]
|
|
126
|
+
: []
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
|
|
133
|
+
*/
|
|
134
|
+
const setupComposerCachePermissions = () => ({
|
|
135
|
+
title: 'Setting Composer Cache permissions',
|
|
136
|
+
task: (ctx, task) =>
|
|
137
|
+
task.newListr([
|
|
138
|
+
ctx.isDockerDesktop
|
|
139
|
+
? makeFolderOwnedByUser(
|
|
140
|
+
'/composer/home',
|
|
141
|
+
'www-data',
|
|
142
|
+
'www-data'
|
|
143
|
+
)
|
|
144
|
+
: makeFolderOwnedByUser(
|
|
145
|
+
'/composer/home',
|
|
146
|
+
os.userInfo().uid,
|
|
147
|
+
os.userInfo().gid
|
|
148
|
+
),
|
|
149
|
+
|
|
150
|
+
runPHPContainerCommandTask('chmod g+ws /composer/home/cache'),
|
|
151
|
+
runPHPContainerCommandTask('chmod g+w /composer/home/cache')
|
|
152
|
+
])
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
module.exports = {
|
|
156
|
+
makeFilesWritableForGroupMembers,
|
|
157
|
+
makeNewFilesCreatedInFolderUseDirectoryGroup,
|
|
158
|
+
setupMagentoFilePermissions,
|
|
159
|
+
setupComposerCachePermissions
|
|
160
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-use-before-define */
|
|
2
|
+
const os = require('os')
|
|
2
3
|
const { deepmerge } = require('../../util/deepmerge')
|
|
3
4
|
const { containerApi } = require('../docker/containers')
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
|
-
* @
|
|
7
|
+
* @param {Parameters<typeof import('./php-container')['runPHPContainerCommand']>[0]} ctx
|
|
8
|
+
* @param {Parameters<typeof import('./php-container')['runPHPContainerCommand']>[1]} command
|
|
9
|
+
* @param {Parameters<typeof import('./php-container')['runPHPContainerCommand']>[2] & { useAutomaticUser?: boolean}} [options]
|
|
7
10
|
*/
|
|
8
11
|
const runPHPContainerCommand = async (ctx, command, options = {}) => {
|
|
9
12
|
const { php } = ctx.config.docker.getContainers(ctx.ports)
|
|
@@ -23,11 +26,21 @@ const runPHPContainerCommand = async (ctx, command, options = {}) => {
|
|
|
23
26
|
php,
|
|
24
27
|
{
|
|
25
28
|
detach: false,
|
|
26
|
-
rm: true
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
+
rm: true,
|
|
29
30
|
command
|
|
30
|
-
}
|
|
31
|
+
},
|
|
32
|
+
options.user
|
|
33
|
+
? {
|
|
34
|
+
user: options.user
|
|
35
|
+
}
|
|
36
|
+
: {},
|
|
37
|
+
options.useAutomaticUser
|
|
38
|
+
? {
|
|
39
|
+
user: ctx.isDockerDesktop
|
|
40
|
+
? 'www-data:www-data'
|
|
41
|
+
: `${os.userInfo().uid}:${os.userInfo().gid}`
|
|
42
|
+
}
|
|
43
|
+
: {}
|
|
31
44
|
),
|
|
32
45
|
options
|
|
33
46
|
)
|
|
@@ -68,7 +81,8 @@ const execPHPContainerCommand = async (ctx, command, options = {}) => {
|
|
|
68
81
|
{
|
|
69
82
|
container: php.name,
|
|
70
83
|
...deepmerge(php, options.env ? { env: options.env } : {}),
|
|
71
|
-
command
|
|
84
|
+
command,
|
|
85
|
+
...(options.user ? { user: options.user } : {})
|
|
72
86
|
},
|
|
73
87
|
options
|
|
74
88
|
)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
-
const os = require('os')
|
|
3
2
|
const getJsonfileData = require('../../util/get-jsonfile-data')
|
|
4
3
|
const pathExists = require('../../util/path-exists')
|
|
5
4
|
const { containerApi } = require('../docker/containers')
|
|
@@ -65,21 +64,16 @@ const updateEnvPHP = () => ({
|
|
|
65
64
|
HOST_MACHINE: hostMachine,
|
|
66
65
|
PORTS: JSON.stringify(ctx.ports)
|
|
67
66
|
},
|
|
68
|
-
command: 'php ./update-env
|
|
67
|
+
command: 'php ./update-env.php',
|
|
69
68
|
mountVolumes: [
|
|
70
69
|
`${path.join(__dirname, 'update-env.php')}:${
|
|
71
70
|
ctx.config.baseConfig.containerMagentoDir
|
|
72
|
-
}/update-env
|
|
71
|
+
}/update-env.php`,
|
|
73
72
|
`${envPhpPath}:${ctx.config.baseConfig.containerMagentoDir}/env.php`
|
|
74
73
|
],
|
|
75
74
|
image: php.image,
|
|
76
75
|
detach: false,
|
|
77
|
-
rm: true
|
|
78
|
-
user:
|
|
79
|
-
(ctx.platform === 'linux' && isDockerDesktop) ||
|
|
80
|
-
!isDockerDesktop
|
|
81
|
-
? `${os.userInfo().uid}:${os.userInfo().gid}`
|
|
82
|
-
: ''
|
|
76
|
+
rm: true
|
|
83
77
|
})
|
|
84
78
|
|
|
85
79
|
task.output = result
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const semver = require('semver')
|
|
2
|
+
const { execAsync } = require('../../util/exec-async')
|
|
3
|
+
const { systemApi } = require('../docker/system')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
7
|
+
*/
|
|
8
|
+
const checkCGroupVersion = () => ({
|
|
9
|
+
title: 'Checking CGroup version',
|
|
10
|
+
task: async (ctx, task) => {
|
|
11
|
+
ctx.cgroupVersion = 'v1'
|
|
12
|
+
|
|
13
|
+
let cgroupVersionDetected
|
|
14
|
+
|
|
15
|
+
if (ctx.platform === 'linux' && !ctx.isWsl) {
|
|
16
|
+
const cgroupVersion = await execAsync(`stat -fc %T /sys/fs/cgroup/`)
|
|
17
|
+
|
|
18
|
+
if (cgroupVersion && cgroupVersion.includes('cgroup2')) {
|
|
19
|
+
ctx.cgroupVersion = 'v2'
|
|
20
|
+
|
|
21
|
+
cgroupVersionDetected = true
|
|
22
|
+
} else {
|
|
23
|
+
const kernelReleaseVersionResult =
|
|
24
|
+
ctx.platformVersion.match(/(\d+\.\d+\.\d+)/)
|
|
25
|
+
|
|
26
|
+
if (
|
|
27
|
+
kernelReleaseVersionResult &&
|
|
28
|
+
kernelReleaseVersionResult.length > 0
|
|
29
|
+
) {
|
|
30
|
+
const kernelVersion = kernelReleaseVersionResult[1]
|
|
31
|
+
|
|
32
|
+
if (semver.satisfies(kernelVersion, '>=6.12.0')) {
|
|
33
|
+
ctx.cgroupVersion = 'v2'
|
|
34
|
+
|
|
35
|
+
cgroupVersionDetected = true
|
|
36
|
+
} else {
|
|
37
|
+
cgroupVersionDetected = true
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!cgroupVersionDetected) {
|
|
44
|
+
const dockerSystemVersions = await systemApi.version({
|
|
45
|
+
formatToJSON: true
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const kernelReleaseVersionResult =
|
|
49
|
+
dockerSystemVersions.Server.KernelVersion.match(
|
|
50
|
+
/(\d+\.\d+\.\d+)/
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if (
|
|
54
|
+
kernelReleaseVersionResult &&
|
|
55
|
+
kernelReleaseVersionResult.length > 0
|
|
56
|
+
) {
|
|
57
|
+
const kernelVersion = kernelReleaseVersionResult[1]
|
|
58
|
+
|
|
59
|
+
if (semver.satisfies(kernelVersion, '>=6.12.0')) {
|
|
60
|
+
ctx.cgroupVersion = 'v2'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
task.title = `Using CGroup ${ctx.cgroupVersion}`
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
module.exports = checkCGroupVersion
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { getPort } = require('../../config/port-config')
|
|
2
|
+
const KnownError = require('../../errors/known-error')
|
|
2
3
|
const UnknownError = require('../../errors/unknown-error')
|
|
3
4
|
const { containerApi } = require('../docker/containers')
|
|
4
5
|
|
|
@@ -41,13 +42,29 @@ const checkElasticSearchVersion = () => ({
|
|
|
41
42
|
detach: false,
|
|
42
43
|
rm: true,
|
|
43
44
|
ports: [`127.0.0.1:${availableElasticSearchPort}:9200`],
|
|
44
|
-
memory: '
|
|
45
|
+
memory: '2gb'
|
|
45
46
|
})
|
|
46
47
|
} catch (e) {
|
|
47
48
|
elasticSearchVersionResponse = e.message
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
if (
|
|
53
|
+
ctx.cgroupVersion === 'v2' &&
|
|
54
|
+
elasticSearchVersionResponse.includes(
|
|
55
|
+
'Cannot invoke "jdk.internal.platform.CgroupInfo.getMountPoint()" because "anyController" is null'
|
|
56
|
+
)
|
|
57
|
+
) {
|
|
58
|
+
throw new KnownError(`ElasticSearch failed to start up due to a JVM bug with CGroup version 2.
|
|
59
|
+
Similar issue on StackOverflow: https://stackoverflow.com/q/71532170.
|
|
60
|
+
|
|
61
|
+
Right now is check if OpenSearch works with your version of Magento.
|
|
62
|
+
Follow the documentation: https://docs.create-magento-app.com/getting-started/config-file#searchengine-opensearch-elasticsearch
|
|
63
|
+
|
|
64
|
+
If it will not help, try updating ElasticSearch image version: https://docs.create-magento-app.com/getting-started/config-file#elasticsearch
|
|
65
|
+
`)
|
|
66
|
+
}
|
|
67
|
+
|
|
51
68
|
const elasticSearchVersionResponseResult =
|
|
52
69
|
elasticSearchVersionResponse.match(/Version:\s(\d+\.\d+\.\d+)/i)
|
|
53
70
|
|
|
@@ -64,8 +81,7 @@ const checkElasticSearchVersion = () => ({
|
|
|
64
81
|
`Cannot retrieve ElasticSearch Version!\n\n${elasticSearchVersionResponse}`
|
|
65
82
|
)
|
|
66
83
|
}
|
|
67
|
-
}
|
|
68
|
-
exitOnError: false
|
|
84
|
+
}
|
|
69
85
|
})
|
|
70
86
|
|
|
71
87
|
module.exports = checkElasticSearchVersion
|
|
@@ -4,6 +4,7 @@ const localAuthJson = require('../composer/local-auth-json')
|
|
|
4
4
|
const checkDocker = require('./docker')
|
|
5
5
|
const checkNodeVersion = require('./node-version')
|
|
6
6
|
const checkRosetta = require('./rosetta')
|
|
7
|
+
const checkCGroupVersion = require('./cgroup-version')
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
|
|
@@ -19,6 +20,8 @@ const checkRequirements = () => ({
|
|
|
19
20
|
checkPlatform(),
|
|
20
21
|
// check the Docker installation
|
|
21
22
|
checkDocker(),
|
|
23
|
+
// check if cgroup v2 is used
|
|
24
|
+
checkCGroupVersion(),
|
|
22
25
|
// check for Node.js version
|
|
23
26
|
checkNodeVersion(),
|
|
24
27
|
// check for COMPOSER_AUTH or auth.json
|
|
@@ -22,7 +22,11 @@ const buildInstructions = (instructions) => {
|
|
|
22
22
|
addInstruction += ` --chown=${instruction.chown}`
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
addInstruction += ` ${
|
|
25
|
+
addInstruction += ` ${
|
|
26
|
+
Array.isArray(instruction.src)
|
|
27
|
+
? instruction.src.join(' ')
|
|
28
|
+
: instruction.src
|
|
29
|
+
}`
|
|
26
30
|
addInstruction += ` ${instruction.dest}`
|
|
27
31
|
|
|
28
32
|
dockerFileInstructions.push(addInstruction)
|
|
@@ -17,6 +17,49 @@ const getComposerData = async (composerPath) => {
|
|
|
17
17
|
return JSON.parse(await fs.promises.readFile(composerPath, 'utf-8'))
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* @param {string} composerLockPath
|
|
22
|
+
* @returns {Promise<{ packages: Array<{ name: string, version: string }> } | null>}
|
|
23
|
+
*/
|
|
24
|
+
const getComposerLockData = async (composerLockPath) => {
|
|
25
|
+
const composerExists = await pathExists(composerLockPath)
|
|
26
|
+
|
|
27
|
+
if (!composerExists) {
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return JSON.parse(await fs.promises.readFile(composerLockPath, 'utf-8'))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const getInstalledMagentoVersionFromLock = async (
|
|
35
|
+
projectPath = process.cwd()
|
|
36
|
+
) => {
|
|
37
|
+
const composerLockData = await getComposerLockData(
|
|
38
|
+
path.join(projectPath, 'composer.lock')
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
if (!composerLockData) {
|
|
42
|
+
throw new KnownError('composer.lock not found')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const magentoDependency = composerLockData.packages.find(
|
|
46
|
+
(composerLockPackage) => {
|
|
47
|
+
return [
|
|
48
|
+
'magento/product-community-edition',
|
|
49
|
+
'magento/product-enterprise-edition'
|
|
50
|
+
].some(
|
|
51
|
+
(magentoEdition) => composerLockPackage.name === magentoEdition
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if (!magentoDependency) {
|
|
57
|
+
return null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return magentoDependency.version
|
|
61
|
+
}
|
|
62
|
+
|
|
20
63
|
const getInstalledMagentoVersion = async (projectPath = process.cwd()) => {
|
|
21
64
|
const composerData = await getComposerData(
|
|
22
65
|
path.join(projectPath, 'composer.json')
|
|
@@ -30,11 +73,26 @@ const getInstalledMagentoVersion = async (projectPath = process.cwd()) => {
|
|
|
30
73
|
'magento/product-enterprise-edition'
|
|
31
74
|
].find((magentoEdition) => composerData.require[magentoEdition])
|
|
32
75
|
|
|
76
|
+
let foundMagentoVersion = ''
|
|
77
|
+
|
|
33
78
|
if (!magentoDependency) {
|
|
34
|
-
|
|
79
|
+
const magentoLockVersion = await getInstalledMagentoVersionFromLock(
|
|
80
|
+
projectPath
|
|
81
|
+
)
|
|
82
|
+
if (!magentoLockVersion) {
|
|
83
|
+
if (!magentoDependency) {
|
|
84
|
+
throw new KnownError(
|
|
85
|
+
'No Magento dependency found in composer.json or composer.lock'
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
foundMagentoVersion = magentoLockVersion
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
foundMagentoVersion = composerData.require[magentoDependency]
|
|
35
93
|
}
|
|
36
94
|
|
|
37
|
-
return
|
|
95
|
+
return foundMagentoVersion.replace(/\^/i, '')
|
|
38
96
|
}
|
|
39
97
|
|
|
40
98
|
module.exports = getInstalledMagentoVersion
|
package/lib/util/portscanner.js
CHANGED
|
@@ -13,7 +13,7 @@ const { Socket } = net
|
|
|
13
13
|
* @param {Object} [options] - Options object.
|
|
14
14
|
* @param {String} [options.host] - Host of where to scan.
|
|
15
15
|
* @param {Number} [options.timeout] - Connection timeout in ms.
|
|
16
|
-
* @returns {Promise<
|
|
16
|
+
* @returns {Promise<'open' | 'closed'>}
|
|
17
17
|
*/
|
|
18
18
|
const checkPortStatus = (port, options = {}) =>
|
|
19
19
|
new Promise((resolve, reject) => {
|
|
@@ -23,7 +23,7 @@ const checkPortStatus = (port, options = {}) =>
|
|
|
23
23
|
|
|
24
24
|
const socket = new Socket()
|
|
25
25
|
/**
|
|
26
|
-
* @type {
|
|
26
|
+
* @type {'open' | 'closed'}
|
|
27
27
|
*/
|
|
28
28
|
let status
|
|
29
29
|
|
|
@@ -80,7 +80,7 @@ const checkPortStatus = (port, options = {}) =>
|
|
|
80
80
|
/**
|
|
81
81
|
* Internal helper function used by {@link findAPortInUse} and {@link findAPortNotInUse}
|
|
82
82
|
* to find a port from a range or a list with a specific status.
|
|
83
|
-
* @param {
|
|
83
|
+
* @param {'open' | 'closed'} status - Status to check.
|
|
84
84
|
* @param {Object} options
|
|
85
85
|
* @param {Number} options.startPort Port to begin status check on (inclusive).
|
|
86
86
|
* @param {Number} options.endPort Last port to check status on (inclusive).
|
package/lib/util/run-composer.js
CHANGED
|
@@ -4,7 +4,7 @@ const { runPHPContainerCommand } = require('../tasks/php/php-container')
|
|
|
4
4
|
* Execute composer command
|
|
5
5
|
* @param {import('../../typings/context').ListrContext} ctx
|
|
6
6
|
* @param {String} command composer command
|
|
7
|
-
* @param {Parameters<import('../tasks/php/php-container')['runPHPContainerCommand']>[2] & { throwNonZeroCode?: boolean }} [options]
|
|
7
|
+
* @param {Parameters<import('../tasks/php/php-container')['runPHPContainerCommand']>[2] & { throwNonZeroCode?: boolean, user?: string, useAutomaticUser?: boolean }} [options]
|
|
8
8
|
*/
|
|
9
9
|
const runComposerCommand = async (ctx, command, options = {}) => {
|
|
10
10
|
const { throwNonZeroCode = true } = options
|
package/lib/util/run-magento.js
CHANGED
|
@@ -5,7 +5,7 @@ const { runPHPContainerCommand } = require('../tasks/php/php-container')
|
|
|
5
5
|
*
|
|
6
6
|
* @param {import('../../typings/context').ListrContext} ctx
|
|
7
7
|
* @param {String} command magento command
|
|
8
|
-
* @param {Parameters<typeof import('../tasks/php/php-container')['runPHPContainerCommand']>[2] & { throwNonZeroCode?: boolean }} options
|
|
8
|
+
* @param {Parameters<typeof import('../tasks/php/php-container')['runPHPContainerCommand']>[2] & { throwNonZeroCode?: boolean, useAutomaticUser?: boolean }} options
|
|
9
9
|
* @returns {Promise<{ code: number, result: string }>}
|
|
10
10
|
*/
|
|
11
11
|
const runMagentoCommand = async (ctx, command, options = {}) => {
|
|
@@ -15,6 +15,7 @@ const runMagentoCommand = async (ctx, command, options = {}) => {
|
|
|
15
15
|
`bin/magento ${command}`,
|
|
16
16
|
{
|
|
17
17
|
...options,
|
|
18
|
+
useAutomaticUser: true,
|
|
18
19
|
withCode: true
|
|
19
20
|
}
|
|
20
21
|
)
|
package/lib/util/run-php.js
CHANGED
|
@@ -4,7 +4,7 @@ const { runPHPContainerCommand } = require('../tasks/php/php-container')
|
|
|
4
4
|
* Execute PHP code
|
|
5
5
|
* @param {import('../../typings/context').ListrContext} ctx
|
|
6
6
|
* @param {String} command php command
|
|
7
|
-
* @param {Parameters<typeof import('../tasks/php/php-container')['runPHPContainerCommand']>[2] & { throwNonZeroCode?: boolean }} [options]
|
|
7
|
+
* @param {Parameters<typeof import('../tasks/php/php-container')['runPHPContainerCommand']>[2] & { throwNonZeroCode?: boolean, useAutomaticUser?: boolean }} [options]
|
|
8
8
|
*/
|
|
9
9
|
const runPhpCode = async (ctx, command, options = {}) => {
|
|
10
10
|
const { throwNonZeroCode = true } = options
|
|
@@ -13,6 +13,7 @@ const runPhpCode = async (ctx, command, options = {}) => {
|
|
|
13
13
|
`php ${command}`,
|
|
14
14
|
{
|
|
15
15
|
...options,
|
|
16
|
+
useAutomaticUser: true,
|
|
16
17
|
withCode: true
|
|
17
18
|
}
|
|
18
19
|
)
|
package/lib/util/set-config.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { Eta } = require('eta')
|
|
2
2
|
const fs = require('fs')
|
|
3
3
|
const path = require('path')
|
|
4
4
|
const pathExists = require('./path-exists')
|
|
5
5
|
|
|
6
|
+
const eta = new Eta()
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
9
|
* @param {{ configPathname: string, template: string, overwrite?: boolean, templateArgs?: Record<string, unknown> }} param0
|
|
8
10
|
*/
|
|
@@ -19,7 +21,7 @@ const setConfigFile = async ({
|
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
const configTemplate = await fs.promises.readFile(template, 'utf-8')
|
|
22
|
-
const compliedConfig = await eta.
|
|
24
|
+
const compliedConfig = await eta.renderStringAsync(configTemplate, {
|
|
23
25
|
date: new Date().toUTCString(),
|
|
24
26
|
...templateArgs
|
|
25
27
|
})
|
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.4.0-alpha.
|
|
6
|
+
"version": "2.4.0-alpha.2",
|
|
7
7
|
"main": "./index.js",
|
|
8
8
|
"types": "./typings/index.d.ts",
|
|
9
9
|
"license": "OSL-3.0",
|
|
@@ -23,24 +23,24 @@
|
|
|
23
23
|
"arm64"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@scandipwa/scandipwa-dev-utils": "0.1.
|
|
27
|
-
"@tilework/mosaic-dev-utils": "^0.2.
|
|
28
|
-
"conf": "10.
|
|
29
|
-
"enquirer": "2.
|
|
30
|
-
"eta": "
|
|
31
|
-
"fast-xml-parser": "^4.0
|
|
26
|
+
"@scandipwa/scandipwa-dev-utils": "0.1.17",
|
|
27
|
+
"@tilework/mosaic-dev-utils": "^0.2.4",
|
|
28
|
+
"conf": "10.2.0",
|
|
29
|
+
"enquirer": "2.4.1",
|
|
30
|
+
"eta": "3.4.0",
|
|
31
|
+
"fast-xml-parser": "^4.4.0",
|
|
32
32
|
"hjson": "^3.2.2",
|
|
33
33
|
"is-installed-globally": "0.4.0",
|
|
34
|
-
"joi": "17.
|
|
34
|
+
"joi": "17.13.3",
|
|
35
35
|
"listr2": "4.0.5",
|
|
36
36
|
"macos-version": "5.2.1",
|
|
37
37
|
"merge-files": "0.1.2",
|
|
38
|
-
"mysql2": "
|
|
39
|
-
"node-ssh": "
|
|
40
|
-
"semver": "7.3
|
|
38
|
+
"mysql2": "3.10.3",
|
|
39
|
+
"node-ssh-no-cpu-features": "^2.0.0",
|
|
40
|
+
"semver": "7.6.3",
|
|
41
41
|
"smol-request": "^2.1.2",
|
|
42
|
-
"systeminformation": "5.
|
|
43
|
-
"yargs": "17.
|
|
42
|
+
"systeminformation": "5.22.11",
|
|
43
|
+
"yargs": "17.7.2"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public"
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"scandipwa"
|
|
57
57
|
],
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@types/node": "^20.
|
|
60
|
-
"@types/yargs": "^17.0.
|
|
59
|
+
"@types/node": "^20.14.11",
|
|
60
|
+
"@types/yargs": "^17.0.32"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "ec855efd799e10f263e82b3bf610d400892db6dc"
|
|
63
63
|
}
|