@scandipwa/magento-scripts 2.0.0-alpha.2 → 2.0.0-alpha.20

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 (144) hide show
  1. package/exec.js +71 -0
  2. package/index.js +1 -1
  3. package/lib/commands/cli.js +14 -1
  4. package/lib/commands/execute.js +2 -57
  5. package/lib/commands/start.js +24 -3
  6. package/lib/commands/status.js +9 -1
  7. package/lib/config/config.js +20 -2
  8. package/lib/config/docker.js +86 -53
  9. package/lib/config/get-project-configuration.js +5 -0
  10. package/lib/config/index.js +10 -3
  11. package/lib/config/php/versions/php-7.2.js +1 -0
  12. package/lib/config/php/versions/php-7.3.js +1 -0
  13. package/lib/config/php/versions/php-7.4.js +1 -0
  14. package/lib/config/php/versions/php-8.1.js +1 -0
  15. package/lib/config/php-config.js +4 -3
  16. package/lib/config/port-config.js +3 -1
  17. package/lib/config/services/composer/versions/composer-1.js +13 -0
  18. package/lib/config/services/composer/versions/composer-2.js +8 -0
  19. package/lib/config/services/composer/versions/index.js +4 -0
  20. package/lib/config/services/maildev/index.js +7 -0
  21. package/lib/config/services/nginx/versions/index.js +3 -0
  22. package/lib/config/services/nginx/versions/nginx-1.18.js +11 -0
  23. package/lib/config/{ssl-terminator → services/ssl-terminator}/index.js +3 -0
  24. package/lib/config/templates/magentorc.template +6 -5
  25. package/lib/config/templates/php-debug.template.ini +31 -0
  26. package/lib/config/templates/php-fpm.template.conf +1 -2
  27. package/lib/config/templates/php.template.ini +5 -201
  28. package/lib/config/templates/ssl-terminator.template.conf +10 -3
  29. package/lib/config/templates/varnish.template.vcl +20 -13
  30. package/lib/config/varnish/varnish-6-0.js +4 -0
  31. package/lib/config/varnish/varnish-6-6.js +4 -0
  32. package/lib/config/varnish/varnish-7-0.js +4 -0
  33. package/lib/config/versions/magento-2.2.10.js +41 -0
  34. package/lib/config/versions/magento-2.3.0.js +8 -10
  35. package/lib/config/versions/magento-2.3.1.js +8 -10
  36. package/lib/config/versions/magento-2.3.2-p1.js +8 -10
  37. package/lib/config/versions/magento-2.3.2-p2.js +8 -10
  38. package/lib/config/versions/magento-2.3.2.js +8 -10
  39. package/lib/config/versions/magento-2.3.3-p1.js +8 -10
  40. package/lib/config/versions/magento-2.3.3.js +8 -10
  41. package/lib/config/versions/magento-2.3.4-p1.js +8 -10
  42. package/lib/config/versions/magento-2.3.4-p2.js +8 -10
  43. package/lib/config/versions/magento-2.3.4.js +8 -10
  44. package/lib/config/versions/magento-2.3.5-p1.js +8 -10
  45. package/lib/config/versions/magento-2.3.5-p2.js +8 -10
  46. package/lib/config/versions/magento-2.3.5.js +8 -10
  47. package/lib/config/versions/magento-2.3.6-p1.js +8 -10
  48. package/lib/config/versions/magento-2.3.6.js +8 -10
  49. package/lib/config/versions/magento-2.3.7-p1.js +8 -10
  50. package/lib/config/versions/magento-2.3.7-p2.js +8 -10
  51. package/lib/config/versions/magento-2.3.7-p3.js +8 -10
  52. package/lib/config/versions/magento-2.3.7-p4.js +42 -0
  53. package/lib/config/versions/magento-2.3.7.js +8 -10
  54. package/lib/config/versions/magento-2.4.0-p1.js +8 -10
  55. package/lib/config/versions/magento-2.4.0.js +8 -10
  56. package/lib/config/versions/magento-2.4.1-p1.js +8 -10
  57. package/lib/config/versions/magento-2.4.1.js +8 -10
  58. package/lib/config/versions/magento-2.4.2-p1.js +8 -10
  59. package/lib/config/versions/magento-2.4.2-p2.js +8 -10
  60. package/lib/config/versions/magento-2.4.2.js +8 -10
  61. package/lib/config/versions/magento-2.4.3-p1.js +8 -10
  62. package/lib/config/versions/magento-2.4.3-p2.js +8 -10
  63. package/lib/config/versions/magento-2.4.3-p3.js +44 -0
  64. package/lib/config/versions/magento-2.4.3.js +8 -10
  65. package/lib/config/versions/magento-2.4.4-p1.js +44 -0
  66. package/lib/config/versions/magento-2.4.4.js +8 -10
  67. package/lib/config/versions/magento-2.4.5.js +44 -0
  68. package/lib/tasks/cli/create-bashrc-config.js +1 -1
  69. package/lib/tasks/composer/local-auth-json.js +1 -1
  70. package/lib/tasks/database/connect-to-database.js +6 -3
  71. package/lib/tasks/database/create-magento-database.js +5 -2
  72. package/lib/tasks/database/create-magento-user.js +50 -0
  73. package/lib/tasks/database/default-magento-database.js +3 -0
  74. package/lib/tasks/database/default-magento-user.js +7 -0
  75. package/lib/tasks/database/import-dump-to-database.js +3 -2
  76. package/lib/tasks/docker/api.d.ts +25 -1
  77. package/lib/tasks/docker/api.js +31 -1
  78. package/lib/tasks/docker/containers/container-api.d.ts +21 -0
  79. package/lib/tasks/docker/containers/container-api.js +82 -17
  80. package/lib/tasks/docker/containers/tasks.js +44 -13
  81. package/lib/tasks/docker/convert-composer-home-to-composer-cache-volume.js +52 -0
  82. package/lib/tasks/docker/convert-mysql-to-mariadb.js +2 -2
  83. package/lib/tasks/docker/image/image-api.d.ts +44 -0
  84. package/lib/tasks/docker/image/image-api.js +30 -2
  85. package/lib/tasks/docker/index.js +6 -1
  86. package/lib/tasks/docker/project-image-builder.js +36 -13
  87. package/lib/tasks/docker/system/index.js +5 -0
  88. package/lib/tasks/docker/system/system-api.d.ts +71 -0
  89. package/lib/tasks/docker/system/system-api.js +29 -0
  90. package/lib/tasks/docker/volume/index.js +2 -1
  91. package/lib/tasks/docker/volume/tasks.js +67 -9
  92. package/lib/tasks/docker/volume/volume-api.d.ts +40 -0
  93. package/lib/tasks/docker/volume/volume-api.js +54 -1
  94. package/lib/tasks/execute.js +100 -0
  95. package/lib/tasks/file-system/create-nginx-config.js +3 -5
  96. package/lib/tasks/file-system/create-php-config.js +2 -23
  97. package/lib/tasks/file-system/create-php-debug-config.js +45 -0
  98. package/lib/tasks/file-system/create-php-fpm-config.js +2 -4
  99. package/lib/tasks/file-system/create-phpstorm-config/exclude-folder-config.js +13 -3
  100. package/lib/tasks/file-system/create-phpstorm-config/workspace-config/php-workspace-project-configuration-config.js +1 -1
  101. package/lib/tasks/file-system/create-ssl-terminator-config.js +4 -7
  102. package/lib/tasks/file-system/create-varnish-config.js +4 -7
  103. package/lib/tasks/file-system/index.js +2 -0
  104. package/lib/tasks/magento/enable-magento-composer-plugins.js +85 -30
  105. package/lib/tasks/magento/install-magento-project.js +3 -2
  106. package/lib/tasks/magento/setup-magento/configure-elasticsearch.js +2 -4
  107. package/lib/tasks/magento/setup-magento/flush-redis-config.js +3 -6
  108. package/lib/tasks/magento/setup-magento/index.js +2 -0
  109. package/lib/tasks/magento/setup-magento/install-magento.js +8 -10
  110. package/lib/tasks/magento/setup-magento/set-base-url.js +1 -1
  111. package/lib/tasks/magento/setup-magento/set-mail-config.js +26 -0
  112. package/lib/tasks/magento/setup-magento/varnish-config.js +4 -9
  113. package/lib/tasks/magento/setup-magento/waiting-for-varnish.js +17 -16
  114. package/lib/tasks/php/php-container.js +7 -3
  115. package/lib/tasks/php/update-env-php.js +3 -4
  116. package/lib/tasks/{prefix → project-config}/index.js +6 -6
  117. package/lib/tasks/requirements/composer-credentials.js +7 -3
  118. package/lib/tasks/requirements/docker/context.js +88 -0
  119. package/lib/tasks/requirements/docker/index.js +114 -20
  120. package/lib/tasks/requirements/docker/install.js +21 -7
  121. package/lib/tasks/requirements/docker/permissions.js +2 -11
  122. package/lib/tasks/requirements/docker/running-status.js +94 -24
  123. package/lib/tasks/requirements/docker/version.js +1 -0
  124. package/lib/tasks/requirements/index.js +0 -2
  125. package/lib/tasks/requirements/php-version.js +4 -2
  126. package/lib/tasks/start.js +27 -8
  127. package/lib/tasks/status/index.js +29 -20
  128. package/lib/tasks/stop.js +2 -0
  129. package/lib/tasks/theme/retrieve-theme-data.js +11 -1
  130. package/lib/util/config-file-validator.js +15 -2
  131. package/lib/util/execute-in-container.js +62 -0
  132. package/lib/util/instance-metadata.js +14 -2
  133. package/lib/util/systemctl.js +62 -13
  134. package/package.json +4 -3
  135. package/typings/context.d.ts +11 -0
  136. package/typings/index.d.ts +42 -1
  137. package/lib/tasks/execute/index.js +0 -26
  138. package/lib/tasks/requirements/dependency/arch.js +0 -50
  139. package/lib/tasks/requirements/dependency/centos.js +0 -36
  140. package/lib/tasks/requirements/dependency/fedora.js +0 -36
  141. package/lib/tasks/requirements/dependency/index.js +0 -33
  142. package/lib/tasks/requirements/dependency/mac.js +0 -124
  143. package/lib/tasks/requirements/dependency/ubuntu.js +0 -83
  144. package/yarn-error.log +0 -9660
@@ -1,11 +1,13 @@
1
- const path = require('path');
2
1
  const { defaultMagentoConfig } = require('../magento-config');
3
2
  const sodium = require('../php/extensions/sodium');
4
3
  const { magento24PHPExtensionList } = require('../magento/required-php-extensions');
5
4
  const { php74 } = require('../php/versions');
6
- const { sslTerminator } = require('../ssl-terminator');
5
+ const { sslTerminator } = require('../services/ssl-terminator');
7
6
  const { varnish66 } = require('../varnish/varnish-6-6');
8
7
  const { repo } = require('../php/base-repo');
8
+ const { nginx118 } = require('../services/nginx/versions');
9
+ const { composer2 } = require('../services/composer/versions');
10
+ const { maildev } = require('../services/maildev');
9
11
 
10
12
  module.exports = ({ templateDir } = {}) => ({
11
13
  magentoVersion: '2.4.3',
@@ -16,10 +18,7 @@ module.exports = ({ templateDir } = {}) => ({
16
18
  extensions: { ...magento24PHPExtensionList, sodium },
17
19
  baseImage: `${ repo }:php-7.4-magento-2.4`
18
20
  }),
19
- nginx: {
20
- version: '1.18.0',
21
- configTemplate: path.join(templateDir || '', 'nginx.template.conf')
22
- },
21
+ nginx: nginx118({ templateDir }),
23
22
  redis: {
24
23
  version: '6.0'
25
24
  },
@@ -32,11 +31,10 @@ module.exports = ({ templateDir } = {}) => ({
32
31
  elasticsearch: {
33
32
  version: '7.16.3'
34
33
  },
35
- composer: {
36
- version: '2'
37
- },
34
+ composer: composer2(),
38
35
  varnish: varnish66({ templateDir }),
39
- sslTerminator: sslTerminator({ templateDir })
36
+ sslTerminator: sslTerminator({ templateDir }),
37
+ maildev: maildev()
40
38
  },
41
39
  magento: defaultMagentoConfig,
42
40
  host: 'localhost',
@@ -0,0 +1,44 @@
1
+ const { defaultMagentoConfig } = require('../magento-config');
2
+ const sodium = require('../php/extensions/sodium');
3
+ const { magento24PHPExtensionList } = require('../magento/required-php-extensions');
4
+ const { php81 } = require('../php/versions');
5
+ const { sslTerminator } = require('../services/ssl-terminator');
6
+ const { varnish70 } = require('../varnish/varnish-7-0');
7
+ const { repo } = require('../php/base-repo');
8
+ const { nginx118 } = require('../services/nginx/versions');
9
+ const { composer2 } = require('../services/composer/versions');
10
+ const { maildev } = require('../services/maildev');
11
+
12
+ module.exports = ({ templateDir } = {}) => ({
13
+ magentoVersion: '2.4.4-p1',
14
+ isDefault: true,
15
+ configuration: {
16
+ php: php81({
17
+ templateDir,
18
+ extensions: { ...magento24PHPExtensionList, sodium },
19
+ baseImage: `${ repo }:php-8.1-magento-2.4`
20
+ }),
21
+ nginx: nginx118({ templateDir }),
22
+ redis: {
23
+ version: '6.0'
24
+ },
25
+ mysql: {
26
+ version: '8.0'
27
+ },
28
+ mariadb: {
29
+ version: '10.4'
30
+ },
31
+ elasticsearch: {
32
+ version: '7.16.3'
33
+ },
34
+ composer: composer2(),
35
+ varnish: varnish70({ templateDir }),
36
+ sslTerminator: sslTerminator({ templateDir }),
37
+ maildev: maildev()
38
+ },
39
+ magento: defaultMagentoConfig,
40
+ host: 'localhost',
41
+ ssl: {
42
+ enabled: false
43
+ }
44
+ });
@@ -1,11 +1,13 @@
1
- const path = require('path');
2
1
  const { defaultMagentoConfig } = require('../magento-config');
3
2
  const sodium = require('../php/extensions/sodium');
4
3
  const { magento24PHPExtensionList } = require('../magento/required-php-extensions');
5
4
  const { php81 } = require('../php/versions');
6
- const { sslTerminator } = require('../ssl-terminator');
5
+ const { sslTerminator } = require('../services/ssl-terminator');
7
6
  const { varnish70 } = require('../varnish/varnish-7-0');
8
7
  const { repo } = require('../php/base-repo');
8
+ const { nginx118 } = require('../services/nginx/versions');
9
+ const { composer2 } = require('../services/composer/versions');
10
+ const { maildev } = require('../services/maildev');
9
11
 
10
12
  module.exports = ({ templateDir } = {}) => ({
11
13
  magentoVersion: '2.4.4',
@@ -16,10 +18,7 @@ module.exports = ({ templateDir } = {}) => ({
16
18
  extensions: { ...magento24PHPExtensionList, sodium },
17
19
  baseImage: `${ repo }:php-8.1-magento-2.4`
18
20
  }),
19
- nginx: {
20
- version: '1.18.0',
21
- configTemplate: path.join(templateDir || '', 'nginx.template.conf')
22
- },
21
+ nginx: nginx118({ templateDir }),
23
22
  redis: {
24
23
  version: '6.0'
25
24
  },
@@ -32,11 +31,10 @@ module.exports = ({ templateDir } = {}) => ({
32
31
  elasticsearch: {
33
32
  version: '7.16.3'
34
33
  },
35
- composer: {
36
- version: '2'
37
- },
34
+ composer: composer2(),
38
35
  varnish: varnish70({ templateDir }),
39
- sslTerminator: sslTerminator({ templateDir })
36
+ sslTerminator: sslTerminator({ templateDir }),
37
+ maildev: maildev()
40
38
  },
41
39
  magento: defaultMagentoConfig,
42
40
  host: 'localhost',
@@ -0,0 +1,44 @@
1
+ const { defaultMagentoConfig } = require('../magento-config');
2
+ const sodium = require('../php/extensions/sodium');
3
+ const { magento24PHPExtensionList } = require('../magento/required-php-extensions');
4
+ const { php81 } = require('../php/versions');
5
+ const { sslTerminator } = require('../services/ssl-terminator');
6
+ const { varnish70 } = require('../varnish/varnish-7-0');
7
+ const { repo } = require('../php/base-repo');
8
+ const { nginx118 } = require('../services/nginx/versions');
9
+ const { composer2 } = require('../services/composer/versions');
10
+ const { maildev } = require('../services/maildev');
11
+
12
+ module.exports = ({ templateDir } = {}) => ({
13
+ magentoVersion: '2.4.5',
14
+ isDefault: true,
15
+ configuration: {
16
+ php: php81({
17
+ templateDir,
18
+ extensions: { ...magento24PHPExtensionList, sodium },
19
+ baseImage: `${ repo }:php-8.1-magento-2.4`
20
+ }),
21
+ nginx: nginx118({ templateDir }),
22
+ redis: {
23
+ version: '6.0'
24
+ },
25
+ mysql: {
26
+ version: '8.0'
27
+ },
28
+ mariadb: {
29
+ version: '10.4'
30
+ },
31
+ elasticsearch: {
32
+ version: '7.17.5'
33
+ },
34
+ composer: composer2(),
35
+ varnish: varnish70({ templateDir }),
36
+ sslTerminator: sslTerminator({ templateDir }),
37
+ maildev: maildev()
38
+ },
39
+ magento: defaultMagentoConfig,
40
+ host: 'localhost',
41
+ ssl: {
42
+ enabled: false
43
+ }
44
+ });
@@ -21,7 +21,7 @@ const createBashrcConfigFile = () => ({
21
21
  }
22
22
  });
23
23
  } catch (e) {
24
- throw new UnknownError(`Unexpected error accrued during php.ini config creation\n\n${e}`);
24
+ throw new UnknownError(`Unexpected error accrued during .magentorc config creation\n\n${e}`);
25
25
  }
26
26
  }
27
27
  });
@@ -27,7 +27,7 @@ const localAuthJson = () => ({
27
27
  throw new KnownError(`Your ./auth.json file does not contain the ${ logger.style.misc("{ 'http-basic': { 'repo.magento.com': <> } }") } field.`);
28
28
  }
29
29
 
30
- process.env.COMPOSER_AUTH = localAuthJson;
30
+ process.env.COMPOSER_AUTH = JSON.stringify(JSON.parse(localAuthJson), null, 0);
31
31
  }
32
32
  },
33
33
  options: {
@@ -3,6 +3,8 @@ const UnknownError = require('../../errors/unknown-error');
3
3
  const { execAsyncSpawn } = require('../../util/exec-async-command');
4
4
  const sleep = require('../../util/sleep');
5
5
  const { createMagentoDatabase } = require('./create-magento-database');
6
+ const { createMagentoUser } = require('./create-magento-user');
7
+ const defaultMagentoUser = require('./default-magento-user');
6
8
 
7
9
  /**
8
10
  * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -60,9 +62,9 @@ const gettingDatabaseConnection = () => ({
60
62
  const connection = await mysql2.createConnection({
61
63
  host: '127.0.0.1',
62
64
  port: ports.mariadb,
63
- user: mariadb.env.MARIADB_USER,
64
- password: mariadb.env.MARIADB_PASSWORD,
65
- database: mariadb.env.MARIADB_DATABASE
65
+ user: defaultMagentoUser.user,
66
+ password: defaultMagentoUser.password,
67
+ database: 'magento'
66
68
  });
67
69
 
68
70
  ctx.databaseConnection = connection;
@@ -101,6 +103,7 @@ const connectToDatabase = () => ({
101
103
  task: (ctx, task) => task.newListr([
102
104
  waitForDatabaseInitialization(),
103
105
  createMagentoDatabase(),
106
+ createMagentoUser(),
104
107
  terminatingExistingConnection(),
105
108
  gettingDatabaseConnection()
106
109
  ], {
@@ -1,4 +1,4 @@
1
- const { execAsyncSpawn } = require('../../util/exec-async-command');
1
+ const { containerApi } = require('../docker/containers');
2
2
 
3
3
  /**
4
4
  * Will create database 'magento' in MariaDB if it does not exist for some reason
@@ -9,7 +9,10 @@ const createMagentoDatabase = () => ({
9
9
  task: async (ctx, task) => {
10
10
  const { mariadb } = ctx.config.docker.getContainers();
11
11
  task.title = `Creating Magento database in ${ mariadb._ }`;
12
- await execAsyncSpawn(`docker exec ${mariadb.name} mysql -umagento -pmagento -h 127.0.0.1 -e "CREATE DATABASE IF NOT EXISTS magento;"`);
12
+ await containerApi.exec(
13
+ `mysql -uroot -p${ mariadb.env.MARIADB_ROOT_PASSWORD } -h 127.0.0.1 -e "CREATE DATABASE IF NOT EXISTS magento;"`,
14
+ mariadb.name
15
+ );
13
16
  }
14
17
  });
15
18
 
@@ -0,0 +1,50 @@
1
+ const mysql2 = require('mysql2/promise');
2
+ const defaultMagentoUser = require('./default-magento-user');
3
+
4
+ /**
5
+ * @returns {import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
6
+ */
7
+ const createMagentoUser = () => ({
8
+ title: 'Creating Magento user',
9
+ task: async (ctx, task) => {
10
+ const { mariadb } = ctx.config.docker.getContainers();
11
+ const connection = await mysql2.createConnection({
12
+ host: '127.0.0.1',
13
+ port: ctx.ports.mariadb,
14
+ user: 'root',
15
+ password: mariadb.env.MARIADB_ROOT_PASSWORD
16
+ });
17
+
18
+ const result = await connection.query('select Host, User from mysql.user;');
19
+
20
+ if (result.length === 0) {
21
+ task.skip();
22
+ return;
23
+ }
24
+
25
+ const [users] = result;
26
+
27
+ if (users.some((user) => user.User === defaultMagentoUser.user && user.Host === '%')) {
28
+ task.skip();
29
+ return;
30
+ }
31
+
32
+ if (users.some((user) => user.User === defaultMagentoUser.user)) {
33
+ const magentoUser = users.find((user) => user.User === defaultMagentoUser.user);
34
+
35
+ await connection.query(`DROP USER '${ magentoUser.User }'@'${ magentoUser.Host }'`);
36
+ }
37
+
38
+ await connection.query(
39
+ `CREATE USER '${ defaultMagentoUser.user }'@'${ defaultMagentoUser.host }' IDENTIFIED BY '${ defaultMagentoUser.password }';`
40
+ );
41
+ await connection.query(`GRANT ALL PRIVILEGES ON *.* TO '${ defaultMagentoUser.user }'@'${ defaultMagentoUser.host }' WITH GRANT OPTION;`);
42
+ await connection.query('FLUSH PRIVILEGES;');
43
+
44
+ await connection.destroy();
45
+ }
46
+ });
47
+
48
+ module.exports = {
49
+ createMagentoUser
50
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ defaultMagentoDatabase: 'magento'
3
+ };
@@ -0,0 +1,7 @@
1
+ const defaultMagentoUser = {
2
+ user: 'magento',
3
+ password: 'magento',
4
+ host: '%'
5
+ };
6
+
7
+ module.exports = defaultMagentoUser;
@@ -5,6 +5,7 @@ const UnknownError = require('../../errors/unknown-error');
5
5
  const { execAsyncSpawn, execCommandTask } = require('../../util/exec-async-command');
6
6
  const pathExists = require('../../util/path-exists');
7
7
  const connectToDatabase = require('./connect-to-database');
8
+ const defaultMagentoUser = require('./default-magento-user');
8
9
 
9
10
  /**
10
11
  * @type {() => import('listr2').ListrTask<import('../../../typings/context').ListrContext>}
@@ -88,8 +89,8 @@ const executeImportDumpSQL = () => ({
88
89
  message: `root (${logger.style.command('Probably safest option')})`
89
90
  },
90
91
  {
91
- name: `--user=${mariadb.env.MARIADB_USER} --password=${mariadb.env.MARIADB_PASSWORD}`,
92
- message: `${mariadb.env.MARIADB_USER}`
92
+ name: `--user=${defaultMagentoUser.user} --password=${defaultMagentoUser.password}`,
93
+ message: `${defaultMagentoUser.user}`
93
94
  }
94
95
  ]
95
96
  });
@@ -1,7 +1,6 @@
1
1
  import { ExecAsyncSpawnOptions } from '../../util/exec-async-command';
2
2
 
3
3
  export interface DockerVersionOptions<T extends boolean = false> {
4
- format?: string
5
4
  format?: string
6
5
  formatToJSON?: T
7
6
  }
@@ -69,3 +68,28 @@ export function version(
69
68
  options: DockerVersionOptions<true>,
70
69
  execOptions?: ExecAsyncSpawnOptions<false>
71
70
  ): Promise<DockerVersionResult>
71
+
72
+ export interface DockerContextOptions<T extends boolean = false> {
73
+ format?: string
74
+ formatToJSON?: T
75
+ }
76
+
77
+ export interface DockerContextResult {
78
+ Current: boolean
79
+ Description: string
80
+ DockerEndpoint: string
81
+ KubernetesEndpoint: string
82
+ ContextType: string
83
+ Name: string
84
+ StackOrchestrator: string
85
+ }
86
+
87
+ export function context(
88
+ options: DockerContextOptions,
89
+ execOptions?: ExecAsyncSpawnOptions<false>
90
+ ): Promise<string>
91
+
92
+ export function context(
93
+ options: DockerContextOptions<true>,
94
+ execOptions?: ExecAsyncSpawnOptions<false>
95
+ ): Promise<DockerContextResult[]>
@@ -25,6 +25,36 @@ const version = async (options, execOptions = {}) => {
25
25
  return execAsyncSpawn(`docker version ${args}`, execOptions);
26
26
  };
27
27
 
28
+ /**
29
+ * @param {import('./api').DockerContextOptions} options
30
+ * @param {import('../../util/exec-async-command').ExecAsyncSpawnOptions} execOptions
31
+ */
32
+ const context = async (options, execOptions = {}) => {
33
+ const {
34
+ format,
35
+ formatToJSON
36
+ } = options;
37
+
38
+ const formatArg = !formatToJSON && format
39
+ ? `--format=${format}`
40
+ : formatToJSON && '--format=\'{{json .}}\'';
41
+ const args = [
42
+ formatArg
43
+ ].filter(Boolean).join(' ');
44
+
45
+ if (formatToJSON) {
46
+ const result = await execAsyncSpawn(`docker context ls ${args}`, execOptions);
47
+ if (result.startsWith('[')) {
48
+ return JSON.parse(result);
49
+ }
50
+
51
+ return JSON.parse(`[${result.split('\n').join(', ')}]`);
52
+ }
53
+
54
+ return execAsyncSpawn(`docker context ls ${args}`, execOptions);
55
+ };
56
+
28
57
  module.exports = {
29
- version
58
+ version,
59
+ context
30
60
  };
@@ -69,6 +69,8 @@ export interface ContainerRunOptions {
69
69
  * Run container in background and print container ID
70
70
  */
71
71
  detach?: boolean
72
+
73
+ tty?: boolean
72
74
  /**
73
75
  * Publish or expose port [docs](https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose)
74
76
  */
@@ -126,3 +128,22 @@ export interface ContainerRunOptions {
126
128
  }
127
129
 
128
130
  export function run(containerOptions: ContainerRunOptions, execOptions?: ExecAsyncSpawnOptions<false>): Promise<false>
131
+
132
+ export function runCommand(options: ContainerRunOptions): string[]
133
+
134
+ export interface ContainerLogsOptions<T = never> {
135
+ name: string
136
+ details?: boolean
137
+ follow?: boolean
138
+ since?: string
139
+ tail?: string
140
+ timestamps?: boolean
141
+ until?: string
142
+ parser?: (line: string) => T
143
+ }
144
+
145
+ export function logs(options?: ContainerLogsOptions, execOptions?: ExecAsyncSpawnOptions<false>): Promise<string>
146
+ export function logs<T>(options?: ContainerLogsOptions<T>, execOptions?: ExecAsyncSpawnOptions<false>): Promise<T[]>
147
+
148
+ export function stop(containers: string[], execOptions: ExecAsyncSpawnOptions<false>): Promise<string>
149
+ export function rm(containers: string[], execOptions: ExecAsyncSpawnOptions<false>): Promise<string>
@@ -3,9 +3,9 @@ const { execAsyncSpawn } = require('../../../util/exec-async-command');
3
3
 
4
4
  /**
5
5
  * @param {import('./container-api').ContainerRunOptions} options
6
- * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions<false>} execOptions
6
+ * @returns {string[]}
7
7
  */
8
- const run = (options, execOptions = {}) => {
8
+ const runCommand = (options) => {
9
9
  const {
10
10
  addHost,
11
11
  ports = [],
@@ -24,32 +24,35 @@ const run = (options, execOptions = {}) => {
24
24
  expose = [],
25
25
  detach = true,
26
26
  rm = false,
27
+ tty = false,
27
28
  user
28
29
  } = options;
29
30
 
30
31
  const detachArg = detach && '-d';
31
32
  const rmArg = rm && '--rm';
33
+ const ttyArg = tty && '-it';
32
34
  const exposeArg = expose && expose.map((e) => `--expose=${ e }`);
33
- const restartArg = !rm && restart && `--restart ${ restart }`;
34
- const networkArg = network && `--network ${ network }`;
35
- const portsArgs = ports.map((port) => `-p ${ port }`).join(' ');
36
- const mountsArgs = mounts.map((mount) => `--mount ${ mount }`).join(' ');
37
- const mountVolumesArgs = mountVolumes.map((mount) => `-v ${mount}`).join(' ');
38
- const envArgs = !env ? '' : Object.entries(env).map(([key, value]) => `--env ${ key }='${ value }'`).join(' ');
39
- const nameArg = name && `--name ${name}`;
40
- const entrypointArg = entrypoint && `--entrypoint "${entrypoint}"`;
41
- const healthCheckArg = healthCheck && Object.entries(healthCheck).map(([key, value]) => `--health-${key} '${value}'`).join(' ');
42
- const securityArg = securityOptions.length > 0 && securityOptions.map((opt) => `--security-opt ${opt}`).join(' ');
43
- const tmpfsArg = tmpfs.length > 0 && tmpfs.map((t) => `--tmpfs ${t}`).join(' ');
35
+ const restartArg = !rm && restart && `--restart=${ restart }`;
36
+ const networkArg = network && `--network=${ network }`;
37
+ const portsArgs = ports && ports.length > 0 && ports.map((port) => `-p=${ port }`);
38
+ const mountsArgs = mounts && mounts.map((mount) => `--mount=${ mount }`);
39
+ const mountVolumesArgs = mountVolumes && mountVolumes.map((mount) => `-v=${mount}`);
40
+ const envArgs = !env ? '' : Object.entries(env).map(([key, value]) => `--env=${ key }='${ value }'`);
41
+ const nameArg = name && `--name=${name}`;
42
+ const entrypointArg = entrypoint && `--entrypoint="${entrypoint}"`;
43
+ const healthCheckArg = healthCheck && Object.entries(healthCheck).map(([key, value]) => `--health-${key}='${value}'`);
44
+ const securityArg = securityOptions.length > 0 && securityOptions.map((opt) => `--security-opt=${opt}`);
45
+ const tmpfsArg = tmpfs.length > 0 && tmpfs.map((t) => `--tmpfs=${t}`);
44
46
  const userArg = user && `--user=${user}`;
45
47
  const addHostArg = addHost && `--add-host=${addHost}`;
46
48
 
47
49
  const dockerCommand = [
48
50
  'docker',
49
51
  'run',
52
+ nameArg,
53
+ ttyArg,
50
54
  detachArg,
51
55
  rmArg,
52
- nameArg,
53
56
  networkArg,
54
57
  restartArg,
55
58
  portsArgs,
@@ -65,11 +68,17 @@ const run = (options, execOptions = {}) => {
65
68
  addHostArg,
66
69
  image,
67
70
  command
68
- ].filter(Boolean).join(' ');
71
+ ].flat().filter(Boolean).filter((arg) => typeof arg === 'string');
69
72
 
70
- return execAsyncSpawn(dockerCommand, execOptions);
73
+ return dockerCommand;
71
74
  };
72
75
 
76
+ /**
77
+ * @param {import('./container-api').ContainerRunOptions} options
78
+ * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions<false>} execOptions
79
+ */
80
+ const run = (options, execOptions = {}) => execAsyncSpawn(runCommand(options).join(' '), execOptions);
81
+
73
82
  /**
74
83
  * @param {string} command
75
84
  * @param {string} container container id or name
@@ -140,14 +149,70 @@ const ls = async (options = {}, execOptions = {}) => {
140
149
 
141
150
  if (formatToJSON) {
142
151
  const result = await execAsyncSpawn(`docker container ls ${args}`, execOptions);
152
+ if (result.startsWith('[')) {
153
+ return JSON.parse(result);
154
+ }
155
+
143
156
  return JSON.parse(`[${result.split('\n').join(', ')}]`);
144
157
  }
145
158
 
146
159
  return execAsyncSpawn(`docker container ls ${args}`, execOptions);
147
160
  };
148
161
 
162
+ /**
163
+ * @param {import('./container-api').ContainerLogsOptions} options
164
+ * @param {import('../../../util/exec-async-command').ExecAsyncSpawnOptions<false>} execOptions
165
+ */
166
+ const logs = async (options = {}, execOptions = {}) => {
167
+ const {
168
+ name,
169
+ details = false,
170
+ follow = false,
171
+ since = '',
172
+ tail = '',
173
+ timestamps = false,
174
+ until = '',
175
+ parser
176
+ } = options;
177
+ const detailsArg = details && '--details';
178
+ const followArg = follow && '--follow';
179
+ const sinceArg = since && `--since=${since}`;
180
+ const tailArg = tail && `--tail=${tail}`;
181
+ const timestampsArg = timestamps && '--timestamps';
182
+ const untilArg = until && `--until=${until}`;
183
+
184
+ const logsCommand = [
185
+ 'docker',
186
+ 'container',
187
+ 'logs',
188
+ detailsArg,
189
+ followArg,
190
+ sinceArg,
191
+ tailArg,
192
+ timestampsArg,
193
+ untilArg,
194
+ name
195
+ ].filter(Boolean).join(' ');
196
+
197
+ if (parser) {
198
+ const result = await execAsyncSpawn(logsCommand, execOptions);
199
+
200
+ return result.split('\n').map((line) => parser(line));
201
+ }
202
+
203
+ return execAsyncSpawn(logsCommand, execOptions);
204
+ };
205
+
206
+ const stop = (containers, execOptions = {}) => execAsyncSpawn(`docker container stop ${containers.join(' ')}`, execOptions);
207
+
208
+ const rm = (containers, execOptions = {}) => execAsyncSpawn(`docker container rm ${containers.join(' ')}`, execOptions);
209
+
149
210
  module.exports = {
150
211
  run,
212
+ runCommand,
151
213
  exec,
152
- ls
214
+ ls,
215
+ logs,
216
+ stop,
217
+ rm
153
218
  };