@scandipwa/magento-scripts 1.16.0-alpha.4 → 1.16.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.
@@ -46,6 +46,10 @@ Would you like to disable it in your project?`,
46
46
  name: 'disable',
47
47
  message: 'Disable it, thanks'
48
48
  },
49
+ {
50
+ name: 'remove',
51
+ message: `Remove ${prestissimoPluginName} from your system`
52
+ },
49
53
  {
50
54
  name: 'skip',
51
55
  message: 'Skip this step'
@@ -56,6 +60,17 @@ Would you like to disable it in your project?`,
56
60
  if (disableConfirmation === 'disable') {
57
61
  localComposerJsonData.config['allow-plugins'][prestissimoPluginName] = false;
58
62
  await fs.promises.writeFile(localComposerJsonPath, JSON.stringify(localComposerJsonData, null, 4), 'utf-8');
63
+
64
+ return;
65
+ }
66
+
67
+ if (disableConfirmation === 'remove') {
68
+ await runComposerCommand(`global remove ${prestissimoPluginName}`, {
69
+ throwNonZeroCode: false,
70
+ magentoVersion
71
+ });
72
+
73
+ return;
59
74
  }
60
75
  }
61
76
  }
@@ -1,4 +1,5 @@
1
1
  const path = require('path');
2
+ const fs = require('fs');
2
3
  const os = require('os');
3
4
  const runComposerCommand = require('../../util/run-composer');
4
5
  const matchFilesystem = require('../../util/match-filesystem');
@@ -128,7 +129,7 @@ const createMagentoProject = async ({
128
129
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
129
130
  */
130
131
  const installMagentoProject = () => ({
131
- title: 'Installing Magento',
132
+ title: 'Installing Magento Project',
132
133
  task: async (ctx, task) => {
133
134
  const { magentoVersion, config: { baseConfig, overridenConfiguration }, verbose } = ctx;
134
135
  const {
@@ -180,6 +181,12 @@ const installMagentoProject = () => ({
180
181
  verbose
181
182
  });
182
183
  }
184
+
185
+ if (!await pathExists(path.join(process.cwd(), 'app', 'etc'))) {
186
+ await fs.promises.mkdir(path.join(process.cwd(), 'app', 'etc'), {
187
+ recursive: true
188
+ });
189
+ }
183
190
  try {
184
191
  await runComposerCommand('install',
185
192
  {
@@ -12,7 +12,7 @@ const logger = require('@scandipwa/scandipwa-dev-utils/logger');
12
12
  * @returns {import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
13
13
  */
14
14
  const installMagento = ({ isDbEmpty = false } = {}) => ({
15
- title: 'Installing magento',
15
+ title: 'Installing Magento in Database',
16
16
  task: async (ctx, task) => {
17
17
  if (isDbEmpty) {
18
18
  task.output = 'No Magento is installed in DB!\nInstalling...';
@@ -23,8 +23,47 @@ const installMagento = ({ isDbEmpty = false } = {}) => ({
23
23
  docker,
24
24
  magentoConfiguration
25
25
  },
26
- ports
26
+ ports,
27
+ mysqlConnection
27
28
  } = ctx;
29
+
30
+ const response = await mysqlConnection.query(
31
+ 'select * from admin_user where username=\'admin\';'
32
+ );
33
+
34
+ const usersWithUsernameAdmin = response && response.length > 0 && response[0];
35
+
36
+ if (usersWithUsernameAdmin && usersWithUsernameAdmin.length > 0) {
37
+ const confirmDeleteAdminUsers = await task.prompt({
38
+ type: 'Select',
39
+ message: `In order to install Magento in database you will need to delete admin user with username ${logger.style.command('admin')}`,
40
+ choices: [
41
+ {
42
+ name: 'delete-all',
43
+ message: `Delete all admin users (${logger.style.code('Recommended')})`
44
+ },
45
+ {
46
+ name: 'delete-only-admin',
47
+ message: `Delete only admin user with ${logger.style.command('admin')} username`
48
+ }
49
+ ]
50
+ });
51
+
52
+ await mysqlConnection.query('SET FOREIGN_KEY_CHECKS = 0;');
53
+
54
+ if (confirmDeleteAdminUsers === 'delete-all') {
55
+ await mysqlConnection.query(`
56
+ TRUNCATE TABLE admin_user;
57
+ `);
58
+ } else {
59
+ await mysqlConnection.query(`
60
+ DELETE FROM admin_user WHERE username='admin';
61
+ `);
62
+ }
63
+
64
+ await mysqlConnection.query('SET FOREIGN_KEY_CHECKS = 1;');
65
+ }
66
+
28
67
  const { mysql: { env } } = docker.getContainers(ports);
29
68
  const envPhpData = await envPhpToJson(process.cwd(), {
30
69
  magentoVersion: ctx.magentoVersion
@@ -82,13 +82,15 @@ const migrateDatabase = (options = {}) => ({
82
82
  case 1: {
83
83
  if (options.onlyInstallMagento) {
84
84
  ctx.isSetupUpgradeNeeded = false;
85
- return task.newListr(
86
- installMagentoProject()
87
- );
85
+ return task.newListr([
86
+ installMagentoProject(),
87
+ installMagento()
88
+ ]);
88
89
  }
89
90
 
90
91
  return task.newListr([
91
92
  installMagentoProject(),
93
+ installMagento(),
92
94
  updateEnvPHP(),
93
95
  varnishConfigSetup(),
94
96
  configureElasticsearch(),
@@ -78,6 +78,17 @@ const gettingMySQLConnection = () => ({
78
78
  }
79
79
  });
80
80
 
81
+ /**
82
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
83
+ */
84
+ const terminatingExistingConnection = () => ({
85
+ title: 'Terminating existing MySQL connection',
86
+ skip: (ctx) => !ctx.mysqlConnection,
87
+ task: (ctx) => {
88
+ ctx.mysqlConnection.destroy();
89
+ }
90
+ });
91
+
81
92
  /**
82
93
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
83
94
  */
@@ -87,6 +98,7 @@ const connectToMySQL = () => ({
87
98
  task: (ctx, task) => task.newListr([
88
99
  waitForMySQLInitialization(),
89
100
  createMagentoDatabase(),
101
+ terminatingExistingConnection(),
90
102
  gettingMySQLConnection()
91
103
  ], {
92
104
  concurrent: false,
@@ -2,23 +2,100 @@
2
2
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
3
3
  const KnownError = require('../../errors/known-error');
4
4
  const UnknownError = require('../../errors/unknown-error');
5
- const { execAsyncSpawn } = require('../../util/exec-async-command');
5
+ const { execAsyncSpawn, execCommandTask } = require('../../util/exec-async-command');
6
6
  const pathExists = require('../../util/path-exists');
7
+ const connectToMySQL = require('./connect-to-mysql');
7
8
 
8
9
  /**
9
10
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
10
11
  */
11
- const importDumpToMySQL = () => ({
12
- title: 'Importing Database Dump To MySQL',
12
+ const copyDatabaseDumpIntoContainer = () => ({
13
+ title: 'Copying database dump into container',
13
14
  task: async (ctx, task) => {
14
- if (!await pathExists(ctx.importDb)) {
15
- throw new KnownError(`Dump file at ${ctx.importDb} does not exist. Please provide correct relative path to the file`);
16
- }
15
+ const { config: { docker }, ports } = ctx;
16
+ const { mysql } = docker.getContainers(ports);
17
17
 
18
+ return task.newListr(
19
+ execCommandTask(`docker cp ${ctx.importDb} ${mysql.name}:/dump.sql`, {
20
+ logOutput: true
21
+ })
22
+ );
23
+ }
24
+ });
25
+
26
+ /**
27
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
28
+ */
29
+ const runSetGlobalLogBinTrustFunctionCreatorsCommand = () => ({
30
+ task: async (ctx, task) => {
18
31
  const { config: { docker }, ports } = ctx;
32
+ const { mysql } = docker.getContainers(ports);
19
33
 
34
+ return task.newListr(
35
+ execCommandTask(`docker exec ${mysql.name} bash -c 'mysql -uroot -p${mysql.env.MYSQL_ROOT_PASSWORD} -e "SET GLOBAL log_bin_trust_function_creators = 1;"'`)
36
+ );
37
+ }
38
+ });
39
+
40
+ /**
41
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
42
+ */
43
+ const deleteDatabaseBeforeImportingDumpPrompt = () => ({
44
+ title: 'Deleting magento database before importing dump',
45
+ task: async (ctx, task) => {
46
+ const deleteDatabaseMagentoChoice = await task.prompt({
47
+ type: 'Select',
48
+ message: `Before importing database dump, would you like to delete existing database?
49
+
50
+ It is possible that dump might interfere with existing data in database.
51
+
52
+ Note that you will lose your existing database!`,
53
+ choices: [
54
+ {
55
+ name: 'delete',
56
+ message: 'YES I AM SURE I WANT TO DELETE magento DATABASE!'
57
+ },
58
+ {
59
+ name: 'skip',
60
+ message: 'Skip this step'
61
+ }
62
+ ]
63
+ });
64
+
65
+ if (deleteDatabaseMagentoChoice === 'delete') {
66
+ await ctx.mysqlConnection.query('DROP DATABASE IF EXISTS magento;');
67
+ await ctx.mysqlConnection.query('CREATE DATABASE magento;');
68
+ return;
69
+ }
70
+ task.skip();
71
+ }
72
+ });
73
+
74
+ /**
75
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
76
+ */
77
+ const executeImportDumpSQL = () => ({
78
+ task: async (ctx, task) => {
79
+ const { config: { docker }, ports } = ctx;
20
80
  const { mysql } = docker.getContainers(ports);
21
81
 
82
+ const userCredentialsForMySQLCLI = await task.prompt({
83
+ type: 'Select',
84
+ message: 'Which user do you want to use to import db in MySQL client?',
85
+ choices: [
86
+ {
87
+ name: `--user=root --password=${mysql.env.MYSQL_ROOT_PASSWORD}`,
88
+ message: `root (${logger.style.command('Probably safest option')})`
89
+ },
90
+ {
91
+ name: `--user=${mysql.env.MYSQL_USER} --password=${mysql.env.MYSQL_PASSWORD}`,
92
+ message: `${mysql.env.MYSQL_USER}`
93
+ }
94
+ ]
95
+ });
96
+
97
+ const importCommand = `docker exec ${mysql.name} bash -c "mysql ${userCredentialsForMySQLCLI} magento < ./dump.sql"`;
98
+
22
99
  const startImportTime = Date.now();
23
100
  const tickInterval = setInterval(() => {
24
101
  task.title = `Importing Database Dump To MySQL, ${Math.floor((Date.now() - startImportTime) / 1000)}s in progress...`;
@@ -26,18 +103,7 @@ const importDumpToMySQL = () => ({
26
103
 
27
104
  try {
28
105
  await execAsyncSpawn(
29
- `docker cp ${ctx.importDb} ${mysql.name}:/dump.sql`
30
- );
31
-
32
- await execAsyncSpawn(
33
- `docker exec ${mysql.name} bash -c 'mysql -uroot -p${mysql.env.MYSQL_ROOT_PASSWORD} -e "SET GLOBAL log_bin_trust_function_creators = 1;"'`
34
- );
35
-
36
- /**
37
- * Using `mysql` instead of `mysqlimport` because `mysqlimport` has permission issues during import
38
- */
39
- await execAsyncSpawn(
40
- `docker exec ${mysql.name} bash -c "mysql -umagento -pmagento magento < ./dump.sql"`,
106
+ importCommand,
41
107
  {
42
108
  callback: (t) => {
43
109
  task.output = t;
@@ -54,15 +120,42 @@ You can try replacing all occurrences of ${logger.style.misc('utf8mb4_0900_ai_ci
54
120
  }
55
121
 
56
122
  throw new UnknownError(`Unexpected error during dump import.\n\n${e}`);
123
+ } finally {
124
+ clearInterval(tickInterval);
57
125
  }
58
-
59
- clearInterval(tickInterval);
60
-
61
- task.title = 'Database imported!';
62
126
  },
63
127
  options: {
64
128
  bottomBar: 10
65
129
  }
66
130
  });
67
131
 
132
+ /**
133
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
134
+ */
135
+ const importDumpToMySQL = () => ({
136
+ title: 'Importing Database Dump To MySQL',
137
+ task: async (ctx, task) => {
138
+ if (!await pathExists(ctx.importDb)) {
139
+ throw new KnownError(`Dump file at ${ctx.importDb} does not exist. Please provide correct relative path to the file`);
140
+ }
141
+
142
+ return task.newListr([
143
+ copyDatabaseDumpIntoContainer(),
144
+ deleteDatabaseBeforeImportingDumpPrompt(),
145
+ runSetGlobalLogBinTrustFunctionCreatorsCommand(),
146
+ executeImportDumpSQL(),
147
+ connectToMySQL(),
148
+ {
149
+ task: () => {
150
+ task.title = 'Database imported!';
151
+ }
152
+ }
153
+ ], {
154
+ rendererOptions: {
155
+ collapse: false
156
+ }
157
+ });
158
+ }
159
+ });
160
+
68
161
  module.exports = importDumpToMySQL;
@@ -12,10 +12,10 @@ const checkRosetta = require('./rosetta');
12
12
  const checkRequirements = () => ({
13
13
  title: 'Checking requirements',
14
14
  task: (ctx, task) => task.newListr([
15
- // checking if user is on supported platform
16
- checkPlatform(),
17
15
  // check if rosetta 2 is installed or not on m1 macs
18
16
  checkRosetta(),
17
+ // checking if user is on supported platform
18
+ checkPlatform(),
19
19
  // check the Docker installation
20
20
  checkDocker(),
21
21
  // check for Node.js version
@@ -120,8 +120,8 @@ const configureProject = () => ({
120
120
  installPrestissimo(),
121
121
  installMagentoProject(),
122
122
  enableMagentoComposerPlugins(),
123
- startServices(),
124
123
  startPhpFpm(),
124
+ startServices(),
125
125
  connectToMySQL()
126
126
  ])
127
127
  });
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": "1.16.0-alpha.4",
6
+ "version": "1.16.0",
7
7
  "main": "./index.js",
8
8
  "types": "./typings/index.d.ts",
9
9
  "license": "OSL-3.0",
@@ -53,5 +53,5 @@
53
53
  "mysql",
54
54
  "scandipwa"
55
55
  ],
56
- "gitHead": "987f793ba2d0bb3bcabea54d3b996a5204222738"
56
+ "gitHead": "c070162301e655d6b768449d641736fbaf0ebe4b"
57
57
  }