@scandipwa/magento-scripts 1.14.0 → 1.14.1-alpha.10

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 (91) hide show
  1. package/index.js +13 -0
  2. package/lib/commands/cli.js +28 -1
  3. package/lib/commands/execute.js +2 -1
  4. package/lib/config/docker.js +85 -12
  5. package/lib/config/get-port-config.js +7 -2
  6. package/lib/config/port-config.js +3 -1
  7. package/lib/config/scandipwa-versions.js +2 -1
  8. package/lib/config/ssl-terminator/index.js +10 -0
  9. package/lib/config/templates/magentorc.template +3 -5
  10. package/lib/config/templates/nginx.template.conf +0 -14
  11. package/lib/config/templates/php-fpm.template.conf +1 -0
  12. package/lib/config/templates/php.template.ini +6 -4
  13. package/lib/config/templates/ssl-terminator.template.conf +27 -0
  14. package/lib/config/templates/varnish.template.vcl +250 -0
  15. package/lib/config/varnish/varnish-6-0.js +11 -0
  16. package/lib/config/varnish/varnish-6-6.js +11 -0
  17. package/lib/config/varnish/varnish-7-0.js +11 -0
  18. package/lib/config/versions/magento-2.3.0.js +9 -1
  19. package/lib/config/versions/magento-2.3.1.js +9 -1
  20. package/lib/config/versions/magento-2.3.2-p2.js +9 -1
  21. package/lib/config/versions/magento-2.3.2.js +9 -1
  22. package/lib/config/versions/magento-2.3.3-p1.js +9 -1
  23. package/lib/config/versions/magento-2.3.3.js +9 -1
  24. package/lib/config/versions/magento-2.3.4-p2.js +9 -1
  25. package/lib/config/versions/magento-2.3.4.js +9 -1
  26. package/lib/config/versions/magento-2.3.5-p1.js +9 -1
  27. package/lib/config/versions/magento-2.3.5-p2.js +9 -1
  28. package/lib/config/versions/magento-2.3.5.js +9 -1
  29. package/lib/config/versions/magento-2.3.6-p1.js +9 -1
  30. package/lib/config/versions/magento-2.3.6.js +9 -1
  31. package/lib/config/versions/magento-2.3.7-p1.js +9 -1
  32. package/lib/config/versions/magento-2.3.7-p2.js +55 -0
  33. package/lib/config/versions/magento-2.3.7-p3.js +55 -0
  34. package/lib/config/versions/magento-2.3.7.js +9 -1
  35. package/lib/config/versions/magento-2.4.0-p1.js +9 -1
  36. package/lib/config/versions/magento-2.4.0.js +9 -1
  37. package/lib/config/versions/magento-2.4.1-p1.js +9 -1
  38. package/lib/config/versions/magento-2.4.1.js +9 -1
  39. package/lib/config/versions/magento-2.4.2-p1.js +9 -1
  40. package/lib/config/versions/magento-2.4.2-p2.js +9 -1
  41. package/lib/config/versions/magento-2.4.2.js +9 -1
  42. package/lib/config/versions/magento-2.4.3-p1.js +9 -1
  43. package/lib/config/versions/magento-2.4.3-p2.js +59 -0
  44. package/lib/config/versions/magento-2.4.3.js +9 -1
  45. package/lib/config/versions/magento-2.4.4.js +59 -0
  46. package/lib/tasks/cli/create-bashrc-config.js +5 -2
  47. package/lib/tasks/docker/containers.js +13 -8
  48. package/lib/tasks/docker/volumes.js +4 -4
  49. package/lib/tasks/file-system/create-nginx-config.js +7 -39
  50. package/lib/tasks/file-system/create-ssl-terminator-config.js +94 -0
  51. package/lib/tasks/file-system/create-varnish-config.js +74 -0
  52. package/lib/tasks/file-system/index.js +5 -1
  53. package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +1 -1
  54. package/lib/tasks/magento/setup-magento/disable-2fa.js +4 -12
  55. package/lib/tasks/magento/setup-magento/disable-full-page-cache.js +20 -0
  56. package/lib/tasks/magento/setup-magento/increase-admin-session-lifetime.js +14 -16
  57. package/lib/tasks/magento/setup-magento/migrate-database.js +24 -11
  58. package/lib/tasks/magento/setup-magento/set-base-url.js +7 -2
  59. package/lib/tasks/magento/setup-magento/upgrade-magento.js +17 -3
  60. package/lib/tasks/magento/setup-magento/varnish-config.js +69 -0
  61. package/lib/tasks/mysql/fix-db.js +2 -2
  62. package/lib/tasks/php/index.js +1 -1
  63. package/lib/tasks/php/update-env-php.js +16 -1
  64. package/lib/tasks/php/update-env.php +56 -12
  65. package/lib/tasks/requirements/docker/index.js +2 -0
  66. package/lib/tasks/requirements/docker/install.js +11 -11
  67. package/lib/tasks/requirements/docker/running-status.js +137 -0
  68. package/lib/tasks/requirements/docker/version.js +2 -0
  69. package/lib/tasks/requirements/index.js +5 -5
  70. package/lib/tasks/requirements/php-version.js +3 -1
  71. package/lib/tasks/start.js +9 -10
  72. package/lib/tasks/status/index.js +25 -9
  73. package/lib/tasks/theme/build-theme.js +26 -8
  74. package/lib/tasks/theme/install-theme.js +16 -4
  75. package/lib/tasks/theme/link-theme.js +2 -2
  76. package/lib/tasks/theme/setup-persisted-query.js +3 -3
  77. package/lib/tasks/theme/setup-themes.js +3 -2
  78. package/lib/tasks/theme/symlink-theme.js +18 -3
  79. package/lib/util/config-file-validator.js +12 -1
  80. package/lib/util/config-php-json.js +19 -0
  81. package/lib/util/instance-metadata.js +9 -3
  82. package/lib/util/is-running-root.js +3 -0
  83. package/lib/util/match-filesystem.js +2 -1
  84. package/lib/util/php-task.js +6 -2
  85. package/lib/util/run-php.js +7 -1
  86. package/lib/util/systemctl.js +46 -0
  87. package/package.json +12 -2
  88. package/typings/context.d.ts +5 -1
  89. package/typings/index.d.ts +32 -1
  90. package/lib/tasks/magento/setup-magento/adjust-magento-configuration.js +0 -27
  91. package/lib/tasks/magento/setup-magento/disable-page-cache.js +0 -11
@@ -0,0 +1,137 @@
1
+ const os = require('os');
2
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
3
+ const getIsWsl = require('../../../util/is-wsl');
4
+ const pathExists = require('../../../util/path-exists');
5
+ const sleep = require('../../../util/sleep');
6
+ const { systemctlControl } = require('../../../util/systemctl');
7
+
8
+ const pathToDockerApplication = '/Applications/Docker.app';
9
+
10
+ const getDockerVersion = () => execAsyncSpawn('docker version --format {{.Server.Version}}', {
11
+ withCode: true
12
+ });
13
+
14
+ /**
15
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
16
+ */
17
+ const checkDockerStatusMacOS = () => ({
18
+ title: 'Checking Docker status on MacOS',
19
+ task: async (ctx, task) => {
20
+ const { result, code } = await getDockerVersion();
21
+
22
+ if (code !== 0 && result.includes('Is the docker daemon running?')) {
23
+ const dockerOpenAppConfirmation = await task.prompt({
24
+ type: 'Confirm',
25
+ message: 'Looks like Docker is not running, would you like us to open a Docker for Mac application and wait for it to start up?'
26
+ });
27
+
28
+ if (dockerOpenAppConfirmation && await pathExists(pathToDockerApplication)) {
29
+ await execAsyncSpawn(`open ${pathToDockerApplication}`);
30
+ let ready = false;
31
+ let attempts = 0;
32
+ while (!ready) {
33
+ if (attempts > 24 && !ready) {
34
+ throw new Error('Docker haven\'t started in 2 mins, exiting...');
35
+ }
36
+ try {
37
+ const { code: startupCode } = await getDockerVersion();
38
+ if (startupCode !== 0) {
39
+ task.output = `Waiting for Docker to startup for ${attempts * 5} seconds...`;
40
+ attempts++;
41
+ await sleep(5000);
42
+ } else {
43
+ ready = true;
44
+ }
45
+ } catch (e) {
46
+ //
47
+ }
48
+ }
49
+
50
+ return;
51
+ }
52
+
53
+ task.skip('User skipped running Docker');
54
+ }
55
+ },
56
+ options: {
57
+ bottomBar: 10
58
+ }
59
+ });
60
+
61
+ /**
62
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
63
+ */
64
+ const checkDockerStatusWSL = () => ({
65
+ title: 'Checking Docker status on Windows WSL',
66
+ task: async () => {
67
+ const { result, code } = await getDockerVersion();
68
+
69
+ if (code !== 0 && result.includes('Is the docker daemon running?')) {
70
+ throw new Error(`Docker is not running!
71
+
72
+ Please open Docker Desktop application for Windows and make sure that Docker is running. Then you can try again!`);
73
+ }
74
+ }
75
+ });
76
+
77
+ /**
78
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
79
+ */
80
+ const checkDockerStatusLinux = () => ({
81
+ title: 'Checking Docker status on Linux',
82
+ task: async (ctx, task) => {
83
+ const dockerService = systemctlControl('docker');
84
+
85
+ const isRunning = await dockerService.isRunning();
86
+ const isEnabled = await dockerService.isEnabled();
87
+
88
+ if (!isEnabled && !isRunning) {
89
+ const dockerStartConfirmation = await task.prompt({
90
+ type: 'Confirm',
91
+ message: `Looks like Docker is not enabled and not running, would you like to enable and run it?
92
+
93
+ This action requires root privileges.`
94
+ });
95
+
96
+ if (dockerStartConfirmation) {
97
+ await dockerService.enableAndStart();
98
+
99
+ return;
100
+ }
101
+ task.skip('User skipped running Docker');
102
+ } else if (!isRunning) {
103
+ const dockerStartConfirmation = await task.prompt({
104
+ type: 'Confirm',
105
+ message: `Looks like Docker is not running, would you like to run it?
106
+
107
+ This action requires root privileges.`
108
+ });
109
+
110
+ if (dockerStartConfirmation) {
111
+ await dockerService.start();
112
+
113
+ return;
114
+ }
115
+ task.skip('User skipped running Docker');
116
+ }
117
+ }
118
+ });
119
+
120
+ /**
121
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
122
+ */
123
+ const checkDockerStatus = () => ({
124
+ title: 'Checking Docker status',
125
+ task: async (ctx, task) => {
126
+ if (os.platform() === 'darwin') {
127
+ return task.newListr(checkDockerStatusMacOS());
128
+ }
129
+ if (!await getIsWsl()) {
130
+ return task.newListr(checkDockerStatusLinux());
131
+ }
132
+
133
+ return task.newListr(checkDockerStatusWSL());
134
+ }
135
+ });
136
+
137
+ module.exports = checkDockerStatus;
@@ -13,6 +13,8 @@ const getDockerVersion = () => ({
13
13
  const dockerVersion = result.split('').filter((c) => /[\d.]/i.test(c)).join('') || result;
14
14
 
15
15
  ctx.dockerVersion = dockerVersion;
16
+ } else {
17
+ throw new Error(`Got unexpected result during Docker version retrieval!\n\n${ result }`);
16
18
  }
17
19
  }
18
20
  });
@@ -13,17 +13,17 @@ const checkRequirements = () => ({
13
13
  task: (ctx, task) => task.newListr([
14
14
  // checking if user is on supported platform
15
15
  checkPlatform(),
16
+ // check the Docker installation
17
+ checkDocker(),
18
+ // check for Node.js version
19
+ checkNodeVersion(),
16
20
  // check the PHPBrew installation
17
21
  checkPHPbrew(),
18
22
  // check installed PHP version
19
23
  checkPHPVersion(),
20
- // check the Docker installation
21
- checkDocker(),
22
24
  // check for COMPOSER_AUTH or auth.json
23
25
  // localAuthJson(),
24
- checkComposer(),
25
- // check for Node.js version
26
- checkNodeVersion()
26
+ checkComposer()
27
27
  ], {
28
28
  concurrent: false,
29
29
  exitOnError: true,
@@ -99,7 +99,7 @@ const checkPHPVersion = () => ({
99
99
  task: async (ctx, task) => {
100
100
  const phpVersionResponse = await execAsyncSpawn('php --version');
101
101
 
102
- const phpVersionResponseResult = phpVersionResponse.match(/PHP\s(\d\.\d\.\d)/i);
102
+ const phpVersionResponseResult = phpVersionResponse.match(/PHP\s(\d+\.\d+\.\d+)/i);
103
103
 
104
104
  if (phpVersionResponseResult && phpVersionResponseResult.length > 0) {
105
105
  const phpVersion = phpVersionResponseResult[1];
@@ -123,6 +123,8 @@ To fix that we will build special PHP version that will be used by PHPBrew, plea
123
123
  );
124
124
  }
125
125
  }
126
+
127
+ task.title = `Using PHP version ${phpVersion} in system`;
126
128
  }
127
129
  }
128
130
  });
@@ -29,6 +29,7 @@ const convertLegacyVolumes = require('./docker/convert-legacy-volumes');
29
29
  const enableMagentoComposerPlugins = require('./magento/enable-magento-composer-plugins');
30
30
  const getIsWsl = require('../util/is-wsl');
31
31
  const checkForXDGOpen = require('../util/xdg-open-exists');
32
+ const { getInstanceMetadata, constants: { WEB_LOCATION_TITLE } } = require('../util/instance-metadata');
32
33
 
33
34
  /**
34
35
  * @type {() => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
@@ -126,6 +127,7 @@ const configureProject = () => ({
126
127
  */
127
128
  const finishProjectConfiguration = () => ({
128
129
  title: 'Finishing project configuration',
130
+ skip: ({ skipSetup }) => skipSetup,
129
131
  task: (ctx, task) => task.newListr([
130
132
  {
131
133
  skip: (ctx) => !ctx.importDb,
@@ -143,16 +145,10 @@ const finishProjectConfiguration = () => ({
143
145
  });
144
146
  }
145
147
  },
146
- {
147
- title: 'Setting up themes',
148
- skip: (ctx) => !ctx.magentoFirstInstall,
149
- task: (subCtx, subTask) => subTask.newListr(
150
- setupThemes()
151
- )
152
- }
148
+ setupThemes()
153
149
  ], {
154
150
  rendererOptions: {
155
- collapse: true
151
+ collapse: false
156
152
  }
157
153
  })
158
154
  });
@@ -189,8 +185,11 @@ const start = () => ({
189
185
 
190
186
  return false;
191
187
  },
192
- task: ({ ports, config: { overridenConfiguration: { host, ssl } } }) => {
193
- openBrowser(`${ssl.enabled ? 'https' : 'http'}://${host}${ssl.enabled || ports.app === 80 ? '' : `:${ports.app}`}/`);
188
+ task: (ctx) => {
189
+ const instanceMetadata = getInstanceMetadata(ctx);
190
+ const locationOnTheWeb = instanceMetadata.frontend.find(({ title }) => title === WEB_LOCATION_TITLE);
191
+
192
+ openBrowser(locationOnTheWeb.text);
194
193
  },
195
194
  options: {
196
195
  showTimer: false
@@ -6,6 +6,7 @@ const { version: packageVersion } = require('../../../package.json');
6
6
  const { getArchSync } = require('../../util/arch');
7
7
  const ConsoleBlock = require('../../util/console-block');
8
8
  const { getComposerVersion } = require('../composer');
9
+ const { getInstanceMetadata } = require('../../util/instance-metadata');
9
10
 
10
11
  /**
11
12
  * @param {string} port
@@ -23,11 +24,8 @@ const parsePort = (port) => {
23
24
 
24
25
  const prettyStatus = async (ctx) => {
25
26
  const {
26
- ports,
27
27
  config: {
28
- magentoConfiguration,
29
28
  baseConfig,
30
- overridenConfiguration: { host, ssl },
31
29
  php,
32
30
  composer
33
31
  },
@@ -91,7 +89,7 @@ const prettyStatus = async (ctx) => {
91
89
  .addLine(`Image: ${logger.style.file(container.image)}`)
92
90
  .addLine(`Network: ${logger.style.link(container.network)}`);
93
91
 
94
- if (container.ports.length > 0) {
92
+ if (container.ports && container.ports.length > 0) {
95
93
  block.addLine('Port forwarding:');
96
94
  container.ports.forEach((port) => {
97
95
  const { host, hostPort, containerPort } = parsePort(port);
@@ -107,15 +105,33 @@ const prettyStatus = async (ctx) => {
107
105
  }
108
106
  });
109
107
 
108
+ const instanceMetadata = getInstanceMetadata(ctx);
109
+
110
110
  block
111
111
  .addEmptyLine()
112
- .addSeparator('Magento status')
113
- .addEmptyLine()
114
- .addLine(`Web location: ${logger.style.link(`${ssl.enabled ? 'https' : 'http'}://${host}${ports.app === 80 ? '' : `:${ports.app}`}/`)}`)
115
- .addLine(`Magento Admin panel location: ${logger.style.link(`${ssl.enabled ? 'https' : 'http'}://${host}${ports.app === 80 ? '' : `:${ports.app}`}/${magentoConfiguration.adminuri}`)}`)
116
- .addLine(`Magento Admin panel credentials: ${logger.style.misc(magentoConfiguration.user)} - ${logger.style.misc(magentoConfiguration.password)}`)
112
+ .addSeparator('Magento 2')
117
113
  .addEmptyLine();
118
114
 
115
+ block.addLine(logger.style.misc('Frontend'));
116
+ instanceMetadata.frontend.forEach(({ title, text }) => {
117
+ block.addLine(` ${title}: ${text}`);
118
+ });
119
+
120
+ block.addEmptyLine();
121
+
122
+ block.addLine(logger.style.misc('Admin'));
123
+ instanceMetadata.admin.forEach(({ title, text }) => {
124
+ block.addLine(` ${title}: ${text}`);
125
+ });
126
+ // block
127
+ // .addEmptyLine()
128
+ // .addSeparator('Magento status')
129
+ // .addEmptyLine()
130
+ // .addLine(`Web location: ${logger.style.link(`${ssl.enabled ? 'https' : 'http'}://${host}${ports.app === 80 ? '' : `:${ports.app}`}/`)}`)
131
+ // .addLine(`Magento Admin panel location: ${logger.style.link(`${ssl.enabled ? 'https' : 'http'}://${host}${ports.app === 80 ? '' : `:${ports.app}`}/${magentoConfiguration.adminuri}`)}`)
132
+ // .addLine(`Magento Admin panel credentials: ${logger.style.misc(magentoConfiguration.user)} - ${logger.style.misc(magentoConfiguration.password)}`)
133
+ // .addEmptyLine();
134
+
119
135
  block.log();
120
136
  };
121
137
 
@@ -1,7 +1,8 @@
1
1
  const path = require('path');
2
2
  const pathExists = require('../../util/path-exists');
3
3
  const { execAsyncSpawn } = require('../../util/exec-async-command');
4
- const shouldUseYarn = require('@scandipwa/scandipwa-dev-utils/should-use-yarn');
4
+ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
5
+ const matchFilesystem = require('../../util/match-filesystem');
5
6
 
6
7
  /**
7
8
  * @type {(theme: import('../../../typings/theme').Theme) => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -13,15 +14,32 @@ const buildTheme = ({ themePath }) => ({
13
14
 
14
15
  if (!await pathExists(path.join(themePath, 'node_modules'))) {
15
16
  task.output = 'Installing theme dependencies';
16
- await execAsyncSpawn(shouldUseYarn() ? 'yarn' : 'npm i', {
17
- cwd: path.join(process.cwd(), themePath),
18
- callback: !verbose ? undefined : (t) => {
19
- task.output = t;
20
- }
21
- });
17
+ const commandToInstallDependencies = await pathExists(path.join(themePath, 'package-lock.json'))
18
+ ? 'npm ci'
19
+ : 'npm i';
20
+
21
+ try {
22
+ await execAsyncSpawn(commandToInstallDependencies, {
23
+ cwd: path.join(process.cwd(), themePath),
24
+ callback: !verbose ? undefined : (t) => {
25
+ task.output = t;
26
+ }
27
+ });
28
+ } catch (e) {
29
+ throw new Error(`We were unable to install theme dependencies in ${themePath} using ${logger.style.code(commandToInstallDependencies)} command!
30
+ If you have ${logger.style.file('package-lock.json')} in theme directory make sure it's up to date with ${logger.style.file('package.json')} file content.`);
31
+ }
22
32
  }
23
33
 
24
- if (await pathExists(path.join(themePath, 'magento', 'Magento_Theme'))) {
34
+ const magentoThemeDirPath = path.join(themePath, 'magento', 'Magento_Theme');
35
+ const isMagentoThemeDirMatching = await matchFilesystem(magentoThemeDirPath, {
36
+ templates: true,
37
+ web: [
38
+ 'static'
39
+ ]
40
+ });
41
+
42
+ if (isMagentoThemeDirMatching) {
25
43
  task.skip();
26
44
  return;
27
45
  }
@@ -1,13 +1,23 @@
1
+ const path = require('path');
2
+ const getJsonfileData = require('../../util/get-jsonfile-data');
1
3
  const runComposerCommand = require('../../util/run-composer');
2
4
 
3
5
  /**
4
6
  * @type {(theme: import('../../../typings/theme').Theme) => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
5
7
  */
6
- const installTheme = ({ composerData }) => ({
8
+ const installTheme = (theme) => ({
7
9
  title: 'Installing theme in composer.json',
8
- task: async ({ magentoVersion, verbose = false }, task) => {
10
+ task: async (ctx, task) => {
11
+ const { magentoVersion, verbose = false } = ctx;
12
+ const composerJsonData = await getJsonfileData(path.join(process.cwd(), 'composer.json'));
13
+
14
+ if (composerJsonData.require[theme.composerData.name]) {
15
+ task.skip();
16
+ return;
17
+ }
18
+
9
19
  try {
10
- await runComposerCommand(`require ${composerData.name}`, {
20
+ await runComposerCommand(`require ${theme.composerData.name}`, {
11
21
  magentoVersion,
12
22
  callback: !verbose ? undefined : (t) => {
13
23
  task.output = t;
@@ -16,9 +26,11 @@ const installTheme = ({ composerData }) => ({
16
26
  } catch (e) {
17
27
  throw new Error(
18
28
  `Unexpected error while installing theme.
19
- See ERROR log below.\n\n${e}`
29
+ See ERROR log below.\n\n${e}`
20
30
  );
21
31
  }
32
+
33
+ ctx.isSetupUpgradeNeeded = true;
22
34
  },
23
35
  options: {
24
36
  bottomBar: 10
@@ -1,6 +1,6 @@
1
1
  const symlinkTheme = require('./symlink-theme');
2
2
  const installTheme = require('./install-theme');
3
- const disablePageCache = require('../magento/setup-magento/disable-page-cache');
3
+ const disableFullPageCache = require('../magento/setup-magento/disable-full-page-cache');
4
4
  const disablePageBuilder = require('../magento/setup-magento/disable-page-builder');
5
5
  const buildTheme = require('./build-theme');
6
6
  const upgradeMagento = require('../magento/setup-magento/upgrade-magento');
@@ -53,7 +53,7 @@ const linkTheme = () => ({
53
53
  updateEnvPHP(),
54
54
  setupPersistedQuery(),
55
55
  upgradeMagento(),
56
- disablePageCache(),
56
+ disableFullPageCache(),
57
57
  ...(isPageBuilderInstalled && Number(isPagebuilderEnabled) ? [disablePageBuilder()] : []),
58
58
  buildTheme(theme)
59
59
  ]);
@@ -8,7 +8,7 @@ const runMagentoCommand = require('../../util/run-magento');
8
8
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
9
9
  */
10
10
  const persistedQuerySetup = () => ({
11
- title: 'Setting up redis configuration for persisted queries',
11
+ title: 'Setting up Redis configuration for persisted queries',
12
12
  task: async (ctx, task) => {
13
13
  const { ports, magentoVersion, verbose = false } = ctx;
14
14
  const composerLockData = await getJsonfileData(path.join(process.cwd(), 'composer.lock'));
@@ -29,8 +29,8 @@ const persistedQuerySetup = () => ({
29
29
  if (
30
30
  persistedQueryConfig
31
31
  && persistedQueryConfig.redis
32
- && persistedQueryConfig.redis.port === ports.redis
33
- && persistedQueryConfig.redis.localhost === 'localhost'
32
+ && persistedQueryConfig.redis.port === `${ ports.redis }`
33
+ && persistedQueryConfig.redis.host === 'localhost'
34
34
  ) {
35
35
  task.skip();
36
36
  return;
@@ -5,13 +5,14 @@ const symlinkTheme = require('./symlink-theme');
5
5
  const installTheme = require('./install-theme');
6
6
  const setupPersistedQuery = require('./setup-persisted-query');
7
7
  const upgradeMagento = require('../magento/setup-magento/upgrade-magento');
8
- const disablePageCache = require('../magento/setup-magento/disable-page-cache');
8
+ const disableFullPageCache = require('../magento/setup-magento/disable-full-page-cache');
9
9
  const buildTheme = require('./build-theme');
10
10
 
11
11
  /**
12
12
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
13
13
  */
14
14
  const setupThemes = () => ({
15
+ title: 'Setting up themes',
15
16
  task: async (ctx, task) => {
16
17
  const { config: { baseConfig } } = ctx;
17
18
  const composerData = await getJsonfileData(path.join(baseConfig.magentoDir, 'composer.json'));
@@ -80,7 +81,7 @@ const setupThemes = () => ({
80
81
  ])
81
82
  })).concat([
82
83
  upgradeMagento(),
83
- disablePageCache(),
84
+ disableFullPageCache(),
84
85
  setupPersistedQuery()
85
86
  ])
86
87
  );
@@ -1,13 +1,26 @@
1
+ const path = require('path');
2
+ const getJsonfileData = require('../../util/get-jsonfile-data');
1
3
  const runComposerCommand = require('../../util/run-composer');
2
4
 
3
5
  /**
4
6
  * @type {(theme: import('../../../typings/theme').Theme) => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
5
7
  */
6
- const symlinkTheme = ({ absoluteThemePath }) => ({
8
+ const symlinkTheme = (theme) => ({
7
9
  title: 'Setting symbolic link for theme in composer.json',
8
- task: async ({ magentoVersion, verbose = false }, task) => {
10
+ task: async (ctx, task) => {
11
+ const { magentoVersion, verbose = false } = ctx;
12
+ const composerJsonData = await getJsonfileData(path.join(process.cwd(), 'composer.json'));
13
+ const repositories = Array.isArray(composerJsonData.repositories)
14
+ ? composerJsonData.repositories.reduce((acc, repo, index) => ({ ...acc, [`${index}`]: repo }), {})
15
+ : composerJsonData.repositories;
16
+
17
+ if (Object.values(repositories).some((value) => value.url === theme.themePath)) {
18
+ task.skip();
19
+ return;
20
+ }
21
+
9
22
  try {
10
- await runComposerCommand(`config repo.scandipwa path ${absoluteThemePath}`, {
23
+ await runComposerCommand(`config repo.scandipwa path ${theme.absoluteThemePath}`, {
11
24
  magentoVersion,
12
25
  callback: !verbose ? undefined : (t) => {
13
26
  task.output = t;
@@ -19,6 +32,8 @@ const symlinkTheme = ({ absoluteThemePath }) => ({
19
32
  See ERROR log above.\n\n${e}`
20
33
  );
21
34
  }
35
+
36
+ ctx.isSetupUpgradeNeeded = true;
22
37
  }
23
38
  });
24
39
 
@@ -72,6 +72,15 @@ const nginxConfigurationSchema = Joi.object({
72
72
  configTemplate: Joi.string().optional().custom(fileExistsValidator)
73
73
  });
74
74
 
75
+ /**
76
+ * @type {Joi.ObjectSchema<import('../../typings').NginxConfiguration>}
77
+ */
78
+ const varnishConfigurationSchema = Joi.object({
79
+ enabled: Joi.boolean().optional(),
80
+ version: Joi.string().optional(),
81
+ configTemplate: Joi.string().optional().custom(fileExistsValidator)
82
+ });
83
+
75
84
  /**
76
85
  * @type {Joi.ObjectSchema<import('../../typings').ServiceWithVersion>}
77
86
  */
@@ -101,7 +110,9 @@ const configurationSchema = Joi.object({
101
110
  mysql: serviceConfigurationSchema.optional(),
102
111
  elasticsearch: serviceConfigurationSchema.optional(),
103
112
  redis: serviceConfigurationSchema.optional(),
104
- composer: composerConfigurationSchema.optional()
113
+ composer: composerConfigurationSchema.optional(),
114
+ varnish: varnishConfigurationSchema.optional(),
115
+ sslTerminator: nginxConfigurationSchema.optional()
105
116
  });
106
117
 
107
118
  /**
@@ -0,0 +1,19 @@
1
+ const path = require('path');
2
+ const runPhpCode = require('./run-php');
3
+
4
+ const configPhpToJson = async (projectPath = process.cwd(), { magentoVersion }) => {
5
+ const { code, result } = await runPhpCode(`-r "echo json_encode(require '${path.join(projectPath, 'app', 'etc', 'config.php')}');"`, {
6
+ magentoVersion
7
+ });
8
+
9
+ if (code !== 0) {
10
+ throw new Error(result);
11
+ }
12
+ try {
13
+ return JSON.parse(result);
14
+ } catch (e) {
15
+ throw new Error(`Ooops! Something went wrong when trying to parse app/etc/config.php file!\n\n${e}\n\nFile result: ${result}`);
16
+ }
17
+ };
18
+
19
+ module.exports = configPhpToJson;
@@ -38,7 +38,7 @@ const getInstanceMetadata = (ctx) => {
38
38
  if (isNgrok) {
39
39
  frontend.push({
40
40
  title: WEB_LOCAL_LOCATION_TITLE,
41
- text: `${ssl.enabled ? 'https' : 'http'}://localhost${ssl.enabled || ports.app === 80 ? '' : `:${ports.app}`}/`
41
+ text: `${ssl.enabled ? 'https' : 'http'}://localhost${ssl.enabled || ports.sslTerminator === 80 ? '' : `:${ports.sslTerminator}`}/`
42
42
  });
43
43
  frontend.push({
44
44
  title: WEB_LOCATION_TITLE,
@@ -47,7 +47,7 @@ const getInstanceMetadata = (ctx) => {
47
47
  } else {
48
48
  frontend.push({
49
49
  title: WEB_LOCATION_TITLE,
50
- text: `${ssl.enabled ? 'https' : 'http'}://${host}${ssl.enabled || ports.app === 80 ? '' : `:${ports.app}`}/`
50
+ text: `${ssl.enabled ? 'https' : 'http'}://${host}${ssl.enabled || ports.sslTerminator === 80 ? '' : `:${ports.sslTerminator}`}/`
51
51
  });
52
52
  }
53
53
 
@@ -70,5 +70,11 @@ const getInstanceMetadata = (ctx) => {
70
70
  };
71
71
 
72
72
  module.exports = {
73
- getInstanceMetadata
73
+ getInstanceMetadata,
74
+ constants: {
75
+ WEB_LOCAL_LOCATION_TITLE,
76
+ WEB_LOCATION_TITLE,
77
+ WEB_ADMIN_LOCATION_TITLE,
78
+ WEB_ADMIN_CREDENTIALS_TITLE
79
+ }
74
80
  };
@@ -0,0 +1,3 @@
1
+ const isRunningRoot = () => process.getuid() === 0; // UID 0 is always root
2
+
3
+ module.exports = isRunningRoot;
@@ -13,7 +13,8 @@ const matchFilesystem = async (cwd, structure) => {
13
13
  .every((value) => value === true);
14
14
 
15
15
  return ok;
16
- } if (typeof structure === 'object') {
16
+ }
17
+ if (typeof structure === 'object') {
17
18
  const ok = (await Promise.all(Object.entries(structure).map(([key, value]) => {
18
19
  if (typeof value === 'boolean') {
19
20
  return pathExists(path.join(cwd, key));
@@ -1,7 +1,10 @@
1
1
  const runPhpCode = require('./run-php');
2
2
 
3
3
  /**
4
- * @type {(command: string, options: { noTitle: boolean }) => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
4
+ * @type {(
5
+ * command: string,
6
+ * options: { noTitle: boolean, env: Record<string, string> }
7
+ * ) => import('listr2').ListrTask<import('../../typings/context').ListrContext>}
5
8
  */
6
9
  const phpTask = (command, options = {}) => ({
7
10
  title: !options.noTitle ? `Running command 'php ${command}` : undefined,
@@ -10,7 +13,8 @@ const phpTask = (command, options = {}) => ({
10
13
  task.output = t;
11
14
  },
12
15
  throwNonZeroCode: true,
13
- magentoVersion
16
+ magentoVersion,
17
+ env: options.env
14
18
  })
15
19
  });
16
20
 
@@ -10,6 +10,7 @@ const { getConfigFromMagentoVersion, defaultConfiguration } = require('../config
10
10
  * @param {() => {}} options.callback
11
11
  * @param {Boolean} options.throwNonZeroCode Throw if command return non 0 code.
12
12
  * @param {String} options.magentoVersion Magento version for config
13
+ * @param {Record<string, string>} options.env Environment variables
13
14
  */
14
15
  const runPhpCode = async (command, options = {}) => {
15
16
  const {
@@ -17,7 +18,12 @@ const runPhpCode = async (command, options = {}) => {
17
18
  magentoVersion = defaultConfiguration.magentoVersion
18
19
  } = options;
19
20
  const { php } = await getConfigFromMagentoVersion(magentoVersion);
20
- const { code, result } = await execAsyncSpawn(`${php.binPath} -c ${php.iniPath} ${command}`, {
21
+ let spawnCommand = `${php.binPath} -c ${php.iniPath} ${command}`;
22
+ if (options.env && Object.keys(options.env).length > 0) {
23
+ const env = Object.entries(options.env).map(([key, value]) => `${key}=${value}`).join(' ');
24
+ spawnCommand = `${env} ${spawnCommand}`;
25
+ }
26
+ const { code, result } = await execAsyncSpawn(spawnCommand, {
21
27
  ...options,
22
28
  withCode: true
23
29
  });