libdragon 10.2.1 → 10.3.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Change Log
2
2
 
3
+ ## [10.3.1] - 2022-01-25
4
+
5
+ ### Fixed
6
+
7
+ - Do not try to parse arguments after exec/make. They used to get evaluated as
8
+ libdragon paramaters previously, preventing passing down -v to the container
9
+ make for example.
10
+ - Docker image update issues
11
+ - Attempt an image update whenever the image flag is provided. Previously this
12
+ was only done if a different image name is provided, preventing the update of
13
+ the latest image. Previously not providing an image name was behaving the same
14
+ so this is not a breaking change.
15
+ - Start action used to update the image if provided but this bug was already
16
+ prevented by previous fixes by not accepting the image flag for actions other
17
+ than init/update/install. Start action no longer tries to update the image
18
+ regardless.
19
+
20
+ ### Changed
21
+
22
+ - Only accept he image flag for init, install, and update actions as documented.
23
+ - Improve documentation for the `init` and `install` actions.
24
+ - Do not attempt an `install` when running `exec`, just start the container. If
25
+ there is a half-baked container, a manual `install` will potentially restore it.
26
+ - Update libdragon.
27
+
28
+ ### Added
29
+
30
+ - Extra information for skipping the image flag when doing init for an already
31
+ initialized project.
32
+
33
+ ## [10.3.0] - 2022-01-20
34
+
35
+ ### Changed
36
+
37
+ - Update dependencies.
38
+ - Detailed help output.
39
+ - Move action descriptions to `libdragon help`.
40
+ - Update libdragon to latest version for local build.
41
+
42
+ ### Added
43
+
44
+ - Shorthand flag support.
45
+
3
46
  ## [10.2.1] - 2021-10-14
4
47
 
5
48
  ### Changed
@@ -16,42 +59,42 @@
16
59
 
17
60
  - Container discovery. The tool can now find a container even if `.git` is lost.
18
61
  - A few additional error messages for some potentially confusing cases such as
19
- already having a file with `libdragon` like name.
62
+ already having a file with `libdragon` like name.
20
63
 
21
64
  ### Changed
22
65
 
23
66
  - Show more output for downloading the container and initial git operations.
24
67
  - Remove an extra log during initialization.
25
68
  - The submodule was always being initialized when a container is started. This
26
- was making some actions inconsistent. For example `install` or `make` action
27
- was trying to re-initialize the submodule unnecessarily. This is fixed by only
28
- initializing it with the `init` action. If any of those need to re-init the
29
- container, now they assume there is an intact libdragon folder to use.
69
+ was making some actions inconsistent. For example `install` or `make` action
70
+ was trying to re-initialize the submodule unnecessarily. This is fixed by only
71
+ initializing it with the `init` action. If any of those need to re-init the
72
+ container, now they assume there is an intact libdragon folder to use.
30
73
  - Similarly a git repository is not initialized unnecessarily anymore.
31
74
  - `update` and `install` are now able to start containers if necessary.
32
75
  - Always try to copy skeleton files, they won't overwrite anything already.
33
76
  - Do not re-initialize if there is a `.libdragon` folder. We now only try to
34
- start it in this case. If it is not a complete container, it can probably be
35
- recovered by a `libdragon install` or `libdragon update`.
77
+ start it in this case. If it is not a complete container, it can probably be
78
+ recovered by a `libdragon install` or `libdragon update`.
36
79
 
37
80
  ### Fixed
38
81
 
39
82
  - Fix wording for libdragon install on the container.
40
83
  - Improve image name persitence such that the tool finds and updates it more
41
- consistently.
84
+ consistently.
42
85
 
43
86
  ## [10.1.0] - 2021-10-07
44
87
 
45
88
  ### Added
46
89
 
47
90
  - `exec` action to execute arbitrary commands in the container with TTY support.
48
- This also improves the color output support as docker now knows it is using TTY.
91
+ This also improves the color output support as docker now knows it is using TTY.
49
92
  - Add more verbose logging for skeleton project copy.
50
93
 
51
94
  ### Changed
52
95
 
53
96
  - Removed partially not working `--byte-swap` option. It does not already work
54
- with the new libdragon build system so there is no need keeping it in the tool.
97
+ with the new libdragon build system so there is no need keeping it in the tool.
55
98
 
56
99
  ### Fixed
57
100
 
@@ -62,14 +105,14 @@ with the new libdragon build system so there is no need keeping it in the tool.
62
105
  ### Changed
63
106
 
64
107
  - A complete re-write of the tool. Check documentation for the new usage. It is
65
- much more straightforward to use now. `libdragon make` behaves almost the same.
108
+ much more straightforward to use now. `libdragon make` behaves almost the same.
66
109
 
67
110
  ## [9.0.0] - 2021-09-06
68
111
 
69
112
  ### Changed
70
113
 
71
114
  - Updated libdragon. We will be changing the update mechanism to be based on a
72
- git pull, so listing them here will not be useful anymore, let's not bother now.
115
+ git pull, so listing them here will not be useful anymore, let's not bother now.
73
116
  - Start using the new build system.
74
117
  - Update node engine spec to be at least 14.
75
118
  - Added minimum docker version to readme.
@@ -119,7 +162,6 @@ git pull, so listing them here will not be useful anymore, let's not bother now.
119
162
  - Support for RTC status/read/write commands (https://github.com/DragonMinded/libdragon/pull/152)
120
163
  - Generic libdragon NPM script
121
164
 
122
-
123
165
  ## [7.0.0] - 2021-06-06
124
166
 
125
167
  ### Changed
package/README.md CHANGED
@@ -36,53 +36,15 @@ You can invoke libdragon as follows;
36
36
 
37
37
  libdragon [flags] <action>
38
38
 
39
- ### Available actions
40
-
41
- __`init`__
42
-
43
- Creates a libdragon project in the current directory. Every libdragon project will have its own docker container instance. If you are in a git repository or an NPM project, libdragon will be initialized at their root also marking there with a `.libdragon` folder.
44
-
45
- A git repository and a submodule at `./libdragon` will also be created. Do not remove the `.libdragon` folder and commit its contents if you are using git, as it keeps persistent libdragon project information.
46
-
47
- If this is the first time you are creating a libdragon project at that location, this action will also create skeleton project files to kickstart things.
48
-
49
- __`make`__
50
-
51
- Runs the libdragon build system in the current directory. It will mirror your current working directory to the container.
52
-
53
- This action is a shortcut to the `exec` action under the hood.
54
-
55
- __`exec`__
56
-
57
- Executes the given command in the container passing down any arguments provided. If you change your host working directory, the command will be executed in the corresponding folder in the container as well.
58
-
59
- This action will first try to execute the command in the container and if the container is not accessible, it will attempt a complete `start` cycle.
60
-
61
- This will properly passthrough your TTY if you have one. So by running `libdragon exec bash` you can start an interactive bash session with full TTY support.
62
-
63
- __`install`__
64
-
65
- Attempts to build and install everything libdragon related into the container. This includes all the tools and third parties used by libdragon except for the toolchain. If you have made changes to libdragon, you can execute this action to build everything based on your changes. Requires you to have an intact `libdragon` at the root of the project. If you are not working on libdragon, you can just use the `update` action instead.
66
-
67
- __`update`__
68
-
69
- This action will update the submodule from the remote branch (`trunk`) with a merge strategy and then perform a `libdragon install`. You can use the `install` action to only update all libdragon related artifacts in the container.
70
-
71
- __`start`__
72
-
73
- Start the container assigned to the current libdragon project. Will first attempt to start an existing container if found, followed by a new container run and installation similar to the `install` action. Will always print out the container id on success.
74
-
75
- __`stop`__
76
-
77
- Stop the container assigned to the current libdragon project.
39
+ Run `libdragon help [action]` for more details on individual actions.
78
40
 
79
41
  ### Available flags
80
42
 
81
- __`--image <docker-image>`__
43
+ **`--image <docker-image>`**
82
44
 
83
45
  Use this flag to provide a custom image to use instead of the default. It should include the toolchain at `/n64_toolchain`. It will be effective for `init`, `install` and `update` actions and will cause a re-initialization of the container if an image different from what was written to project configuration is provided.
84
46
 
85
- __`--verbose`__
47
+ **`--verbose`**
86
48
 
87
49
  Be verbose. This will print all commands dispatched and their outputs as well.
88
50
 
package/index.js CHANGED
@@ -3,86 +3,93 @@
3
3
  const chalk = require('chalk');
4
4
  const { readProjectInfo, CommandError, globals } = require('./modules/helpers');
5
5
  const actions = require('./modules/actions');
6
+ const { printUsage } = require('./modules/usage');
6
7
 
7
8
  const STATUS_OK = 0;
8
9
  const STATUS_ERROR = 1;
9
10
  const STATUS_BAD_PARAM = 2;
10
11
 
11
- // Command line options
12
- const options = {
13
- DOCKER_IMAGE: undefined,
14
- VERBOSE: false,
15
-
16
- ACTION: undefined,
17
- PARAMS: undefined,
18
- };
19
-
20
- // Allow standard io here
21
- /* eslint-disable no-console */
12
+ let options = {},
13
+ currentAction;
22
14
 
23
15
  for (let i = 2; i < process.argv.length; i++) {
24
16
  const val = process.argv[i];
25
17
 
26
- if (val === '--verbose') {
18
+ // Allow console here
19
+ /* eslint-disable no-console */
20
+
21
+ if (['--verbose', '-v'].includes(val)) {
27
22
  options.VERBOSE = true;
28
23
  globals.verbose = true;
29
24
  continue;
30
25
  }
31
26
 
32
- if (val === '--image') {
27
+ if (['--image', '-i'].includes(val)) {
33
28
  options.DOCKER_IMAGE = process.argv[++i];
34
29
  continue;
30
+ } else if (val.indexOf('--image=') === 0) {
31
+ options.DOCKER_IMAGE = val.split('=')[1];
32
+ continue;
35
33
  }
36
34
 
37
35
  if (val.indexOf('--') >= 0) {
38
36
  console.error(chalk.red(`Invalid flag \`${val}\``));
39
- actions.help.fn();
37
+ printUsage();
40
38
  process.exit(STATUS_BAD_PARAM);
41
39
  }
42
40
 
43
- if (options.ACTION) {
41
+ if (currentAction) {
44
42
  console.error(
45
43
  chalk.red(`Expected only a single action, found: \`${val}\``)
46
44
  );
47
- actions.help.fn();
45
+ printUsage();
48
46
  process.exit(STATUS_BAD_PARAM);
49
47
  }
50
48
 
51
- options.ACTION = actions[val];
49
+ currentAction = actions[val];
52
50
 
53
- if (!options.ACTION) {
51
+ if (!currentAction) {
54
52
  console.error(chalk.red(`Invalid action \`${val}\``));
55
- actions.help.fn();
53
+ printUsage();
56
54
  process.exit(STATUS_BAD_PARAM);
57
55
  }
58
56
 
59
- if (options.ACTION.forwardsRestParams) {
57
+ if (currentAction.forwardsRestParams) {
60
58
  options.PARAMS = process.argv.slice(i + 1);
61
59
  break;
62
60
  }
63
61
  }
64
62
 
65
- if (!options.ACTION) {
63
+ if (!currentAction) {
66
64
  console.error(chalk.red('No action provided'));
67
- actions.help.fn();
65
+ printUsage();
68
66
  process.exit(STATUS_BAD_PARAM);
69
67
  }
70
68
 
71
- if (options.ACTION === actions.exec && options.PARAMS.length === 0) {
69
+ if (currentAction === actions.exec && options.PARAMS.length === 0) {
72
70
  console.error(chalk.red('You should provide a command to exec'));
73
- actions.help.fn();
71
+ printUsage(undefined, [currentAction.name]);
72
+ process.exit(STATUS_BAD_PARAM);
73
+ }
74
+
75
+ if (
76
+ ![actions.init, actions.install, actions.update].includes(currentAction) &&
77
+ options.DOCKER_IMAGE
78
+ ) {
79
+ console.error(chalk.red('Invalid flag: image'));
80
+ printUsage(undefined, [currentAction.name]);
74
81
  process.exit(STATUS_BAD_PARAM);
75
82
  }
76
83
 
77
84
  readProjectInfo()
78
85
  .then((info) =>
79
- options.ACTION.fn(
86
+ currentAction.fn(
80
87
  {
81
88
  ...info,
82
89
  options,
83
- ...options.ACTION,
90
+ ...currentAction,
84
91
  },
85
- options.PARAMS
92
+ options.PARAMS ?? []
86
93
  )
87
94
  )
88
95
  .catch((e) => {
@@ -2,6 +2,7 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
4
  const _ = require('lodash');
5
+
5
6
  const {
6
7
  LIBDRAGON_SUBMODULE,
7
8
  LIBDRAGON_BRANCH,
@@ -9,6 +10,7 @@ const {
9
10
  CONTAINER_TARGET_PATH,
10
11
  LIBDRAGON_PROJECT_MANIFEST,
11
12
  } = require('./constants');
13
+
12
14
  const {
13
15
  spawnProcess,
14
16
  checkContainerAndClean,
@@ -27,6 +29,8 @@ const {
27
29
  tryCacheContainerId,
28
30
  } = require('./helpers');
29
31
 
32
+ const { printUsage } = require('./usage');
33
+
30
34
  const destroyContainer = async (libdragonInfo) => {
31
35
  if (libdragonInfo.containerId) {
32
36
  await spawnProcess('docker', [
@@ -60,27 +64,60 @@ const initSubmodule = async (libdragonInfo) => {
60
64
  };
61
65
 
62
66
  /**
63
- * Will download image and create a new container
67
+ * Downloads the given docker image. Returns false if the local image is the
68
+ * same, new image name otherwise.
69
+ * @param libdragonInfo
70
+ * @param newImageName
71
+ * @returns false | string
64
72
  */
65
- const initContainer = async (libdragonInfo) => {
66
- let newId;
67
- try {
68
- const imageName =
69
- libdragonInfo.imageName ?? libdragonInfo.options.DOCKER_IMAGE;
70
- await updateImageName({
71
- ...libdragonInfo,
72
- imageName,
73
- });
73
+ const updateImage = async (libdragonInfo, newImageName) => {
74
+ // Will not take too much time if already have the same
75
+ const download = async () => {
76
+ libdragonInfo.showStatus &&
77
+ log(`Downloading docker image: ${newImageName}`);
78
+ await spawnProcess(
79
+ 'docker',
80
+ ['pull', newImageName],
81
+ false,
82
+ libdragonInfo.showStatus
83
+ );
84
+ };
74
85
 
75
- // Download image
76
- libdragonInfo.showStatus && log(`Downloading docker image: ${imageName}`);
86
+ const getDigest = async () =>
77
87
  await spawnProcess(
78
88
  'docker',
79
- ['pull', imageName],
89
+ ['images', '-q', '--no-trunc', newImageName],
80
90
  false,
81
91
  libdragonInfo.showStatus
82
92
  );
83
93
 
94
+ // Attempt to compare digests if the new image name is the same
95
+ // Even if they are not the same tag, it is possible to have a different
96
+ // image but we already attempt a download in any case. It would just take
97
+ // less time as we already have the layers.
98
+ if (libdragonInfo.imageName === newImageName) {
99
+ const existingDigest = await getDigest();
100
+ await download();
101
+ const newDigest = await getDigest();
102
+
103
+ if (existingDigest === newDigest) {
104
+ libdragonInfo.showStatus && log(`Image is the same: ${newImageName}`);
105
+ return false;
106
+ }
107
+ } else {
108
+ await download();
109
+ }
110
+
111
+ libdragonInfo.showStatus && log(`Image is different: ${newImageName}`);
112
+ return newImageName;
113
+ };
114
+
115
+ /**
116
+ * Create a new container
117
+ */
118
+ const initContainer = async (libdragonInfo) => {
119
+ let newId;
120
+ try {
84
121
  // Create a new container
85
122
  libdragonInfo.showStatus && log('Creating new container...');
86
123
  newId = (
@@ -93,7 +130,7 @@ const initContainer = async (libdragonInfo) => {
93
130
  ',target=' +
94
131
  CONTAINER_TARGET_PATH, // Mount files
95
132
  '-w=' + CONTAINER_TARGET_PATH, // Set working directory
96
- imageName,
133
+ libdragonInfo.imageName,
97
134
  'tail',
98
135
  '-f',
99
136
  '/dev/null',
@@ -103,7 +140,6 @@ const initContainer = async (libdragonInfo) => {
103
140
  const newInfo = {
104
141
  ...libdragonInfo,
105
142
  containerId: newId,
106
- imageName,
107
143
  };
108
144
 
109
145
  // chown the installation folder once on init
@@ -140,6 +176,9 @@ const initContainer = async (libdragonInfo) => {
140
176
  log(
141
177
  chalk.green(`Successfully initialized docker container: ${name.trim()}`)
142
178
  );
179
+
180
+ // Update the image name only after everything is OK
181
+ await updateImageName(libdragonInfo);
143
182
  return newId;
144
183
  };
145
184
 
@@ -183,6 +222,7 @@ function copyDirContents(src, dst) {
183
222
 
184
223
  /**
185
224
  * Initialize a new libdragon project in current working directory
225
+ * Also downloads the image
186
226
  */
187
227
  async function init(libdragonInfo) {
188
228
  log(`Initializing a libdragon project at ${libdragonInfo.root}`);
@@ -198,9 +238,14 @@ async function init(libdragonInfo) {
198
238
  `${path.join(
199
239
  libdragonInfo.root,
200
240
  manifestFile
201
- )} exists. This is probably already a libdragon project, starting it...`
241
+ )} exists. This is already a libdragon project, starting it...`
202
242
  );
203
- await startAndInstall(libdragonInfo);
243
+ if (libdragonInfo.options.DOCKER_IMAGE) {
244
+ log(
245
+ `Not changing docker image. Use the install action if you want to override the image.`
246
+ );
247
+ }
248
+ await install(libdragonInfo);
204
249
  return;
205
250
  }
206
251
 
@@ -218,7 +263,13 @@ async function init(libdragonInfo) {
218
263
  }
219
264
 
220
265
  await createManifestIfNotExist(libdragonInfo);
221
- const newId = await start(libdragonInfo);
266
+ // Download image and start it
267
+ const newId = await start({
268
+ ...libdragonInfo,
269
+ imageName:
270
+ (await updateImage(libdragonInfo, libdragonInfo.imageName)) ||
271
+ libdragonInfo.imageName,
272
+ });
222
273
  const newInfo = {
223
274
  ...libdragonInfo,
224
275
  containerId: newId,
@@ -301,7 +352,7 @@ const exec = async (libdragonInfo, commandAndParams) => {
301
352
  let started = false;
302
353
  const startOnceAndCmd = async () => {
303
354
  if (!started) {
304
- const newId = await startAndInstall(libdragonInfo);
355
+ const newId = await start(libdragonInfo);
305
356
  started = true;
306
357
  await tryCmd({
307
358
  ...libdragonInfo,
@@ -440,17 +491,6 @@ const installDependencies = async (libdragonInfo) => {
440
491
  }
441
492
  };
442
493
 
443
- async function startAndInstall(libdragonInfo) {
444
- const containerId = await start(libdragonInfo);
445
-
446
- // TODO: skip if unnecessary
447
- await installDependencies({
448
- ...libdragonInfo,
449
- containerId,
450
- });
451
- return containerId;
452
- }
453
-
454
494
  const update = async (libdragonInfo) => {
455
495
  const containerId = await start(libdragonInfo);
456
496
 
@@ -484,13 +524,26 @@ const update = async (libdragonInfo) => {
484
524
  await install(newInfo);
485
525
  };
486
526
 
527
+ /**
528
+ * Updates the image if flag is provided and install vendors onto the container.
529
+ * We should probably remove the image installation responsibility from this
530
+ * action but it might be a breaking change. Maybe we can keep it backward
531
+ * compatible with additional flags.
532
+ * @param libdragonInfo
533
+ */
487
534
  const install = async (libdragonInfo) => {
488
535
  let containerId;
489
536
  const oldImageName = libdragonInfo.imageName;
490
- const imageName = libdragonInfo.options.DOCKER_IMAGE ?? oldImageName;
491
- if (oldImageName !== imageName) {
537
+ const imageName = libdragonInfo.options.DOCKER_IMAGE;
538
+ // If an image is provided, always attempt to install it
539
+ // See https://github.com/anacierdem/libdragon-docker/issues/47
540
+ if (imageName) {
492
541
  log(`Changing image from \`${oldImageName}\` to \`${imageName}\``);
493
- await destroyContainer(libdragonInfo);
542
+
543
+ // Download the new image and if it is different, re-create the container
544
+ if (await updateImage(libdragonInfo, imageName)) {
545
+ await destroyContainer(libdragonInfo);
546
+ }
494
547
 
495
548
  containerId = await start({
496
549
  ...libdragonInfo,
@@ -502,6 +555,7 @@ const install = async (libdragonInfo) => {
502
555
  }
503
556
 
504
557
  // Re-install vendors on new image
558
+ // TODO: skip this if unnecessary
505
559
  await installDependencies({
506
560
  ...libdragonInfo,
507
561
  imageName,
@@ -509,59 +563,49 @@ const install = async (libdragonInfo) => {
509
563
  });
510
564
  };
511
565
 
512
- const help = () => {
513
- log(`${chalk.green('Usage:')}
514
- libdragon [flags] <action>
515
-
516
- ${chalk.green('Available Commands:')}
517
- help Display this help information.
518
- init Create a libdragon project in the current directory.
519
- make Run the libdragon build system in the current directory.
520
- exec Execute given command in the current directory.
521
- start Start the container for current project.
522
- stop Stop the container for current project.
523
- install Vendor libdragon as is.
524
- update Update libdragon and do an install.
525
-
526
- ${chalk.green('Flags:')}
527
- --image <docker-image> Provide a custom image.
528
- --verbose Be verbose
529
- `);
530
- };
531
-
566
+ // TODO: separate into files
532
567
  module.exports = {
533
568
  start: {
569
+ name: 'start',
534
570
  fn: start,
535
571
  showStatus: false, // This will only print out the id
536
572
  },
537
573
  init: {
574
+ name: 'init',
538
575
  fn: init,
539
576
  showStatus: true,
540
577
  },
541
578
  make: {
579
+ name: 'make',
542
580
  fn: make,
543
581
  forwardsRestParams: true,
544
582
  showStatus: true,
545
583
  },
546
584
  exec: {
585
+ name: 'exec',
547
586
  fn: exec,
548
587
  forwardsRestParams: true,
549
588
  showStatus: true,
550
589
  },
551
590
  stop: {
591
+ name: 'stop',
552
592
  fn: stop,
553
593
  showStatus: false, // This will only print out the id
554
594
  },
555
595
  install: {
596
+ name: 'install',
556
597
  fn: install,
557
598
  showStatus: true,
558
599
  },
559
600
  update: {
601
+ name: 'update',
560
602
  fn: update,
561
603
  showStatus: true,
562
604
  },
563
605
  help: {
564
- fn: help,
606
+ name: 'help',
607
+ fn: printUsage,
565
608
  showStatus: true,
609
+ forwardsRestParams: true,
566
610
  },
567
611
  };
@@ -0,0 +1,129 @@
1
+ const chalk = require('chalk');
2
+ const commandLineUsage = require('command-line-usage');
3
+
4
+ const { log } = require('./helpers');
5
+
6
+ const printUsage = (_, actionArr) => {
7
+ const globalOptionDefinitions = [
8
+ {
9
+ name: 'verbose',
10
+ description: 'Be verbose',
11
+ alias: 'v',
12
+ group: 'global',
13
+ },
14
+ ];
15
+
16
+ const optionDefinitions = [
17
+ {
18
+ name: 'image',
19
+ description: 'Provide a custom image.',
20
+ alias: 'i',
21
+ typeLabel: '<docker-image>',
22
+ group: 'docker',
23
+ },
24
+ ];
25
+
26
+ const actions = {
27
+ help: {
28
+ name: 'help [action]',
29
+ summary: 'Display this help information or details for the given action.',
30
+ },
31
+ init: {
32
+ name: 'init',
33
+ summary: 'Create a libdragon project in the current directory.',
34
+ description: `Creates a libdragon project in the current directory. Every libdragon project will have its own docker container instance. If you are in a git repository or an NPM project, libdragon will be initialized at their root also marking there with a \`.libdragon\` folder.
35
+
36
+ A git repository and a submodule at \`./libdragon\` will also be created. Do not remove the \`.libdragon\` folder and commit its contents if you are using git, as it keeps persistent libdragon project information.
37
+
38
+ If this is the first time you are creating a libdragon project at that location, this action will also create skeleton project files to kickstart things with the given image, if provided. For subsequent runs, it will act like \`start\` thus can be used to revive an existing project without modifying it.`,
39
+ group: ['docker'],
40
+ },
41
+ make: {
42
+ name: 'make [params]',
43
+ summary: 'Run the libdragon build system in the current directory.',
44
+ description: `Runs the libdragon build system in the current directory. It will mirror your current working directory to the container.
45
+
46
+ This action is a shortcut to the \`exec\` action under the hood.`,
47
+ },
48
+ exec: {
49
+ name: 'exec <command>',
50
+ summary: 'Execute given command in the current directory.',
51
+ description: `Executes the given command in the container passing down any arguments provided. If you change your host working directory, the command will be executed in the corresponding folder in the container as well.
52
+
53
+ This action will first try to execute the command in the container and if the container is not accessible, it will attempt a complete \`start\` cycle.
54
+
55
+ This will properly passthrough your TTY if you have one. So by running \`libdragon exec bash\` you can start an interactive bash session with full TTY support.`,
56
+ },
57
+ start: {
58
+ name: 'start',
59
+ summary: 'Start the container for current project.',
60
+ description:
61
+ 'Start the container assigned to the current libdragon project. Will first attempt to start an existing container if found, followed by a new container run and installation similar to the `install` action. Will always print out the container id on success.',
62
+ },
63
+ name: {
64
+ name: 'stop',
65
+ summary: 'Stop the container for current project.',
66
+ description:
67
+ 'Stop the container assigned to the current libdragon project.',
68
+ },
69
+ install: {
70
+ name: 'install',
71
+ summary: 'Vendor libdragon as is.',
72
+ group: ['docker'],
73
+ description: `Attempts to build and install everything libdragon related into the container. This includes all the tools and third parties used by libdragon except for the toolchain. If you have made changes to libdragon, you can execute this action to build everything based on your changes. Requires you to have an intact \`libdragon\` at the root of the project. If you are not working on libdragon, you can just use the \`update\` action instead.
74
+
75
+ This can be useful to recover from a half-baked container.`,
76
+ },
77
+ update: {
78
+ name: 'update',
79
+ summary: 'Update libdragon and do an install.',
80
+ description:
81
+ 'This action will update the submodule from the remote branch (`trunk`) with a merge strategy and then perform a `libdragon install`. You can use the `install` action to only update all libdragon related artifacts in the container.',
82
+ group: ['docker'],
83
+ },
84
+ };
85
+
86
+ const actionsToShow = actionArr
87
+ ?.filter((action) => Object.keys(actions).includes(action))
88
+ .filter((action) => !['help'].includes(action));
89
+
90
+ const sections = [
91
+ {
92
+ header: chalk.green('Usage:'),
93
+ content: 'libdragon [flags] <action>',
94
+ },
95
+ ...(actionsToShow?.length
96
+ ? actionsToShow.flatMap((action) => [
97
+ {
98
+ header: chalk.green(`${action} action:`),
99
+ content: actions[action].description,
100
+ },
101
+ actions[action].group
102
+ ? {
103
+ header: `accepted flags:`,
104
+ optionList: optionDefinitions,
105
+ group: actions[action].group,
106
+ }
107
+ : {},
108
+ ])
109
+ : [
110
+ {
111
+ header: chalk.green('Available Commands:'),
112
+ content: Object.values(actions).map((action) => ({
113
+ name: action.name,
114
+ summary: action.summary,
115
+ })),
116
+ },
117
+ ]),
118
+ {
119
+ header: chalk.green('Global flags:'),
120
+ optionList: globalOptionDefinitions,
121
+ },
122
+ ];
123
+ const usage = commandLineUsage(sections);
124
+ log(usage);
125
+ };
126
+
127
+ module.exports = {
128
+ printUsage,
129
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libdragon",
3
- "version": "10.2.1",
3
+ "version": "10.3.1",
4
4
  "description": "This is a docker wrapper for libdragon",
5
5
  "main": "index.js",
6
6
  "engines": {
@@ -35,6 +35,7 @@
35
35
  "homepage": "https://github.com/anacierdem/libdragon-docker#readme",
36
36
  "dependencies": {
37
37
  "chalk": "^4.1.0",
38
+ "command-line-usage": "^6.1.1",
38
39
  "lodash": "^4.17.20"
39
40
  },
40
41
  "devDependencies": {