@scandipwa/magento-scripts 1.16.0 → 2.0.0-alpha.1

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 (225) hide show
  1. package/lib/commands/cli.js +4 -6
  2. package/lib/commands/execute.js +29 -4
  3. package/lib/commands/import-db.js +1 -1
  4. package/lib/commands/logs.js +1 -1
  5. package/lib/commands/start.js +38 -20
  6. package/lib/commands/status.js +2 -0
  7. package/lib/config/docker.js +98 -83
  8. package/lib/config/get-project-configuration.js +3 -1
  9. package/lib/config/index.js +10 -7
  10. package/lib/config/magento/required-php-extensions/index.js +29 -0
  11. package/lib/config/magento/required-php-extensions/magento-2.3.js +19 -0
  12. package/lib/config/magento/required-php-extensions/magento-2.4.js +29 -0
  13. package/lib/config/php/base-repo.js +3 -0
  14. package/lib/config/php/extensions/apcu.js +12 -0
  15. package/lib/config/php/extensions/bcmath.js +7 -0
  16. package/lib/config/php/extensions/curl.js +11 -0
  17. package/lib/config/php/extensions/gd.js +14 -0
  18. package/lib/config/php/extensions/index.js +18 -2
  19. package/lib/config/php/extensions/intl.js +10 -0
  20. package/lib/config/php/extensions/opcache.js +10 -0
  21. package/lib/config/php/extensions/pdo_mysql.js +7 -0
  22. package/lib/config/php/extensions/soap.js +10 -0
  23. package/lib/config/php/extensions/sodium.js +10 -0
  24. package/lib/config/php/extensions/xdebug.js +8 -5
  25. package/lib/config/php/extensions/xsl.js +10 -0
  26. package/lib/config/php/extensions/zip.js +10 -0
  27. package/lib/config/php/{releases → versions}/index.js +0 -0
  28. package/lib/config/php/versions/php-7.2.js +23 -0
  29. package/lib/config/php/versions/php-7.3.js +23 -0
  30. package/lib/config/php/versions/php-7.4.js +23 -0
  31. package/lib/config/php/versions/php-8.1.js +23 -0
  32. package/lib/config/php-config.js +8 -12
  33. package/lib/config/port-config.js +2 -6
  34. package/lib/config/services/elasticsearch/base-repo.js +3 -0
  35. package/lib/config/services/elasticsearch/versions/elasticsearch-6.8.js +23 -0
  36. package/lib/config/services/elasticsearch/versions/index.js +5 -0
  37. package/lib/config/templates/magentorc.template +5 -5
  38. package/lib/config/templates/mariadb.template.cnf +191 -0
  39. package/lib/config/templates/php-fpm.template.conf +3 -3
  40. package/lib/config/templates/php.template.ini +12 -6
  41. package/lib/config/templates/ssl-terminator.template.conf +1 -1
  42. package/lib/config/templates/vscode-launch.template.json +3 -1
  43. package/lib/config/versions/magento-2.3.0.js +10 -5
  44. package/lib/config/versions/magento-2.3.1.js +10 -5
  45. package/lib/config/versions/magento-2.3.2-p1.js +43 -0
  46. package/lib/config/versions/magento-2.3.2-p2.js +10 -5
  47. package/lib/config/versions/magento-2.3.2.js +10 -5
  48. package/lib/config/versions/magento-2.3.3-p1.js +10 -5
  49. package/lib/config/versions/magento-2.3.3.js +10 -5
  50. package/lib/config/versions/magento-2.3.4-p1.js +43 -0
  51. package/lib/config/versions/magento-2.3.4-p2.js +10 -5
  52. package/lib/config/versions/magento-2.3.4.js +10 -5
  53. package/lib/config/versions/magento-2.3.5-p1.js +8 -2
  54. package/lib/config/versions/magento-2.3.5-p2.js +8 -2
  55. package/lib/config/versions/magento-2.3.5.js +8 -2
  56. package/lib/config/versions/magento-2.3.6-p1.js +8 -2
  57. package/lib/config/versions/magento-2.3.6.js +8 -2
  58. package/lib/config/versions/magento-2.3.7-p1.js +8 -2
  59. package/lib/config/versions/magento-2.3.7-p2.js +8 -2
  60. package/lib/config/versions/magento-2.3.7-p3.js +8 -2
  61. package/lib/config/versions/magento-2.3.7.js +8 -2
  62. package/lib/config/versions/magento-2.4.0-p1.js +9 -3
  63. package/lib/config/versions/magento-2.4.0.js +9 -3
  64. package/lib/config/versions/magento-2.4.1-p1.js +6 -5
  65. package/lib/config/versions/magento-2.4.1.js +9 -2
  66. package/lib/config/versions/magento-2.4.2-p1.js +6 -5
  67. package/lib/config/versions/magento-2.4.2-p2.js +6 -6
  68. package/lib/config/versions/magento-2.4.2.js +6 -6
  69. package/lib/config/versions/magento-2.4.3-p1.js +7 -7
  70. package/lib/config/versions/magento-2.4.3-p2.js +7 -7
  71. package/lib/config/versions/magento-2.4.3.js +7 -7
  72. package/lib/config/versions/magento-2.4.4.js +9 -2
  73. package/lib/tasks/cleanup.js +3 -3
  74. package/lib/tasks/composer/index.js +14 -104
  75. package/lib/tasks/database/connect-to-database.js +117 -0
  76. package/lib/tasks/database/create-magento-database.js +18 -0
  77. package/lib/tasks/{mysql → database}/dump-theme-config.js +3 -3
  78. package/lib/tasks/{mysql → database}/fix-db.js +2 -2
  79. package/lib/tasks/{mysql/import-dump-to-mysql.js → database/import-dump-to-database.js} +65 -22
  80. package/lib/tasks/{mysql → database}/import-remote-db/index.js +0 -0
  81. package/lib/tasks/{mysql/import-remote-db/ssh/mysqldump-command.js → database/import-remote-db/ssh/database-dump-command.js} +2 -2
  82. package/lib/tasks/{mysql → database}/import-remote-db/ssh/index.js +0 -0
  83. package/lib/tasks/{mysql → database}/import-remote-db/ssh/readymage.js +4 -4
  84. package/lib/tasks/{mysql → database}/import-remote-db/ssh/regular-server.js +2 -2
  85. package/lib/tasks/{mysql → database}/index.js +2 -2
  86. package/lib/tasks/{mysql → database}/magento-tables.js +0 -0
  87. package/lib/tasks/{mysql → database}/restore-theme-config.js +4 -4
  88. package/lib/tasks/docker/api.d.ts +71 -0
  89. package/lib/tasks/docker/api.js +30 -0
  90. package/lib/tasks/docker/containers/container-api.d.ts +128 -0
  91. package/lib/tasks/docker/containers/container-api.js +153 -0
  92. package/lib/tasks/docker/containers/index.js +19 -0
  93. package/lib/tasks/docker/containers/tasks.js +215 -0
  94. package/lib/tasks/docker/convert-legacy-volumes.js +15 -10
  95. package/lib/tasks/docker/convert-mysql-to-mariadb.js +284 -0
  96. package/lib/tasks/docker/image/image-api.d.ts +34 -0
  97. package/lib/tasks/docker/image/image-api.js +49 -0
  98. package/lib/tasks/docker/image/index.js +5 -0
  99. package/lib/tasks/docker/index.js +1 -13
  100. package/lib/tasks/docker/network/index.js +7 -0
  101. package/lib/tasks/docker/network/network-api.d.ts +103 -0
  102. package/lib/tasks/docker/network/network-api.js +99 -0
  103. package/lib/tasks/docker/{network.js → network/tasks.js} +17 -10
  104. package/lib/tasks/docker/project-image-builder.js +167 -0
  105. package/lib/tasks/docker/volume/index.js +8 -0
  106. package/lib/tasks/docker/{volumes.js → volume/tasks.js} +5 -19
  107. package/lib/tasks/docker/volume/volume-api.d.ts +39 -0
  108. package/lib/tasks/docker/volume/volume-api.js +66 -0
  109. package/lib/tasks/execute/index.js +5 -2
  110. package/lib/tasks/file-system/create-mariadb-config.js +23 -0
  111. package/lib/tasks/file-system/create-nginx-config.js +2 -3
  112. package/lib/tasks/file-system/create-php-config.js +20 -5
  113. package/lib/tasks/file-system/create-php-fpm-config.js +8 -4
  114. package/lib/tasks/file-system/create-phpstorm-config/exclude-folder-config.js +41 -29
  115. package/lib/tasks/file-system/create-phpstorm-config/index.js +2 -0
  116. package/lib/tasks/file-system/create-phpstorm-config/keys.js +15 -1
  117. package/lib/tasks/file-system/create-phpstorm-config/php-config/index.js +4 -1
  118. package/lib/tasks/file-system/create-phpstorm-config/php-config/php-config.js +3 -3
  119. package/lib/tasks/file-system/create-phpstorm-config/php-config/php-interpreters-config.js +81 -0
  120. package/lib/tasks/file-system/create-phpstorm-config/php-docker-settings-config/index.js +42 -0
  121. package/lib/tasks/file-system/create-phpstorm-config/php-docker-settings-config/php-docker-settings-config.js +9 -0
  122. package/lib/tasks/file-system/create-phpstorm-config/php-docker-settings-config/setup-php-docker-container-settings-config.js +66 -0
  123. package/lib/tasks/file-system/create-phpstorm-config/setup-xml-structure.js +11 -9
  124. package/lib/tasks/file-system/create-phpstorm-config/stylelint-config.js +2 -1
  125. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/composer-settings-config.js +15 -30
  126. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/index.js +24 -5
  127. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/mess-detector-project-configuration-config.js +50 -0
  128. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-code-sniffer-project-configuration-config.js +50 -0
  129. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-cs-fixer-project-configuration-config.js +50 -0
  130. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-debug-general-config.js +15 -15
  131. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-server-config.js +29 -3
  132. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-stan-project-configuration-config.js.js +50 -0
  133. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-workspace-project-configuration-config.js +42 -0
  134. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/psalm-project-configuration-config.js.js +50 -0
  135. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/workspace-config.js +0 -2
  136. package/lib/tasks/file-system/create-ssl-terminator-config.js +4 -2
  137. package/lib/tasks/file-system/create-vscode-config.js +57 -42
  138. package/lib/tasks/file-system/index.js +5 -2
  139. package/lib/tasks/import-dump.js +6 -6
  140. package/lib/tasks/link.js +5 -4
  141. package/lib/tasks/magento/install-magento-project.js +31 -63
  142. package/lib/tasks/magento/setup-magento/adjust-full-page-cache.js +4 -4
  143. package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +7 -3
  144. package/lib/tasks/magento/setup-magento/create-admin.js +5 -6
  145. package/lib/tasks/magento/setup-magento/delete-admin-users.js +2 -2
  146. package/lib/tasks/magento/setup-magento/delete-customers.js +4 -4
  147. package/lib/tasks/magento/setup-magento/delete-orders.js +4 -4
  148. package/lib/tasks/magento/setup-magento/disable-2fa.js +3 -5
  149. package/lib/tasks/magento/setup-magento/disable-maintenance-mode.js +3 -4
  150. package/lib/tasks/magento/setup-magento/increase-admin-session-lifetime.js +2 -2
  151. package/lib/tasks/magento/setup-magento/index.js +3 -3
  152. package/lib/tasks/magento/setup-magento/install-magento.js +47 -40
  153. package/lib/tasks/magento/setup-magento/migrate-database.js +7 -14
  154. package/lib/tasks/magento/setup-magento/set-base-url.js +2 -2
  155. package/lib/tasks/magento/setup-magento/set-deployment-mode.js +4 -4
  156. package/lib/tasks/magento/setup-magento/set-url-rewrite.js +2 -2
  157. package/lib/tasks/magento/setup-magento/varnish-config.js +11 -9
  158. package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +128 -3
  159. package/lib/tasks/php/php-container.js +108 -0
  160. package/lib/tasks/php/update-env-php.js +39 -21
  161. package/lib/tasks/php/update-env.php +66 -61
  162. package/lib/tasks/php/working_health_check.php +85 -0
  163. package/lib/tasks/requirements/{composer.js → composer-credentials.js} +3 -1
  164. package/lib/tasks/requirements/docker/index.js +15 -12
  165. package/lib/tasks/requirements/docker/performance.js +54 -0
  166. package/lib/tasks/requirements/docker/version.js +8 -8
  167. package/lib/tasks/requirements/index.js +5 -8
  168. package/lib/tasks/requirements/php-version.js +8 -116
  169. package/lib/tasks/requirements/platform.js +12 -25
  170. package/lib/tasks/start.js +24 -51
  171. package/lib/tasks/status/index.js +8 -12
  172. package/lib/tasks/stop.js +0 -2
  173. package/lib/tasks/theme/install-theme.js +1 -1
  174. package/lib/tasks/theme/link-theme.js +2 -2
  175. package/lib/tasks/theme/symlink-theme.js +2 -3
  176. package/lib/util/config-file-validator.js +27 -13
  177. package/lib/util/config-php-json.js +13 -4
  178. package/lib/util/database.js +7 -7
  179. package/lib/util/dockerfile-builder/build-instructions.js +197 -0
  180. package/lib/util/dockerfile-builder/index.js +276 -0
  181. package/lib/util/dockerfile-builder/types.d.ts +123 -0
  182. package/lib/util/env-php-json.js +10 -6
  183. package/lib/util/exec-async-command.js +3 -9
  184. package/lib/util/macos-version.js +20 -0
  185. package/lib/util/magento-task.js +3 -4
  186. package/lib/util/nginx-logs-parser.js +122 -0
  187. package/lib/util/php-task.js +3 -6
  188. package/lib/util/run-composer.js +6 -14
  189. package/lib/util/run-container-image.js +17 -0
  190. package/lib/util/run-magento.js +6 -14
  191. package/lib/util/run-php.js +6 -17
  192. package/package.json +9 -9
  193. package/typings/context.d.ts +7 -13
  194. package/typings/index.d.ts +67 -85
  195. package/yarn-error.log +9660 -0
  196. package/lib/config/composer.js +0 -11
  197. package/lib/config/php/extensions/libsodium.js +0 -36
  198. package/lib/config/php/releases/php-7.2.js +0 -25
  199. package/lib/config/php/releases/php-7.3.js +0 -25
  200. package/lib/config/php/releases/php-7.4.js +0 -23
  201. package/lib/config/php/releases/php-8.1.js +0 -25
  202. package/lib/config/phpbrew.js +0 -12
  203. package/lib/tasks/composer/install-prestissimo.js +0 -103
  204. package/lib/tasks/docker/containers.js +0 -231
  205. package/lib/tasks/mysql/connect-to-mysql.js +0 -114
  206. package/lib/tasks/mysql/create-magento-database.js +0 -18
  207. package/lib/tasks/php/bundled-extensions.js +0 -27
  208. package/lib/tasks/php/compile-options.js +0 -56
  209. package/lib/tasks/php/compile.js +0 -55
  210. package/lib/tasks/php/configure.js +0 -89
  211. package/lib/tasks/php/extensions/disable.js +0 -49
  212. package/lib/tasks/php/extensions/enable.js +0 -52
  213. package/lib/tasks/php/extensions/index.js +0 -80
  214. package/lib/tasks/php/extensions/install.js +0 -54
  215. package/lib/tasks/php/index.js +0 -79
  216. package/lib/tasks/php/install-sodium.js +0 -93
  217. package/lib/tasks/php/update-phpbrew.js +0 -45
  218. package/lib/tasks/php/validate-php.js +0 -67
  219. package/lib/tasks/php-fpm/get-process-id.js +0 -14
  220. package/lib/tasks/php-fpm/index.js +0 -4
  221. package/lib/tasks/php-fpm/start-php-fpm.js +0 -49
  222. package/lib/tasks/php-fpm/stop-php-fpm.js +0 -48
  223. package/lib/tasks/requirements/phpbrew/index.js +0 -61
  224. package/lib/tasks/requirements/phpbrew/install.js +0 -159
  225. package/lib/tasks/requirements/phpbrew/version.js +0 -28
@@ -1,6 +1,5 @@
1
1
  const containers = require('./containers');
2
2
  const network = require('./network');
3
- const volumes = require('./volumes');
4
3
 
5
4
  /**
6
5
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -8,17 +7,6 @@ const volumes = require('./volumes');
8
7
  const startServices = () => ({
9
8
  title: 'Starting Docker services',
10
9
  task: (ctx, task) => task.newListr([
11
- {
12
- title: 'Preparing services',
13
- task: (ctx, task) => task.newListr([
14
- network.createNetwork(),
15
- volumes.createVolumes()
16
- ], {
17
- concurrent: true,
18
- exitOnError: true,
19
- ctx
20
- })
21
- },
22
10
  containers.startContainers(),
23
11
  containers.checkContainersAreRunning()
24
12
  ], {
@@ -33,7 +21,7 @@ const startServices = () => ({
33
21
  const stopServices = () => ({
34
22
  task: (ctx, task) => task.newListr([
35
23
  containers.stopContainers(),
36
- network.removeNetwork()
24
+ network.tasks.removeNetwork()
37
25
  ])
38
26
  });
39
27
 
@@ -0,0 +1,7 @@
1
+ const networkApi = require('./network-api');
2
+ const tasks = require('./tasks');
3
+
4
+ module.exports = {
5
+ networkApi,
6
+ tasks
7
+ };
@@ -0,0 +1,103 @@
1
+ import { ExecAsyncSpawnOptions } from '../../../util/exec-async-command';
2
+
3
+ export interface NetworkLsOptions<T extends boolean = false> {
4
+ filter?: string | string[]
5
+ format?: string
6
+ formatToJSON?: T
7
+ quiet?: boolean
8
+ noTrunc?: boolean
9
+ }
10
+
11
+ export interface NetworkLsResult {
12
+ CreatedAt: string
13
+ Driver: string
14
+ ID: string
15
+ IPv6: string
16
+ Internal: string
17
+ Labels: string
18
+ Name: string
19
+ Scope: string
20
+ }
21
+
22
+ export function ls(
23
+ options?: NetworkLsOptions,
24
+ execOptions?: ExecAsyncSpawnOptions<false>
25
+ ): Promise<string>
26
+ export function ls(
27
+ options?: NetworkLsOptions<true>,
28
+ execOptions?: ExecAsyncSpawnOptions<false>
29
+ ): Promise<NetworkLsResult[]>
30
+
31
+ export interface NetworkInspectOptions<T extends boolean = false> {
32
+ network: string | string[]
33
+ format?: string
34
+ formatToJSON?: T
35
+ verbose?: boolean
36
+ }
37
+
38
+ export interface NetworkInspectResult {
39
+ Name: string
40
+ Id: string
41
+ Created: string
42
+ Scope: string
43
+ EnableIPv6: boolean
44
+ IPAM: {
45
+ Driver: string
46
+ Options: Record<string, unknown>
47
+ Config: {
48
+ Subnet: string
49
+ Gateway: string
50
+ }[]
51
+ }
52
+ Internal: boolean
53
+ Attachable: boolean
54
+ Ingress: boolean
55
+ ConfigFrom: {
56
+ Network: string
57
+ }
58
+ ConfigOnly: boolean
59
+ Containers: Record<string, {
60
+ Name: string
61
+ EndpointID: string
62
+ MacAddress: string
63
+ IPv4Address: string
64
+ IPv6Address: string
65
+ }>
66
+ Options: Record<string, unknown>
67
+ Labels: Record<string, unknown>
68
+ }
69
+
70
+ export function inspect(
71
+ options?: NetworkInspectOptions,
72
+ execOptions?: ExecAsyncSpawnOptions<false>
73
+ ): Promise<string>
74
+
75
+ export function inspect(
76
+ options?: NetworkInspectOptions<true>,
77
+ execOptions?: ExecAsyncSpawnOptions<false>
78
+ ): Promise<NetworkInspectResult>
79
+
80
+ export interface NetworkCreateOptions {
81
+ network: string | string[]
82
+ attachable?: boolean
83
+ auxAddress?: string
84
+ configFrom?: string
85
+ configOnly?: string
86
+ driver?: string
87
+ gateway?: string
88
+ ingress?: boolean
89
+ internal?: boolean
90
+ ipRange?: string
91
+ ipamDriver?: string
92
+ ipamOpt?: string
93
+ ipv6?: boolean
94
+ label?: string
95
+ opt?: string
96
+ scope?: string
97
+ subnet?: string
98
+ }
99
+
100
+ export function create(
101
+ options?: NetworkCreateOptions,
102
+ execOptions?: ExecAsyncSpawnOptions<false>
103
+ ): Promise<string>
@@ -0,0 +1,99 @@
1
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
2
+
3
+ /**
4
+ * @param {import('./network-api').NetworkLsOptions} options
5
+ * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
6
+ */
7
+ const ls = async (options, execOptions = {}) => {
8
+ const {
9
+ filter,
10
+ format,
11
+ formatToJSON = false,
12
+ noTrunc,
13
+ quiet
14
+ } = options;
15
+
16
+ const formatArg = !formatToJSON && format
17
+ ? `--format=${format}`
18
+ : formatToJSON && '--format=\'{{json .}}\'';
19
+ const filterArg = filter && typeof filter === 'string'
20
+ ? `--filter=${filter}`
21
+ : filter && Array.isArray(filter) && filter.every((f) => typeof f === 'string') && filter.map((f) => `--filter=${f}`).join(' ');
22
+ const noTruncArg = noTrunc && '--no-trunc';
23
+ const quietArg = quiet && '--quiet';
24
+ const args = [
25
+ filterArg,
26
+ formatArg,
27
+ noTruncArg,
28
+ quietArg
29
+ ].filter(Boolean).join(' ');
30
+
31
+ if (formatToJSON) {
32
+ const result = await execAsyncSpawn(`docker network ls ${args}`, execOptions);
33
+ return JSON.parse(`[${result.split('\n').join(', ')}]`);
34
+ }
35
+
36
+ return execAsyncSpawn(`docker network ls ${args}`, execOptions);
37
+ };
38
+
39
+ /**
40
+ * @param {import('./network-api').NetworkInspectOptions} options
41
+ * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
42
+ */
43
+ const inspect = async (options, execOptions = {}) => {
44
+ const {
45
+ network,
46
+ format,
47
+ formatToJSON = false,
48
+ verbose
49
+ } = options;
50
+
51
+ const formatArg = !formatToJSON && format
52
+ ? `--format=${format}`
53
+ : formatToJSON && '--format=\'{{json .}}\'';
54
+ const verboseArg = verbose && '--verbose';
55
+ const networks = typeof network === 'string'
56
+ ? network
57
+ : network.join(' ');
58
+
59
+ const args = [
60
+ formatArg,
61
+ verboseArg
62
+ ].filter(Boolean).join(' ');
63
+
64
+ if (formatToJSON) {
65
+ const result = await execAsyncSpawn(`docker network inspect ${args} ${networks}`, execOptions);
66
+ return JSON.parse(result);
67
+ }
68
+
69
+ return execAsyncSpawn(`docker network inspect ${args} ${networks}`, execOptions);
70
+ };
71
+
72
+ /**
73
+ * @param {import('./network-api').NetworkCreateOptions} options
74
+ * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
75
+ */
76
+ const create = async (options, execOptions = {}) => {
77
+ const {
78
+ network,
79
+ driver
80
+ } = options;
81
+
82
+ const networks = typeof network === 'string'
83
+ ? network
84
+ : network.join(' ');
85
+
86
+ const driverArg = driver && `--driver='${ driver }'`;
87
+
88
+ const args = [
89
+ driverArg
90
+ ].filter(Boolean).join(' ');
91
+
92
+ return execAsyncSpawn(`docker network create ${args} ${networks}`, execOptions);
93
+ };
94
+
95
+ module.exports = {
96
+ ls,
97
+ inspect,
98
+ create
99
+ };
@@ -1,21 +1,26 @@
1
1
  const logger = require('@scandipwa/scandipwa-dev-utils/logger');
2
- const KnownError = require('../../errors/known-error');
3
- const { execAsyncSpawn } = require('../../util/exec-async-command');
2
+ const KnownError = require('../../../errors/known-error');
3
+ const UnknownError = require('../../../errors/unknown-error');
4
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
5
+ const networkApi = require('./network-api');
4
6
 
5
7
  /**
6
- * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
8
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
7
9
  */
8
10
  const createNetwork = () => ({
9
11
  title: 'Deploying Docker network',
10
12
  task: async ({ config: { docker } }, task) => {
11
- const networkList = (await execAsyncSpawn("docker network ls --format '{{.Name}}'")).split('\n');
13
+ const networkList = await networkApi.ls({ formatToJSON: true });
12
14
 
13
- if (networkList.includes(docker.network.name)) {
15
+ if (networkList.some((network) => network.Name === docker.network.name)) {
14
16
  task.skip();
15
17
  return;
16
18
  }
17
19
  try {
18
- await execAsyncSpawn(`docker network create --driver=bridge ${ docker.network.name }`);
20
+ await networkApi.create({
21
+ network: docker.network.name,
22
+ driver: 'bridge'
23
+ });
19
24
  } catch (e) {
20
25
  if (e.includes('could not find an available, non-overlapping IPv4 address pool')) {
21
26
  const pruneNetworks = await task.prompt({
@@ -34,19 +39,21 @@ Do you want remove all custom networks not used by at least one container?`
34
39
  You need to delete unused networks yourself.
35
40
  Use command ${logger.style.command('docker network prune')}`);
36
41
  }
42
+
43
+ throw new UnknownError(`Unable to create network!\n\n${e}`);
37
44
  }
38
45
  }
39
46
  });
40
47
 
41
48
  /**
42
- * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
49
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
43
50
  */
44
51
  const removeNetwork = () => ({
45
52
  title: 'Removing Docker network',
46
53
  task: async ({ config: { docker } }, task) => {
47
- const networkList = (await execAsyncSpawn("docker network ls --format '{{.Name}}'")).split('\n');
54
+ const networkList = await networkApi.ls({ formatToJSON: true });
48
55
 
49
- if (!networkList.includes(docker.network.name)) {
56
+ if (!networkList.some((network) => network.Name === docker.network.name)) {
50
57
  task.skip();
51
58
  return;
52
59
  }
@@ -56,7 +63,7 @@ const removeNetwork = () => ({
56
63
  });
57
64
 
58
65
  /**
59
- * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
66
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
60
67
  */
61
68
  const pruneNetworks = () => ({
62
69
  title: 'Removing custom networks not used by at least one container',
@@ -0,0 +1,167 @@
1
+ const { DockerFileBuilder } = require('../../util/dockerfile-builder');
2
+ const semver = require('semver');
3
+ const { execAsyncSpawn } = require('../../util/exec-async-command');
4
+ const KnownError = require('../../errors/known-error');
5
+ const { runContainerImage } = require('../../util/run-container-image');
6
+
7
+ /**
8
+ * Get enabled extensions list with versions
9
+ * @param {string} imageWithTag
10
+ * @returns {Promise<{[key: string]: string}}>}
11
+ */
12
+ const getEnabledExtensionsFromImage = async (imageWithTag) => {
13
+ const output = await runContainerImage(
14
+ imageWithTag,
15
+ // eslint-disable-next-line quotes
16
+ `php -r 'foreach (get_loaded_extensions() as $extension) echo "$extension:" . phpversion($extension) . "\n";'`
17
+ );
18
+
19
+ return output
20
+ .split('\n')
21
+ .map((m) => {
22
+ // eslint-disable-next-line no-unused-vars
23
+ const [_, moduleName, moduleVersion] = m.match(/(.+):(.+)/i);
24
+
25
+ return [moduleName, moduleVersion];
26
+ })
27
+ .reduce((acc, [name, version]) => ({ ...acc, [name]: version }), {});
28
+ };
29
+
30
+ const addExtensionToBuilder = (builder, ctx) => ([extensionName, extensionInstructions]) => {
31
+ const { command, ...extensionInstructionsWithoutCommand } = extensionInstructions;
32
+ let runCommand = '';
33
+ if (typeof command === 'string') {
34
+ runCommand += ` ${command}`;
35
+ } else if (typeof command === 'function') {
36
+ runCommand += ` ${command({ ...extensionInstructionsWithoutCommand, ctx })}`;
37
+ } else {
38
+ runCommand += ` docker-php-ext-install ${extensionInstructionsWithoutCommand.name}`;
39
+ }
40
+ builder
41
+ .comment(`extension ${extensionName} installation command`)
42
+ .run(runCommand.trim());
43
+ };
44
+
45
+ /**
46
+ * @param {import('../../../typings/context').ListrContext} ctx
47
+ * @param {{ image: string, tag: string}} param1
48
+ */
49
+ const buildDockerFileInstructions = async (ctx, { image, tag }) => {
50
+ const { composer } = ctx.config.overridenConfiguration.configuration;
51
+ const existingPHPExtensions = await getEnabledExtensionsFromImage(`${image}:${tag}`);
52
+
53
+ const missingExtensions = Object.entries(
54
+ ctx.config.overridenConfiguration.configuration.php.extensions
55
+ ).filter(
56
+ ([extensionName, extensionInstructions]) => !Object.entries(existingPHPExtensions)
57
+ .map(([n, i]) => [n.toLowerCase(), i])
58
+ .some(
59
+ ([n]) => extensionName === n || (
60
+ extensionInstructions.alternativeName && extensionInstructions.alternativeName.map(
61
+ (s) => s.toLowerCase()
62
+ ).includes(n)
63
+ )
64
+ )
65
+ ).filter(([extensionName]) => extensionName.toLowerCase() !== 'xdebug');
66
+
67
+ const dockerFileInstructions = new DockerFileBuilder()
68
+ .comment('project image')
69
+ .from({ image, tag });
70
+
71
+ // install bash in image
72
+ dockerFileInstructions
73
+ .run('apk add --no-cache bash');
74
+
75
+ if (missingExtensions.length > 0) {
76
+ const allDependencies = missingExtensions.map(
77
+ ([_extensionName, extensionInstructions]) => (extensionInstructions.dependencies || [])
78
+ )
79
+ .reduce((acc, val) => acc.concat(val.filter((ex) => !acc.includes(ex))), []);
80
+
81
+ dockerFileInstructions.run(`apk add --no-cache ${allDependencies.join(' ')}`);
82
+ missingExtensions.forEach(addExtensionToBuilder(dockerFileInstructions, ctx));
83
+ }
84
+
85
+ const composerVersion = /^\d$/.test(composer.version)
86
+ ? `latest-${composer.version}.x`
87
+ : composer.version;
88
+
89
+ dockerFileInstructions
90
+ .comment('download composer')
91
+ .run(`curl https://getcomposer.org/download/${composerVersion}/composer.phar --output composer`)
92
+ .comment('make composer executable')
93
+ .run('chmod +x ./composer')
94
+ .comment('move composer to bin directory')
95
+ .run('mv composer /usr/local/bin/composer');
96
+
97
+ if (semver.satisfies(composer.version, '^1')) {
98
+ dockerFileInstructions
99
+ .comment('install prestissimo composer plugin')
100
+ .run('composer global require hirak/prestissimo');
101
+ }
102
+
103
+ dockerFileInstructions
104
+ .workDir(ctx.config.baseConfig.containerMagentoDir);
105
+
106
+ return dockerFileInstructions;
107
+ };
108
+
109
+ /**
110
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
111
+ */
112
+ const buildProjectImage = () => ({
113
+ title: 'Building Project Image',
114
+ task: async (ctx, task) => {
115
+ const containers = ctx.config.docker.getContainers(ctx.ports);
116
+ const [image, tag = 'latest'] = ctx.config.overridenConfiguration.configuration.php.baseImage.split(':');
117
+ const dockerFileInstructions = await buildDockerFileInstructions(ctx, { image, tag });
118
+
119
+ try {
120
+ await execAsyncSpawn(`docker build -t ${containers.php.image} -<<EOF
121
+ ${dockerFileInstructions.build()}
122
+ EOF`, {
123
+ callback: (r) => {
124
+ task.output = r;
125
+ }
126
+ });
127
+ } catch (e) {
128
+ throw new KnownError(`Unexpected error during project image building!\n\n${e}`);
129
+ }
130
+ },
131
+ options: {
132
+ bottomBar: 10
133
+ }
134
+ });
135
+
136
+ /**
137
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
138
+ */
139
+ const buildDebugProjectImage = () => ({
140
+ title: 'Building Debug Project Image',
141
+ task: async (ctx, task) => {
142
+ const containers = ctx.config.docker.getContainers(ctx.ports);
143
+ const [image, tag = 'latest'] = ctx.config.overridenConfiguration.configuration.php.debugImage.split(':');
144
+ const dockerFileInstructions = await buildDockerFileInstructions(ctx, { image, tag });
145
+
146
+ try {
147
+ await execAsyncSpawn(`docker build -t ${containers.php.debugImage} -<<EOF
148
+ ${dockerFileInstructions.build()}
149
+ EOF`, {
150
+ callback: (r) => {
151
+ task.output = r;
152
+ }
153
+ });
154
+ } catch (e) {
155
+ throw new KnownError(`Unexpected error during debug project image building!\n\n${e}`);
156
+ }
157
+ },
158
+ options: {
159
+ bottomBar: 10
160
+ }
161
+ });
162
+
163
+ module.exports = {
164
+ buildProjectImage,
165
+ buildDebugProjectImage,
166
+ getEnabledExtensionsFromImage
167
+ };
@@ -0,0 +1,8 @@
1
+ const volumeApi = require('./volume-api');
2
+ const { createVolumes, removeVolumes } = require('./tasks');
3
+
4
+ module.exports = {
5
+ createVolumes,
6
+ removeVolumes,
7
+ volumeApi
8
+ };
@@ -1,21 +1,8 @@
1
- const { execAsyncSpawn } = require('../../util/exec-async-command');
2
-
3
- const create = ({
4
- driver,
5
- opts = {},
6
- name
7
- }) => {
8
- let command = `docker volume create ${ Object.entries(opts).map(([name, value]) => `--opt ${name}=${value}`).join(' ') } `;
9
-
10
- if (driver) {
11
- command += `--driver ${ driver }`;
12
- }
13
-
14
- return execAsyncSpawn(`${ command } ${ name }`);
15
- };
1
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
2
+ const { create } = require('./volume-api');
16
3
 
17
4
  /**
18
- * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
5
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
19
6
  */
20
7
  const createVolumes = () => ({
21
8
  title: 'Creating volumes',
@@ -36,7 +23,7 @@ const createVolumes = () => ({
36
23
  });
37
24
 
38
25
  /**
39
- * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
26
+ * @type {() => import('listr2').ListrTask<import('../../../../typings/context').ListrContext>}
40
27
  */
41
28
  const removeVolumes = () => ({
42
29
  title: 'Removing volumes',
@@ -58,6 +45,5 @@ const removeVolumes = () => ({
58
45
 
59
46
  module.exports = {
60
47
  createVolumes,
61
- removeVolumes,
62
- createVolume: create
48
+ removeVolumes
63
49
  };
@@ -0,0 +1,39 @@
1
+ import { ExecAsyncSpawnOptions } from '../../../util/exec-async-command';
2
+
3
+ export interface VolumeLsOptions<T extends boolean = false> {
4
+ filter?: string | string[]
5
+ format?: string
6
+ formatToJSON?: T
7
+ quiet?: boolean
8
+ }
9
+
10
+ export interface VolumeLsResult {
11
+ Driver: string
12
+ Labels: string
13
+ Links: string
14
+ MountPoint: string
15
+ Name: string
16
+ Scope: string
17
+ Size: string
18
+ }
19
+
20
+ export function ls(
21
+ options?: VolumeLsOptions,
22
+ execOptions?: ExecAsyncSpawnOptions<false>
23
+ ): Promise<string>
24
+ export function ls(
25
+ options?: VolumeLsOptions<true>,
26
+ execOptions?: ExecAsyncSpawnOptions<false>
27
+ ): Promise<VolumeLsResult[]>
28
+
29
+ export interface VolumeCreateOptions {
30
+ driver?: string
31
+ label?: string
32
+ name: string
33
+ opt?: Record<string, string>
34
+ }
35
+
36
+ export function create(
37
+ options?: VolumeCreateOptions,
38
+ execOptions?: ExecAsyncSpawnOptions<false>
39
+ ): Promise<string>
@@ -0,0 +1,66 @@
1
+ const { execAsyncSpawn } = require('../../../util/exec-async-command');
2
+
3
+ /**
4
+ * @param {import('./volume-api').VolumeCreateOptions} options
5
+ * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
6
+ */
7
+ const create = async (options, execOptions = {}) => {
8
+ const {
9
+ driver,
10
+ label,
11
+ opt,
12
+ name
13
+ } = options;
14
+
15
+ const driverArg = driver && `--driver=${driver}`;
16
+ const labelArg = label && `--label=${label}`;
17
+ const optArg = opt && Object.entries(opt).map(([name, value]) => `--opt ${name}='${value}'`).join(' ');
18
+
19
+ const args = [
20
+ driverArg,
21
+ labelArg,
22
+ optArg,
23
+ name
24
+ ].filter(Boolean).join(' ');
25
+
26
+ return execAsyncSpawn(`docker volume create ${args}`, execOptions);
27
+ };
28
+
29
+ /**
30
+ * @param {import('./volume-api').VolumeLsOptions} options
31
+ * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
32
+ */
33
+ const ls = async (options, execOptions = {}) => {
34
+ const {
35
+ filter,
36
+ format,
37
+ formatToJSON = false,
38
+ quiet
39
+ } = options;
40
+
41
+ const formatArg = !formatToJSON && format
42
+ ? `--format=${format}`
43
+ : formatToJSON && '--format=\'{{json .}}\'';
44
+ const filterArg = filter && typeof filter === 'string'
45
+ ? `--filter=${filter}`
46
+ : filter && Array.isArray(filter) && filter.every((f) => typeof f === 'string') && filter.map((f) => `--filter=${f}`).join(' ');
47
+ const quietArg = quiet && '--quiet';
48
+
49
+ const args = [
50
+ filterArg,
51
+ formatArg,
52
+ quietArg
53
+ ].filter(Boolean).join(' ');
54
+
55
+ if (formatToJSON) {
56
+ const result = await execAsyncSpawn(`docker volume ls ${args}`, execOptions);
57
+ return JSON.parse(`[${result.split('\n').join(', ')}]`);
58
+ }
59
+
60
+ return execAsyncSpawn(`docker volume ls ${args}`, execOptions);
61
+ };
62
+
63
+ module.exports = {
64
+ create,
65
+ ls
66
+ };
@@ -1,4 +1,4 @@
1
- // const path = require('path');
1
+ const os = require('os');
2
2
  const { spawn } = require('child_process');
3
3
 
4
4
  const executeInContainer = ({ containerName, commands }) => {
@@ -7,11 +7,14 @@ const executeInContainer = ({ containerName, commands }) => {
7
7
  process.exit(1);
8
8
  }
9
9
 
10
+ const userArg = os.platform() === 'linux' && `--user=${os.userInfo().uid}:${os.userInfo().gid}`;
11
+
10
12
  spawn('docker', [
11
13
  'exec',
12
14
  '-it',
15
+ userArg,
13
16
  containerName
14
- ].concat(...commands.map((command) => command.split(' '))), {
17
+ ].filter(Boolean).concat(...commands.map((command) => command.split(' '))), {
15
18
  stdio: [0, 1, 2]
16
19
  });
17
20
 
@@ -0,0 +1,23 @@
1
+ const path = require('path');
2
+ const UnknownError = require('../../errors/unknown-error');
3
+ const setConfigFile = require('../../util/set-config');
4
+
5
+ /**
6
+ * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
7
+ */
8
+ const createMariaDBConfig = () => ({
9
+ title: 'Setting MariaDB config',
10
+ task: async (ctx) => {
11
+ try {
12
+ await setConfigFile({
13
+ configPathname: path.join(ctx.config.baseConfig.cacheDir, 'mariadb.cnf'),
14
+ template: path.join(ctx.config.baseConfig.templateDir, 'mariadb.template.cnf'),
15
+ overwrite: true
16
+ });
17
+ } catch (e) {
18
+ throw new UnknownError(`Unexpected error accrued during php-fpm config creation\n\n${e}`);
19
+ }
20
+ }
21
+ });
22
+
23
+ module.exports = createMariaDBConfig;