libdragon 10.4.2 → 10.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,10 @@
1
1
  const chalk = require('chalk');
2
2
  const commandLineUsage = require('command-line-usage');
3
3
 
4
- const { log } = require('../helpers');
4
+ const { print } = require('../helpers');
5
5
 
6
- const printUsage = (_, actionArr) => {
6
+ const printUsage = (info) => {
7
+ const actions = require('./');
7
8
  const globalOptionDefinitions = [
8
9
  {
9
10
  name: 'verbose',
@@ -11,7 +12,6 @@ const printUsage = (_, actionArr) => {
11
12
  'Be verbose. This will print all commands dispatched and their outputs as well. Will also start printing error stack traces.',
12
13
  alias: 'v',
13
14
  typeLabel: ' ',
14
- group: 'global',
15
15
  },
16
16
  ];
17
17
 
@@ -26,7 +26,7 @@ const printUsage = (_, actionArr) => {
26
26
  },
27
27
  {
28
28
  name: 'directory',
29
- description: `Directory where libdragon files are expected. It must be a project relative path as it will be mounted on the docker container. The cli will create and manage it when using a non-manual strategy. Defaults to \`./libdragon\` if not provided.\n`,
29
+ description: `Directory where libdragon files are expected. It must be inside the libdragon project as it will be mounted on the docker container. The cli will create and manage it when using a non-manual strategy. Defaults to \`./libdragon\` if not provided.\n`,
30
30
  alias: 'd',
31
31
  typeLabel: '<path>',
32
32
  group: 'vendoring',
@@ -42,107 +42,48 @@ const printUsage = (_, actionArr) => {
42
42
  You can always switch to manual by re-running \`init\` with \`--strategy manual\`, though you will be responsible for managing the existing submodule/subtree. Also it is not possible to automatically switch back.
43
43
 
44
44
  With the \`manual\` strategy, it is still recommended to have a git repository at project root such that container actions can execute faster by caching the container id inside the \`.git\` folder.\n`,
45
- alias: 'v',
45
+ alias: 's',
46
46
  typeLabel: '<strategy>',
47
47
  group: 'vendoring',
48
48
  },
49
49
  ];
50
50
 
51
- // TODO: move these to respective actions
52
-
53
- const actions = {
54
- help: {
55
- name: 'help [action]',
56
- summary: 'Display this help information or details for the given action.',
57
- },
58
- init: {
59
- name: 'init',
60
- summary: 'Create a libdragon project in the current directory.',
61
- 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. Do not remove the \`.libdragon\` folder and commit its contents if you are using source control, as it keeps persistent libdragon project information.
62
-
63
- By default, a git repository and a submodule at \`./libdragon\` will be created to automatically update the vendored libdragon files on subsequent \`update\`s. If you intend to opt-out from this feature, see the \`--strategy manual\` flag to provide your self-managed libdragon copy. The default behaviour is intended for users who primarily want to consume libdragon as is.
64
-
65
- 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.`,
66
- group: ['docker', 'vendoring'],
67
- },
68
- make: {
69
- name: 'make [params]',
70
- summary: 'Run the libdragon build system in the current directory.',
71
- description: `Runs the libdragon build system in the current directory. It will mirror your current working directory to the container.
72
-
73
- Must be run in an initialized libdragon project. This action is a shortcut to the \`exec\` action under the hood.`,
74
- },
75
- exec: {
76
- name: 'exec <command>',
77
- summary: 'Execute given command in the current directory.',
78
- 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.
79
-
80
- 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.
81
-
82
- 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.
83
-
84
- Must be run in an initialized libdragon project.`,
85
- },
86
- start: {
87
- name: 'start',
88
- summary: 'Start the container for current project.',
89
- description: `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.
90
-
91
- Must be run in an initialized libdragon project.`,
92
- },
93
- name: {
94
- name: 'stop',
95
- summary: 'Stop the container for current project.',
96
- description: `Stop the container assigned to the current libdragon project.
97
-
98
- Must be run in an initialized libdragon project.`,
99
- },
100
- install: {
101
- name: 'install',
102
- summary: 'Vendor libdragon as is.',
103
- 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 vendoring target (also see the \`--directory\` flag). If you are not working on libdragon itself, you can just use the \`update\` action instead.
104
-
105
- Must be run in an initialized libdragon project. This can be useful to recover from a half-baked container.`,
106
- },
107
- update: {
108
- name: 'update',
109
- summary: 'Update libdragon and do an install.',
110
- description: `Will update the docker image and if you are using auto-vendoring (see \`--strategy\`), will also update the submodule/subtree from the remote branch (\`trunk\`) with a merge/squash strategy and then perform a \`libdragon install\`. You can use the \`install\` action to only update all libdragon related artifacts in the container.
111
-
112
- Must be run in an initialized libdragon project.`,
113
- group: ['docker'],
114
- },
115
- };
116
-
117
- const actionsToShow = actionArr
118
- ?.filter((action) => Object.keys(actions).includes(action))
119
- .filter((action) => !['help'].includes(action));
51
+ const actionsToShow =
52
+ info?.options.EXTRA_PARAMS?.filter(
53
+ (action) =>
54
+ Object.keys(actions).includes(action) && !['help'].includes(action)
55
+ ) ?? (info ? [info.options.CURRENT_ACTION.name] : []);
120
56
 
121
57
  const sections = [
122
58
  {
123
59
  header: chalk.green('Usage:'),
124
- content: 'libdragon [flags] <action>',
60
+ content: `libdragon [flags] <action>
61
+
62
+ Joining flags not supported, provide them separately like \`-v -i\` `,
125
63
  },
126
64
  ...(actionsToShow?.length
127
65
  ? actionsToShow.flatMap((action) => [
128
66
  {
129
67
  header: chalk.green(`${action} action:`),
130
- content: actions[action].description,
68
+ content: actions[action].usage.description,
131
69
  },
132
- actions[action].group
70
+ actions[action].usage.group || actions[action].usage.optionList
133
71
  ? {
134
72
  header: `accepted flags:`,
135
- optionList: optionDefinitions,
136
- group: actions[action].group,
73
+ optionList: [
74
+ ...(actions[action].usage.group ? optionDefinitions : []),
75
+ ...(actions[action].usage.optionList ?? []),
76
+ ],
77
+ group: actions[action].usage.group,
137
78
  }
138
79
  : {},
139
80
  ])
140
81
  : [
141
82
  {
142
83
  header: chalk.green('Available Commands:'),
143
- content: Object.values(actions).map((action) => ({
144
- name: action.name,
145
- summary: action.summary,
84
+ content: Object.values(actions).map(({ usage }) => ({
85
+ name: usage.name,
86
+ summary: usage.summary,
146
87
  })),
147
88
  },
148
89
  ]),
@@ -152,12 +93,16 @@ const printUsage = (_, actionArr) => {
152
93
  },
153
94
  ];
154
95
  const usage = commandLineUsage(sections);
155
- log(usage);
96
+ print(usage);
156
97
  };
157
98
 
158
99
  module.exports = {
159
100
  name: 'help',
160
101
  fn: printUsage,
161
- showStatus: true,
162
102
  forwardsRestParams: true,
103
+ mustHaveProject: false,
104
+ usage: {
105
+ name: 'help [action]',
106
+ summary: 'Display this help information or details for the given action.',
107
+ },
163
108
  };
@@ -1,25 +1,16 @@
1
- const { fn: exec } = require('./exec');
2
-
3
- const make = async (libdragonInfo, params) => {
4
- await exec(libdragonInfo, ['make', ...params]);
5
- };
6
-
7
- // TODO: separate into files
8
1
  module.exports = {
9
- start: require('./start'),
10
- stop: require('./stop'),
11
2
  init: require('./init'),
3
+ make: require('./make'),
12
4
 
5
+ update: require('./update'),
13
6
  exec: require('./exec'),
14
- make: {
15
- name: 'make',
16
- fn: make,
17
- forwardsRestParams: true,
18
- showStatus: true,
19
- },
20
-
7
+ disasm: require('./disasm'),
21
8
  install: require('./install'),
22
- update: require('./update'),
9
+
10
+ start: require('./start'),
11
+ stop: require('./stop'),
23
12
 
24
13
  help: require('./help'),
14
+ version: require('./version'),
15
+ destroy: require('./destroy'),
25
16
  };
@@ -1,13 +1,13 @@
1
1
  const fs = require('fs/promises');
2
2
  const path = require('path');
3
3
 
4
- const chalk = require('chalk');
4
+ const chalk = require('chalk').stderr;
5
5
 
6
6
  const { fn: install } = require('./install');
7
7
  const { start } = require('./start');
8
8
  const {
9
9
  installDependencies,
10
- tryCacheContainerId,
10
+ initGitAndCacheContainerId,
11
11
  updateImage,
12
12
  runGitMaybeHost,
13
13
  } = require('./utils');
@@ -24,8 +24,9 @@ const {
24
24
  CommandError,
25
25
  ParameterError,
26
26
  ValidationError,
27
+ toPosixPath,
28
+ toNativePath,
27
29
  } = require('../helpers');
28
- const { setProjectInfoToSave } = require('../project-info');
29
30
 
30
31
  const autoVendor = async (libdragonInfo) => {
31
32
  await runGitMaybeHost(libdragonInfo, ['init']);
@@ -79,10 +80,10 @@ const autoVendor = async (libdragonInfo) => {
79
80
  * Initialize a new libdragon project in current working directory
80
81
  * Also downloads the image
81
82
  */
82
- async function init(libdragonInfo) {
83
- log(`Initializing a libdragon project at ${libdragonInfo.root}`);
83
+ async function init(info) {
84
+ log(`Initializing a libdragon project at ${info.root}`);
84
85
 
85
- let newInfo = libdragonInfo;
86
+ let newInfo = info;
86
87
 
87
88
  // Validate manifest
88
89
  const manifestPath = path.join(newInfo.root, LIBDRAGON_PROJECT_MANIFEST);
@@ -105,31 +106,29 @@ async function init(libdragonInfo) {
105
106
  newInfo.vendorStrategy !== newInfo.options.VENDOR_STRAT
106
107
  ) {
107
108
  throw new ParameterError(
108
- `Requested strategy switch: ${newInfo.vendorStrategy} -> ${newInfo.options.VENDOR_STRAT} It is not possible to switch vendoring strategy after initializing a project. You can always switch to manual and handle libdragon yourself.`
109
+ `Requested strategy switch: ${newInfo.vendorStrategy} -> ${newInfo.options.VENDOR_STRAT} It is not possible to switch vendoring strategy after initializing a project. You can always switch to manual and handle libdragon yourself.`,
110
+ info.options.CURRENT_ACTION.name
109
111
  );
110
112
  }
111
113
 
112
114
  // Update the strategy information for the project if the flag is provided
113
115
  if (newInfo.options.VENDOR_STRAT) {
114
- newInfo = setProjectInfoToSave({
115
- ...newInfo,
116
- vendorStrategy: newInfo.options.VENDOR_STRAT,
117
- });
116
+ newInfo.vendorStrategy = newInfo.options.VENDOR_STRAT;
118
117
  }
119
118
 
120
119
  // Update the directory information for the project if the flag is provided
121
120
  if (newInfo.options.VENDOR_DIR) {
121
+ const relativeVendorDir = path.relative(info.root, info.options.VENDOR_DIR);
122
122
  // Validate vendoring path
123
- if (path.isAbsolute(newInfo.options.VENDOR_DIR)) {
123
+ if (relativeVendorDir.startsWith('..')) {
124
124
  throw new ParameterError(
125
- '`--directory` must be project-relative as it will be mounted to the docker container.'
125
+ `\`--directory=${info.options.VENDOR_DIR}\` is outside the project directory.`,
126
+ info.options.CURRENT_ACTION.name
126
127
  );
127
128
  }
128
129
 
129
- newInfo = setProjectInfoToSave({
130
- ...newInfo,
131
- vendorDirectory: newInfo.options.VENDOR_DIR,
132
- });
130
+ // Immeditately convert it to a posix and relative path
131
+ newInfo.vendorDirectory = toPosixPath(relativeVendorDir);
133
132
  }
134
133
 
135
134
  if (newInfo.haveProjectConfig) {
@@ -145,57 +144,63 @@ async function init(libdragonInfo) {
145
144
  );
146
145
  }
147
146
  // TODO: we may make sure git and submodule is initialized here
148
- await install(newInfo);
149
- return;
147
+ return await install(newInfo);
150
148
  }
151
149
 
152
- newInfo.imageName =
153
- (await updateImage(newInfo, newInfo.imageName)) || newInfo.imageName;
150
+ await updateImage(newInfo, newInfo.imageName);
151
+
154
152
  // Download image and start it
155
- const containerReadyPromise = start(newInfo, true).then((newId) => ({
156
- ...newInfo,
157
- containerId: newId,
158
- }));
153
+ newInfo.containerId = await start(newInfo);
154
+
155
+ // We have created a new container, save the new info ASAP
156
+ await initGitAndCacheContainerId(newInfo);
159
157
 
160
- let vendorAndGitReadyPromise = containerReadyPromise;
161
158
  if (newInfo.vendorStrategy !== 'manual') {
162
- const vendorTarget = path.relative(newInfo.root, newInfo.vendorDirectory);
163
- const [vendorTargetExists] = await Promise.all([
164
- fs.stat(vendorTarget).catch((e) => {
165
- if (e.code !== 'ENOENT') throw e;
166
- return false;
167
- }),
168
- containerReadyPromise,
169
- ]);
159
+ const vendorTarget = path.relative(
160
+ newInfo.root,
161
+ toNativePath(newInfo.vendorDirectory)
162
+ );
163
+ const vendorTargetExists = await fs.stat(vendorTarget).catch((e) => {
164
+ if (e.code !== 'ENOENT') throw e;
165
+ return false;
166
+ });
170
167
 
171
168
  if (vendorTargetExists) {
172
169
  throw new ValidationError(
173
170
  `${path.resolve(
174
- newInfo.root,
175
- newInfo.vendorDirectory
171
+ vendorTarget
176
172
  )} already exists. That is the libdragon vendoring target, please remove and retry.`
177
173
  );
178
174
  }
179
175
 
180
- vendorAndGitReadyPromise = containerReadyPromise.then(autoVendor);
176
+ newInfo = await autoVendor(newInfo);
181
177
  }
182
178
 
183
179
  log(`Preparing project files...`);
184
180
  const skeletonFolder = path.join(__dirname, '../../skeleton');
185
181
 
186
182
  await Promise.all([
187
- // We have created a new container, save the new info
188
- vendorAndGitReadyPromise.then(tryCacheContainerId),
189
- vendorAndGitReadyPromise.then(installDependencies),
183
+ installDependencies(newInfo),
190
184
  // node copy functions does not work with pkg
191
185
  copyDirContents(skeletonFolder, newInfo.root),
192
186
  ]);
193
187
 
194
188
  log(chalk.green(`libdragon ready at \`${newInfo.root}\`.`));
189
+ return newInfo;
195
190
  }
196
191
 
197
192
  module.exports = {
198
193
  name: 'init',
199
194
  fn: init,
200
- showStatus: true,
195
+ mustHaveProject: false,
196
+ usage: {
197
+ name: 'init',
198
+ summary: 'Create a libdragon project in the current directory.',
199
+ 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. Do not remove the \`.libdragon\` folder and commit its contents if you are using source control, as it keeps persistent libdragon project information.
200
+
201
+ By default, a git repository and a submodule at \`./libdragon\` will be created to automatically update the vendored libdragon files on subsequent \`update\`s. If you intend to opt-out from this feature, see the \`--strategy manual\` flag to provide your self-managed libdragon copy. The default behaviour is intended for users who primarily want to consume libdragon as is.
202
+
203
+ 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.`,
204
+ group: ['docker', 'vendoring'],
205
+ },
201
206
  };
@@ -1,6 +1,6 @@
1
- const chalk = require('chalk');
1
+ const chalk = require('chalk').stderr;
2
2
 
3
- const { installDependencies, mustHaveProject } = require('./utils');
3
+ const { installDependencies } = require('./utils');
4
4
  const { start } = require('./start');
5
5
  const { updateAndStart } = require('./update-and-start');
6
6
  const { log } = require('../helpers');
@@ -17,7 +17,6 @@ const { log } = require('../helpers');
17
17
  * we still keep that logic but with a deprecation warning.
18
18
  */
19
19
  const install = async (libdragonInfo, skipUpdate) => {
20
- await mustHaveProject(libdragonInfo);
21
20
  let updatedInfo = libdragonInfo;
22
21
  const imageName = libdragonInfo.options.DOCKER_IMAGE;
23
22
  // If an image is provided, attempt to install
@@ -39,10 +38,17 @@ const install = async (libdragonInfo, skipUpdate) => {
39
38
  // Re-install vendors on new image
40
39
  // TODO: skip this if unnecessary
41
40
  await installDependencies(updatedInfo);
41
+ return updatedInfo;
42
42
  };
43
43
 
44
44
  module.exports = {
45
45
  name: 'install',
46
46
  fn: install,
47
- showStatus: true,
47
+ usage: {
48
+ name: 'install',
49
+ summary: 'Vendor libdragon as is.',
50
+ 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 vendoring target (also see the \`--directory\` flag). If you are not working on libdragon itself, you can just use the \`update\` action instead.
51
+
52
+ Must be run in an initialized libdragon project. This can be useful to recover from a half-baked container.`,
53
+ },
48
54
  };
@@ -0,0 +1,24 @@
1
+ const { fn: exec } = require('./exec');
2
+
3
+ const make = async (info) => {
4
+ return await exec({
5
+ ...info,
6
+ options: {
7
+ ...info.options,
8
+ EXTRA_PARAMS: ['make', ...info.options.EXTRA_PARAMS],
9
+ },
10
+ });
11
+ };
12
+
13
+ module.exports = {
14
+ name: 'make',
15
+ fn: make,
16
+ forwardsRestParams: true,
17
+ usage: {
18
+ name: 'make [params]',
19
+ summary: 'Run the libdragon build system in the current directory.',
20
+ description: `Runs the libdragon build system in the current directory. It will mirror your current working directory to the container.
21
+
22
+ Must be run in an initialized libdragon project. This action is a shortcut to the \`exec\` action under the hood.`,
23
+ },
24
+ };
@@ -0,0 +1,122 @@
1
+ const path = require('path');
2
+ const fsClassic = require('fs');
3
+
4
+ const _ = require('lodash');
5
+
6
+ const { dockerHostUserParams } = require('./docker-utils');
7
+
8
+ const { CONTAINER_TARGET_PATH } = require('../constants');
9
+ const {
10
+ fileExists,
11
+ toPosixPath,
12
+ spawnProcess,
13
+ dockerExec,
14
+ ValidationError,
15
+ } = require('../helpers');
16
+
17
+ async function findNPMRoot() {
18
+ try {
19
+ const root = path.resolve((await runNPM(['root'])).trim(), '..');
20
+ // Only report if package.json really exists. npm fallbacks to cwd
21
+ if (await fileExists(path.join(root, 'package.json'))) {
22
+ return root;
23
+ }
24
+ } catch {
25
+ // User does not have and does not care about NPM if it didn't work
26
+ return undefined;
27
+ }
28
+ }
29
+
30
+ // Install other NPM dependencies if this is an NPM project
31
+ const installNPMDependencies = async (libdragonInfo) => {
32
+ const npmRoot = await findNPMRoot();
33
+ if (npmRoot) {
34
+ const packageJsonPath = path.join(npmRoot, 'package.json');
35
+
36
+ const { dependencies, devDependencies } = require(packageJsonPath);
37
+
38
+ const deps = await Promise.all(
39
+ Object.keys({
40
+ ...dependencies,
41
+ ...devDependencies,
42
+ })
43
+ .filter((dep) => dep !== 'libdragon')
44
+ .map(async (dep) => {
45
+ const npmPath = await runNPM(['ls', dep, '--parseable=true']);
46
+ return {
47
+ name: dep,
48
+ paths: _.uniq(npmPath.split('\n').filter((f) => f)),
49
+ };
50
+ })
51
+ );
52
+
53
+ await Promise.all(
54
+ deps.map(({ name, paths }) => {
55
+ return new Promise((resolve, reject) => {
56
+ fsClassic.access(
57
+ path.join(paths[0], 'Makefile'),
58
+ fsClassic.F_OK,
59
+ async (e) => {
60
+ if (e) {
61
+ // File does not exist - skip
62
+ resolve();
63
+ return;
64
+ }
65
+
66
+ if (paths.length > 1) {
67
+ reject(
68
+ new ValidationError(
69
+ `Using same dependency with different versions is not supported! ${name}`
70
+ )
71
+ );
72
+ return;
73
+ }
74
+
75
+ try {
76
+ const relativePath = toPosixPath(
77
+ path.relative(libdragonInfo.root, paths[0])
78
+ );
79
+ const containerPath = path.posix.join(
80
+ CONTAINER_TARGET_PATH,
81
+ relativePath
82
+ );
83
+ const makePath = path.posix.join(containerPath, 'Makefile');
84
+
85
+ await dockerExec(
86
+ libdragonInfo,
87
+ [...dockerHostUserParams(libdragonInfo)],
88
+ [
89
+ '/bin/bash',
90
+ '-c',
91
+ '[ -f ' +
92
+ makePath +
93
+ ' ] && make -C ' +
94
+ containerPath +
95
+ ' && make -C ' +
96
+ containerPath +
97
+ ' install',
98
+ ]
99
+ );
100
+
101
+ resolve();
102
+ } catch (e) {
103
+ reject(e);
104
+ }
105
+ }
106
+ );
107
+ });
108
+ })
109
+ );
110
+ }
111
+ };
112
+
113
+ function runNPM(params) {
114
+ return spawnProcess(
115
+ /^win/.test(process.platform) ? 'npm.cmd' : 'npm',
116
+ params
117
+ );
118
+ }
119
+ module.exports = {
120
+ installNPMDependencies,
121
+ findNPMRoot,
122
+ };
@@ -1,14 +1,12 @@
1
- const chalk = require('chalk');
1
+ const chalk = require('chalk').stderr;
2
2
 
3
3
  const { CONTAINER_TARGET_PATH } = require('../constants');
4
- const { spawnProcess, log, dockerExec } = require('../helpers');
5
- const { setProjectInfoToSave } = require('../project-info');
4
+ const { spawnProcess, log, print, dockerExec } = require('../helpers');
6
5
 
7
6
  const {
8
7
  checkContainerAndClean,
9
8
  checkContainerRunning,
10
9
  destroyContainer,
11
- mustHaveProject,
12
10
  } = require('./utils');
13
11
 
14
12
  /**
@@ -18,7 +16,7 @@ const initContainer = async (libdragonInfo) => {
18
16
  let newId;
19
17
  try {
20
18
  // Create a new container
21
- libdragonInfo.showStatus && log('Creating new container...');
19
+ log('Creating new container...');
22
20
  newId = (
23
21
  await spawnProcess('docker', [
24
22
  'run',
@@ -71,18 +69,12 @@ const initContainer = async (libdragonInfo) => {
71
69
  '{{.Name}}',
72
70
  ]);
73
71
 
74
- libdragonInfo.showStatus &&
75
- log(
76
- chalk.green(`Successfully initialized docker container: ${name.trim()}`)
77
- );
72
+ log(chalk.green(`Successfully initialized docker container: ${name.trim()}`));
78
73
 
79
- // Schedule an update to write image name
80
- setProjectInfoToSave(libdragonInfo);
81
74
  return newId;
82
75
  };
83
76
 
84
- const start = async (libdragonInfo, skipProjectCheck) => {
85
- !skipProjectCheck && (await mustHaveProject(libdragonInfo));
77
+ const start = async (libdragonInfo) => {
86
78
  const running =
87
79
  libdragonInfo.containerId &&
88
80
  (await checkContainerRunning(libdragonInfo.containerId));
@@ -108,7 +100,17 @@ const start = async (libdragonInfo, skipProjectCheck) => {
108
100
 
109
101
  module.exports = {
110
102
  name: 'start',
111
- fn: async (libdragonInfo) => log(await start(libdragonInfo)),
103
+ fn: async (libdragonInfo) => {
104
+ const containerId = await start(libdragonInfo);
105
+ print(containerId);
106
+ return { ...libdragonInfo, containerId };
107
+ },
112
108
  start,
113
- showStatus: false, // This will only print out the id
109
+ usage: {
110
+ name: 'start',
111
+ summary: 'Start the container for current project.',
112
+ description: `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 to stdout on success except when verbose is set.
113
+
114
+ Must be run in an initialized libdragon project.`,
115
+ },
114
116
  };
@@ -1,9 +1,8 @@
1
1
  const { spawnProcess } = require('../helpers');
2
2
 
3
- const { checkContainerRunning, mustHaveProject } = require('./utils');
3
+ const { checkContainerRunning } = require('./utils');
4
4
 
5
5
  const stop = async (libdragonInfo) => {
6
- await mustHaveProject(libdragonInfo);
7
6
  const running =
8
7
  libdragonInfo.containerId &&
9
8
  (await checkContainerRunning(libdragonInfo.containerId));
@@ -12,10 +11,17 @@ const stop = async (libdragonInfo) => {
12
11
  }
13
12
 
14
13
  await spawnProcess('docker', ['container', 'stop', running]);
14
+ return libdragonInfo;
15
15
  };
16
16
 
17
17
  module.exports = {
18
18
  name: 'stop',
19
19
  fn: stop,
20
- showStatus: false, // This will only print out the id
20
+ usage: {
21
+ name: 'stop',
22
+ summary: 'Stop the container for current project.',
23
+ description: `Stop the container assigned to the current libdragon project.
24
+
25
+ Must be run in an initialized libdragon project.`,
26
+ },
21
27
  };