@scandipwa/magento-scripts 1.11.2 → 1.12.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.
Files changed (55) hide show
  1. package/lib/config/dependencies-for-platforms.js +0 -1
  2. package/lib/config/index.js +4 -2
  3. package/lib/config/{php.js → php-config.js} +0 -0
  4. package/lib/config/phpstorm/debug-config.js +46 -0
  5. package/lib/config/templates/Project_Default.template.xml +13 -0
  6. package/lib/config/templates/dataSources.local.template.xml +11 -0
  7. package/lib/config/templates/dataSources.template.xml +12 -0
  8. package/lib/config/templates/php.template.xml +14 -0
  9. package/lib/config/templates/vscode-launch.template.json +15 -0
  10. package/lib/config/templates/workspace.template.xml +20 -0
  11. package/lib/config/versions/magento-2.3.0.js +1 -1
  12. package/lib/config/versions/magento-2.3.1.js +1 -1
  13. package/lib/config/versions/magento-2.3.2-p2.js +1 -1
  14. package/lib/config/versions/magento-2.3.2.js +1 -1
  15. package/lib/config/versions/magento-2.3.3-p1.js +1 -1
  16. package/lib/config/versions/magento-2.3.3.js +1 -1
  17. package/lib/config/versions/magento-2.3.4-p2.js +1 -1
  18. package/lib/config/versions/magento-2.3.4.js +1 -1
  19. package/lib/config/versions/magento-2.3.5-p1.js +1 -1
  20. package/lib/config/versions/magento-2.3.5-p2.js +1 -1
  21. package/lib/config/versions/magento-2.3.5.js +1 -1
  22. package/lib/config/versions/magento-2.3.6-p1.js +1 -1
  23. package/lib/config/versions/magento-2.3.6.js +1 -1
  24. package/lib/config/versions/magento-2.3.7-p1.js +3 -3
  25. package/lib/config/versions/magento-2.3.7.js +3 -3
  26. package/lib/config/versions/magento-2.4.0-p1.js +2 -2
  27. package/lib/config/versions/magento-2.4.0.js +2 -2
  28. package/lib/config/versions/magento-2.4.1-p1.js +2 -2
  29. package/lib/config/versions/magento-2.4.1.js +2 -2
  30. package/lib/config/versions/magento-2.4.2-p1.js +3 -3
  31. package/lib/config/versions/magento-2.4.2-p2.js +3 -3
  32. package/lib/config/versions/magento-2.4.2.js +3 -3
  33. package/lib/config/versions/magento-2.4.3-p1.js +3 -3
  34. package/lib/config/versions/magento-2.4.3.js +3 -3
  35. package/lib/tasks/composer/index.js +13 -6
  36. package/lib/tasks/docker/index.js +1 -1
  37. package/lib/tasks/docker/network.js +2 -2
  38. package/lib/tasks/file-system/create-php-storm-config.js +82 -0
  39. package/lib/tasks/file-system/create-vscode-config.js +111 -0
  40. package/lib/tasks/file-system/index.js +5 -1
  41. package/lib/tasks/magento/setup-magento/set-deployment-mode.js +1 -1
  42. package/lib/tasks/magento/setup-magento/waiting-for-redis.js +1 -1
  43. package/lib/tasks/php/compile.js +2 -2
  44. package/lib/tasks/php/configure.js +56 -60
  45. package/lib/tasks/php/extensions/disable.js +41 -0
  46. package/lib/tasks/php/extensions/enable.js +44 -0
  47. package/lib/tasks/php/extensions/install.js +47 -0
  48. package/lib/tasks/php-fpm/start-php-fpm.js +3 -3
  49. package/lib/tasks/php-fpm/stop-php-fpm.js +2 -2
  50. package/lib/tasks/requirements/composer.js +1 -1
  51. package/lib/tasks/requirements/docker/index.js +2 -2
  52. package/lib/util/config-file-validator.js +7 -1
  53. package/package.json +17 -16
  54. package/typings/context.d.ts +2 -2
  55. package/typings/index.d.ts +36 -2
@@ -5,7 +5,7 @@ const { execAsyncSpawn } = require('../../util/exec-async-command');
5
5
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
6
6
  */
7
7
  const createNetwork = () => ({
8
- title: 'Deploying docker network',
8
+ title: 'Deploying Docker network',
9
9
  task: async ({ config: { docker } }, task) => {
10
10
  const networkList = (await execAsyncSpawn("docker network ls --format '{{.Name}}'")).split('\n');
11
11
 
@@ -41,7 +41,7 @@ Use command ${logger.style.command('docker network prune')}`);
41
41
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
42
42
  */
43
43
  const removeNetwork = () => ({
44
- title: 'Removing docker network',
44
+ title: 'Removing Docker network',
45
45
  task: async ({ config: { docker } }, task) => {
46
46
  const networkList = (await execAsyncSpawn("docker network ls --format '{{.Name}}'")).split('\n');
47
47
 
@@ -0,0 +1,82 @@
1
+ const setConfigFile = require('../../util/set-config');
2
+ const pathExists = require('../../util/path-exists');
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+
6
+ const createPhpStormConfig = () => ({
7
+ title: 'Setting PHPStorm config',
8
+ task: async ({ config: { phpStorm }, ports }) => {
9
+ const { phpLanguageLevel } = phpStorm.php;
10
+ const jdbcUrl = `jdbc:mysql://localhost:${ports.mysql}/magento`;
11
+
12
+ try {
13
+ await setConfigFile({
14
+ configPathname: phpStorm.xdebug.path,
15
+ template: phpStorm.xdebug.templatePath,
16
+ overwrite: true,
17
+ templateArgs: {
18
+ phpStorm
19
+ }
20
+ });
21
+ } catch (e) {
22
+ throw new Error(`Unexpected error accrued during workspace.xml config creation\n\n${e}`);
23
+ }
24
+
25
+ try {
26
+ await setConfigFile({
27
+ configPathname: phpStorm.php.path,
28
+ template: phpStorm.php.templatePath,
29
+ overwrite: true,
30
+ templateArgs: {
31
+ phpLanguageLevel
32
+ }
33
+ });
34
+ } catch (e) {
35
+ throw new Error(`Unexpected error accrued during php.xml config creation\n\n${e}`);
36
+ }
37
+
38
+ try {
39
+ await setConfigFile({
40
+ configPathname: phpStorm.database.dataSourcesLocal.path,
41
+ template: phpStorm.database.dataSourcesLocal.templatePath,
42
+ overwrite: true,
43
+ templateArgs: {
44
+ phpStorm
45
+ }
46
+ });
47
+ } catch (e) {
48
+ throw new Error(`Unexpected error accrued during dataSources.local.xml config creation\n\n${e}`);
49
+ }
50
+
51
+ try {
52
+ await setConfigFile({
53
+ configPathname: phpStorm.database.dataSources.path,
54
+ template: phpStorm.database.dataSources.templatePath,
55
+ overwrite: true,
56
+ templateArgs: {
57
+ phpStorm,
58
+ jdbcUrl
59
+ }
60
+ });
61
+ } catch (e) {
62
+ throw new Error(`Unexpected error accrued during dataSources.xml config creation\n\n${e}`);
63
+ }
64
+
65
+ if (!await pathExists(path.resolve('./.idea/dataSources'))) {
66
+ await fs.promises.mkdir(path.resolve('./.idea/dataSources'));
67
+ }
68
+
69
+ try {
70
+ await setConfigFile({
71
+ configPathname: phpStorm.inspectionTools.path,
72
+ template: phpStorm.inspectionTools.templatePath,
73
+ overwrite: true,
74
+ templateArgs: {}
75
+ });
76
+ } catch (e) {
77
+ throw new Error(`Unexpected error accrued during Project_Default.xml config creation\n\n${e}`);
78
+ }
79
+ }
80
+ });
81
+
82
+ module.exports = createPhpStormConfig;
@@ -0,0 +1,111 @@
1
+ const path = require('path');
2
+ const semver = require('semver');
3
+ const fs = require('fs');
4
+ const os = require('os');
5
+ const hjson = require('hjson');
6
+ const pathExists = require('../../util/path-exists');
7
+ const setConfigFile = require('../../util/set-config');
8
+
9
+ const phpXDebug2port = 9111;
10
+ const phpXDebug3port = 9003;
11
+ const listenForXDebugConfigName = 'Listen for XDebug';
12
+
13
+ const vscodeLaunchConfigPath = path.join(process.cwd(), '.vscode', 'launch.json');
14
+
15
+ /**
16
+ * @param {import('../../../typings/context').ListrContext['config']['php']} php
17
+ */
18
+ const getCurrentXDebugPort = (php) => (semver.satisfies(php.extensions.xdebug.version, '>=3')
19
+ ? phpXDebug3port
20
+ : phpXDebug2port);
21
+
22
+ /**
23
+ * @param {import('../../../typings/context').ListrContext['config']['php']} php
24
+ */
25
+ const getPHPBinPathWithHomeVariable = (php) => php.binPath.replace(os.homedir(), '$HOME');
26
+ /**
27
+ * @param {import('../../../typings/context').ListrContext['config']['php']} php
28
+ */
29
+ const addPHPDebugConfig = (vscodeLaunchConfig, php) => {
30
+ const phpXDebugConfig = vscodeLaunchConfig.configurations.find(
31
+ ({ name }) => name === listenForXDebugConfigName
32
+ );
33
+
34
+ const phpXDebugPort = getCurrentXDebugPort(php);
35
+ const phpBingPath = getPHPBinPathWithHomeVariable(php);
36
+
37
+ if (!phpXDebugConfig) {
38
+ vscodeLaunchConfig.configurations.push({
39
+ name: listenForXDebugConfigName,
40
+ type: 'php',
41
+ request: 'launch',
42
+ port: phpXDebugPort,
43
+ runtimeExecutable: phpBingPath
44
+ });
45
+
46
+ return true;
47
+ }
48
+
49
+ if (
50
+ phpXDebugConfig.port !== phpXDebugPort
51
+ && phpXDebugConfig.runtimeExecutable !== phpBingPath
52
+ ) {
53
+ phpXDebugConfig.port = phpXDebugPort;
54
+ phpXDebugConfig.runtimeExecutable = phpBingPath;
55
+
56
+ return true;
57
+ }
58
+
59
+ return false;
60
+ };
61
+
62
+ /**
63
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
64
+ */
65
+ const createPhpFpmConfig = () => ({
66
+ title: 'Setting VSCode config',
67
+ task: async ({ config: { php, baseConfig } }, task) => {
68
+ if (await pathExists(vscodeLaunchConfigPath)) {
69
+ const vscodeLaunchConfig = hjson.parse(await fs.promises.readFile(vscodeLaunchConfigPath, 'utf-8'), {
70
+ keepWsc: true
71
+ });
72
+
73
+ const vscodeConfigEdited = addPHPDebugConfig(vscodeLaunchConfig, php);
74
+
75
+ // if vscode config is up-to-date, skip task
76
+ if (!vscodeConfigEdited) {
77
+ task.skip();
78
+ return;
79
+ }
80
+
81
+ await fs.promises.writeFile(vscodeLaunchConfigPath, hjson.stringify(vscodeLaunchConfig));
82
+
83
+ return;
84
+ }
85
+
86
+ if (!await pathExists(path.join(process.cwd(), '.vscode'))) {
87
+ try {
88
+ await fs.promises.mkdir(path.join(process.cwd(), '.vscode'));
89
+ } catch (e) {
90
+ throw new Error(`Unable to creade .vscode directory in your project!\n\n${e}`);
91
+ }
92
+ }
93
+
94
+ try {
95
+ const phpXDebugPort = getCurrentXDebugPort(php);
96
+ const vscodeLaunchConfigTemplatePath = path.join(baseConfig.templateDir, 'vscode-launch.template.json');
97
+ await setConfigFile({
98
+ template: vscodeLaunchConfigTemplatePath,
99
+ configPathname: vscodeLaunchConfigPath,
100
+ templateArgs: {
101
+ XDebugPort: phpXDebugPort,
102
+ PHPBinPath: getPHPBinPathWithHomeVariable(php)
103
+ }
104
+ });
105
+ } catch (e) {
106
+ throw new Error(`Unexpected error accrued during launch.json config creation!\n\n${e}`);
107
+ }
108
+ }
109
+ });
110
+
111
+ module.exports = createPhpFpmConfig;
@@ -1,6 +1,8 @@
1
1
  const createNginxConfig = require('./create-nginx-config');
2
2
  const createPhpConfig = require('./create-php-config');
3
3
  const createPhpFpmConfig = require('./create-php-fpm-config');
4
+ const createPhpStormConfig = require('./create-php-storm-config');
5
+ const createVSCodeConfig = require('./create-vscode-config');
4
6
 
5
7
  /**
6
8
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -10,7 +12,9 @@ const prepareFileSystem = () => ({
10
12
  task: (ctx, task) => task.newListr([
11
13
  createNginxConfig(),
12
14
  createPhpFpmConfig(),
13
- createPhpConfig()
15
+ createPhpConfig(),
16
+ createPhpStormConfig(),
17
+ createVSCodeConfig()
14
18
  ], {
15
19
  concurrent: true
16
20
  })
@@ -5,7 +5,7 @@ const runMagentoCommand = require('../../../util/run-magento');
5
5
  * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
6
6
  */
7
7
  module.exports = () => ({
8
- title: 'Switching magento mode',
8
+ title: 'Switching Magento mode',
9
9
  task: async ({ magentoVersion, config: { magentoConfiguration: { mode } } }, task) => {
10
10
  const { result } = await runMagentoCommand('deploy:mode:show', {
11
11
  throwNonZeroCode: false,
@@ -4,7 +4,7 @@ const waitForIt = require('../../../util/wait-for-it');
4
4
  * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
5
5
  */
6
6
  module.exports = () => ({
7
- title: 'Waiting for redis',
7
+ title: 'Waiting for Redis',
8
8
  task: async ({ ports }, task) => {
9
9
  await waitForIt({
10
10
  name: 'redis',
@@ -17,8 +17,8 @@ const compile = () => ({
17
17
  platformCompileOptions.extraOptions.push('--with-libdir=lib64');
18
18
  }
19
19
  }
20
- const exportEnv = Object.entries(platformCompileOptions.env || {}).map(([key, value]) => `export ${key}="${value}"`).join(' && ');
21
- const phpCompileCommand = `${exportEnv ? `${exportEnv} && ` : ''} \
20
+ const commandEnv = Object.entries(platformCompileOptions.env || {}).map(([key, value]) => `${key}="${value}"`).join(' && ');
21
+ const phpCompileCommand = `${commandEnv ? `${commandEnv} && ` : ''} \
22
22
  phpbrew install -j ${platformCompileOptions.cpuCount} ${php.version} ${platformCompileOptions.variants.join(' ')} \
23
23
  -- ${platformCompileOptions.extraOptions.join(' ')}`;
24
24
 
@@ -1,14 +1,18 @@
1
1
  /* eslint-disable max-len */
2
+ const path = require('path');
3
+ const os = require('os');
4
+ const fs = require('fs');
2
5
  const { execAsyncSpawn } = require('../../util/exec-async-command');
3
- const macosVersion = require('macos-version');
6
+ const enableExtension = require('./extensions/enable');
7
+ const installExtension = require('./extensions/install');
8
+ const disableExtension = require('./extensions/disable');
4
9
 
5
10
  /**
6
- * Get installed modules list with versions
7
- * @param {Object} param0
8
- * @param {import('../../../typings/context').ListrContext['config']['php']} param0.php
11
+ * Get enabled extensions list with versions
12
+ * @param {import('../../../typings/context').ListrContext['config']} param0
9
13
  * @returns {Promise<{[key: string]: string}}>}
10
14
  */
11
- const getInstalledModules = async ({ php }) => {
15
+ const getEnabledExtensions = async ({ php }) => {
12
16
  const output = await execAsyncSpawn(
13
17
  `${ php.binPath } -c ${php.iniPath} -r 'foreach (get_loaded_extensions() as $extension) echo "$extension:" . phpversion($extension) . "\n";'`
14
18
  );
@@ -25,44 +29,35 @@ const getInstalledModules = async ({ php }) => {
25
29
  };
26
30
 
27
31
  /**
28
- * @type {(extensions: string[]) => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
32
+ * Get installed extensions
33
+ * @param {import('../../../typings/context').ListrContext['config']} param0
34
+ * @returns {Promise<string[]>}
29
35
  */
30
- const disablingExtensions = (extensions) => ({
31
- title: `Disabling extensions ${extensions.join(', ')}`,
32
- task: async ({ config: { overridenConfiguration: { configuration: { php } } } }, task) => {
33
- try {
34
- for (const extension of extensions) {
35
- await execAsyncSpawn(`
36
- source ~/.phpbrew/bashrc && \
37
- phpbrew use ${ php.version } && \
38
- phpbrew ext disable ${extension}`, {
39
- callback: (t) => {
40
- task.output = t;
41
- }
42
- });
43
- }
44
- } catch (e) {
45
- throw new Error(`Something went wrong during extension disabling.\n\n${e}`);
46
- }
47
- },
48
- options: {
49
- bottomBar: 10
50
- }
51
- });
36
+ const getInstalledExtensions = async ({ php }) => {
37
+ const extensionDirectory = path.join(os.homedir(), '.phpbrew', 'build', `php-${php.version}`, 'ext');
38
+
39
+ const availableExtensions = await fs.promises.readdir(extensionDirectory, {
40
+ encoding: 'utf-8'
41
+ });
42
+
43
+ return availableExtensions;
44
+ };
52
45
 
53
46
  /**
54
- * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
47
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
55
48
  */
56
49
  const configure = () => ({
57
50
  title: 'Configuring PHP extensions',
58
51
  task: async ({ config, debug }, task) => {
59
- const { php, overridenConfiguration: { configuration: { php: { disabledExtensions = [] } } } } = config;
60
- const loadedModules = await getInstalledModules({ php });
52
+ const { php, php: { disabledExtensions = [] } } = config;
53
+ const enabledExtensions = await getEnabledExtensions(config);
54
+ const installedExtensions = await getInstalledExtensions(config);
61
55
 
62
- if (!debug && loadedModules.xdebug && !disabledExtensions.includes('xdebug')) {
56
+ if (!debug && enabledExtensions.xdebug && !disabledExtensions.includes('xdebug')) {
63
57
  disabledExtensions.push('xdebug');
64
58
  }
65
59
 
60
+ /** @type {[string, import('../../../typings/index').PHPExtension][]} */
66
61
  const missingExtensions = Object.entries(php.extensions)
67
62
  .filter(([name, options]) => {
68
63
  const extensionName = options.extensionName || name;
@@ -75,49 +70,50 @@ const configure = () => ({
75
70
  if (extensionName === 'xdebug' && !debug) {
76
71
  return false;
77
72
  }
78
- if (!loadedModules[extensionName]) {
73
+ if (!enabledExtensions[extensionName]) {
79
74
  return true;
80
75
  }
81
76
 
82
- if (options && options.version && loadedModules[extensionName] !== options.version) {
77
+ if (options && options.version && enabledExtensions[extensionName] !== options.version) {
83
78
  return true;
84
79
  }
85
80
 
86
81
  return false;
87
82
  });
88
83
 
84
+ /** @type {import('listr2').ListrTask[]} */
85
+ const extensionTasks = [];
86
+
89
87
  if (missingExtensions.length > 0) {
90
- try {
91
- for (const [extensionName, extensionOptions] of missingExtensions) {
92
- const options = macosVersion.isMacOS ? extensionOptions.macOptions : extensionOptions.options;
93
- const { hooks = {} } = extensionOptions;
94
-
95
- if (hooks.preInstall) {
96
- await Promise.resolve(hooks.preInstall(config));
97
- }
98
- await execAsyncSpawn(`source ~/.phpbrew/bashrc && \
99
- phpbrew use ${ php.version } && \
100
- phpbrew ext install ${ extensionName }${ extensionOptions.version ? ` ${extensionOptions.version}` : ''}${ options ? ` -- ${ options }` : ''}`,
101
- {
102
- callback: (t) => {
103
- task.output = t;
104
- }
105
- });
106
-
107
- if (hooks.postInstall) {
108
- await Promise.resolve(hooks.postInstall(config));
109
- }
88
+ missingExtensions.forEach(([extensionName, extensionOptions]) => {
89
+ if (installedExtensions.includes(extensionName)) {
90
+ extensionTasks.push(enableExtension(extensionName, extensionOptions));
91
+ } else {
92
+ extensionTasks.push(installExtension(extensionName, extensionOptions));
110
93
  }
111
- } catch (e) {
112
- throw new Error(`Something went wrong during the extension installation.\n\n${e}`);
113
- }
94
+ });
114
95
  }
115
96
 
116
97
  if (disabledExtensions.length > 0) {
117
- return task.newListr(
118
- disablingExtensions(disabledExtensions)
119
- );
98
+ disabledExtensions.forEach((extensionName) => {
99
+ extensionTasks.push(disableExtension(extensionName));
100
+ });
120
101
  }
102
+
103
+ if (extensionTasks.length === 0) {
104
+ task.skip();
105
+ return;
106
+ }
107
+
108
+ return task.newListr(
109
+ extensionTasks,
110
+ {
111
+ concurrent: false,
112
+ rendererOptions: {
113
+ collapse: false
114
+ }
115
+ }
116
+ );
121
117
  },
122
118
  options: {
123
119
  bottomBar: 10
@@ -0,0 +1,41 @@
1
+ /* eslint-disable max-len */
2
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
3
+
4
+ /**
5
+ * @param {String} extensionName
6
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
7
+ */
8
+ const disableExtension = (extensionName) => ({
9
+ title: `Disabling ${extensionName} extension`,
10
+ task: async (ctx, task) => {
11
+ const {
12
+ config,
13
+ config: { php }
14
+ } = ctx;
15
+ const extensionOptions = php.extensions[extensionName] || {};
16
+ const { hooks } = extensionOptions;
17
+ if (extensionOptions.disable) {
18
+ await Promise.resolve(extensionOptions.disable(ctx, task));
19
+ } else {
20
+ if (hooks && hooks.preDisable) {
21
+ await Promise.resolve(hooks.preDisable(config));
22
+ }
23
+ await execAsyncSpawn(`source ~/.phpbrew/bashrc && \
24
+ phpbrew use ${ php.version } && \
25
+ phpbrew ext disable ${ extensionName }`,
26
+ {
27
+ callback: (t) => {
28
+ task.output = t;
29
+ }
30
+ });
31
+ if (hooks && hooks.postDisable) {
32
+ await Promise.resolve(hooks.postDisable(config));
33
+ }
34
+ }
35
+ },
36
+ options: {
37
+ bottomBar: 10
38
+ }
39
+ });
40
+
41
+ module.exports = disableExtension;
@@ -0,0 +1,44 @@
1
+ /* eslint-disable max-len */
2
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
3
+
4
+ /**
5
+ * @param {String} extensionName
6
+ * @param {import('../../../../typings/index').PHPExtension} extensionOptions
7
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
8
+ */
9
+ const enableExtension = (extensionName, extensionOptions) => ({
10
+ title: `Enabling ${extensionName} extension`,
11
+ task: async (ctx, task) => {
12
+ const {
13
+ config,
14
+ config: { php }
15
+ } = ctx;
16
+ const { hooks } = extensionOptions;
17
+
18
+ if (extensionOptions.enable) {
19
+ await Promise.resolve(extensionOptions.enable(ctx, task));
20
+ } else {
21
+ if (hooks && hooks.postEnable) {
22
+ await Promise.resolve(hooks.postEnable(config));
23
+ }
24
+
25
+ await execAsyncSpawn(`source ~/.phpbrew/bashrc && \
26
+ phpbrew use ${ php.version } && \
27
+ phpbrew ext enable ${ extensionName }`,
28
+ {
29
+ callback: (t) => {
30
+ task.output = t;
31
+ }
32
+ });
33
+
34
+ if (hooks && hooks.postEnable) {
35
+ await Promise.resolve(hooks.postEnable(config));
36
+ }
37
+ }
38
+ },
39
+ options: {
40
+ bottomBar: 10
41
+ }
42
+ });
43
+
44
+ module.exports = enableExtension;
@@ -0,0 +1,47 @@
1
+ /* eslint-disable max-len */
2
+ const macosVersion = require('macos-version');
3
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
4
+
5
+ /**
6
+ * @param {String} extensionName
7
+ * @param {import('../../../../typings/index').PHPExtension} extensionOptions
8
+ * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
9
+ */
10
+ const installExtension = (extensionName, extensionOptions) => ({
11
+ title: `Installing ${extensionName} extension`,
12
+ task: async (ctx, task) => {
13
+ const {
14
+ config,
15
+ config: { php }
16
+ } = ctx;
17
+ const { hooks } = extensionOptions;
18
+
19
+ if (extensionOptions.install) {
20
+ await Promise.resolve(extensionOptions.install(ctx, task));
21
+ } else {
22
+ const options = macosVersion.isMacOS ? extensionOptions.macosOptions : extensionOptions.linuxOptions;
23
+
24
+ if (hooks && hooks.preInstall) {
25
+ await Promise.resolve(hooks.preInstall(config));
26
+ }
27
+
28
+ await execAsyncSpawn(`source ~/.phpbrew/bashrc && \
29
+ phpbrew use ${ php.version } && \
30
+ phpbrew ext install ${ extensionName }${ extensionOptions.version ? ` ${extensionOptions.version}` : ''}${ options ? ` -- ${ options }` : ''}`,
31
+ {
32
+ callback: (t) => {
33
+ task.output = t;
34
+ }
35
+ });
36
+
37
+ if (hooks && hooks.postInstall) {
38
+ await Promise.resolve(hooks.postInstall(config));
39
+ }
40
+ }
41
+ },
42
+ options: {
43
+ bottomBar: 10
44
+ }
45
+ });
46
+
47
+ module.exports = installExtension;
@@ -1,5 +1,5 @@
1
1
  const { execAsyncSpawn } = require('../../util/exec-async-command');
2
- const getPhpConfig = require('../../config/php');
2
+ const getPhpConfig = require('../../config/php-config');
3
3
  const { getBaseConfig } = require('../../config/index');
4
4
  const getProcessId = require('./get-process-id');
5
5
 
@@ -7,7 +7,7 @@ const getProcessId = require('./get-process-id');
7
7
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
8
8
  */
9
9
  const startPhpFpm = () => ({
10
- title: 'Starting php-fpm',
10
+ title: 'Starting PHP-FPM',
11
11
  task: async ({ config: { overridenConfiguration }, projectPath }, task) => {
12
12
  const php = getPhpConfig(overridenConfiguration.configuration, getBaseConfig(projectPath));
13
13
  const processId = await getProcessId(php.fpmPidFilePath);
@@ -35,7 +35,7 @@ const startPhpFpm = () => ({
35
35
  }
36
36
  );
37
37
  } catch (e) {
38
- throw new Error(`Error during php-fpm start\n\n${e}`);
38
+ throw new Error(`Error during PHP-FPM start\n\n${e}`);
39
39
  }
40
40
  },
41
41
  options: {
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const { execAsyncSpawn } = require('../../util/exec-async-command');
3
3
  const pathExists = require('../../util/path-exists');
4
- const getPhpConfig = require('../../config/php');
4
+ const getPhpConfig = require('../../config/php-config');
5
5
  const { getBaseConfig } = require('../../config/index');
6
6
  const getProcessId = require('./get-process-id');
7
7
 
@@ -9,7 +9,7 @@ const getProcessId = require('./get-process-id');
9
9
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
10
10
  */
11
11
  const stopPhpFpmTask = () => ({
12
- title: 'Stopping php-fpm',
12
+ title: 'Stopping PHP-FPM',
13
13
  task: async ({ config: { overridenConfiguration }, projectPath }, task) => {
14
14
  const php = getPhpConfig(overridenConfiguration.configuration, getBaseConfig(projectPath));
15
15
  const processId = await getProcessId(php.fpmPidFilePath);
@@ -4,7 +4,7 @@ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
4
4
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
5
5
  */
6
6
  const checkComposer = () => ({
7
- title: 'Checking composer environmental variables',
7
+ title: 'Checking Composer environmental variables',
8
8
  task: () => {
9
9
  try {
10
10
  if (!process.env.COMPOSER_AUTH) {
@@ -9,7 +9,7 @@ const getDockerVersion = require('./version');
9
9
  * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
10
10
  */
11
11
  const checkDocker = () => ({
12
- title: 'Checking docker',
12
+ title: 'Checking Docker',
13
13
  task: async (ctx, task) => {
14
14
  const { code } = await execAsyncSpawn('docker -v', {
15
15
  withCode: true
@@ -63,7 +63,7 @@ ${ logger.style.link('https://docs.create-magento-app.com/getting-started/prereq
63
63
  getDockerVersion(),
64
64
  {
65
65
  task: (ctx) => {
66
- task.title = `Using docker version ${ctx.dockerVersion}`;
66
+ task.title = `Using Docker version ${ctx.dockerVersion}`;
67
67
  }
68
68
  }
69
69
  ]);
@@ -83,7 +83,13 @@ const serviceConfigurationSchema = Joi.object({
83
83
  * @type {Joi.ObjectSchema<import('../../typings').CMAConfiguration['configuration']['composer']>}
84
84
  */
85
85
  const composerConfigurationSchema = Joi.object({
86
- version: Joi.string().optional().allow('1', '2')
86
+ version: Joi.string().optional().custom((value) => {
87
+ if (['1', '2'].includes(value)) {
88
+ return undefined;
89
+ }
90
+
91
+ return versionValidator(value);
92
+ })
87
93
  });
88
94
 
89
95
  /**