libdragon 10.7.1 → 10.8.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.
@@ -3,7 +3,6 @@ const path = require('path');
3
3
 
4
4
  const chalk = require('chalk').stderr;
5
5
 
6
- const { fn: install } = require('./install');
7
6
  const { start } = require('./start');
8
7
  const {
9
8
  installDependencies,
@@ -27,33 +26,149 @@ const {
27
26
  toPosixPath,
28
27
  toNativePath,
29
28
  } = require('../helpers');
29
+ const { syncImageAndStart } = require('./update-and-start');
30
30
 
31
- const autoVendor = async (libdragonInfo) => {
32
- await runGitMaybeHost(libdragonInfo, ['init']);
31
+ /**
32
+ * @param {import('../project-info').LibdragonInfo} info
33
+ * @return {Promise<"submodule" | "subtree" | undefined>}
34
+ */
35
+ const autoDetect = async (info) => {
36
+ const vendorTarget = path.relative(
37
+ info.root,
38
+ toNativePath(info.vendorDirectory)
39
+ );
40
+ const vendorTargetExists = await fs.stat(vendorTarget).catch((e) => {
41
+ if (e.code !== 'ENOENT') throw e;
42
+ return false;
43
+ });
33
44
 
34
- if (libdragonInfo.vendorStrategy === 'submodule') {
35
- await runGitMaybeHost(libdragonInfo, [
45
+ if (
46
+ vendorTargetExists &&
47
+ (await runGitMaybeHost(info, [
36
48
  'submodule',
37
- 'add',
38
- '--force',
39
- '--name',
40
- LIBDRAGON_SUBMODULE,
41
- '--branch',
42
- LIBDRAGON_BRANCH,
43
- LIBDRAGON_GIT,
44
- libdragonInfo.vendorDirectory,
45
- ]);
46
- } else if (libdragonInfo.vendorStrategy === 'subtree') {
49
+ 'status',
50
+ info.vendorDirectory,
51
+ ]).catch((e) => {
52
+ if (!(e instanceof CommandError)) {
53
+ throw e;
54
+ }
55
+ }))
56
+ ) {
57
+ log(`${info.vendorDirectory} is a submodule.`);
58
+ return 'submodule';
59
+ }
60
+
61
+ if (vendorTargetExists) {
62
+ const gitLogs = await runGitMaybeHost(info, ['log'], {
63
+ inheritStdin: false,
64
+ inheritStdout: false,
65
+ inheritStderr: false,
66
+ }).catch((e) => {
67
+ if (!(e instanceof CommandError)) {
68
+ throw e;
69
+ }
70
+ });
71
+
72
+ if (
73
+ gitLogs &&
74
+ gitLogs.includes(`git-subtree-dir: ${info.vendorDirectory}`)
75
+ ) {
76
+ log(`${info.vendorDirectory} is a subtree.`);
77
+ return 'subtree';
78
+ }
79
+ }
80
+ };
81
+
82
+ /**
83
+ * @param {import('../project-info').LibdragonInfo} info
84
+ */
85
+ const autoVendor = async (info) => {
86
+ // Update the strategy information for the project if the flag is provided
87
+ if (info.options.VENDOR_STRAT) {
88
+ info.vendorStrategy = info.options.VENDOR_STRAT;
89
+ }
90
+
91
+ // Update the directory information for the project if the flag is provided
92
+ if (info.options.VENDOR_DIR) {
93
+ const relativeVendorDir = path.relative(info.root, info.options.VENDOR_DIR);
94
+ // Validate vendoring path
95
+ if (relativeVendorDir.startsWith('..')) {
96
+ throw new ParameterError(
97
+ `\`--directory=${info.options.VENDOR_DIR}\` is outside the project directory.`,
98
+ info.options.CURRENT_ACTION.name
99
+ );
100
+ }
101
+
102
+ // Immeditately convert it to a posix and relative path
103
+ info.vendorDirectory = toPosixPath(relativeVendorDir);
104
+ }
105
+
106
+ // No need to do anything here
107
+ if (info.vendorStrategy === 'manual') {
108
+ return info;
109
+ }
110
+
111
+ await runGitMaybeHost(info, ['init']);
112
+
113
+ // TODO: TS thinks this is already defined
114
+ const detectedStrategy = await autoDetect(info);
115
+
116
+ if (
117
+ info.options.VENDOR_STRAT &&
118
+ detectedStrategy &&
119
+ detectedStrategy !== info.options.VENDOR_STRAT
120
+ ) {
121
+ throw new ValidationError(
122
+ `${info.vendorDirectory} is a ${detectedStrategy} which is different from the provided strategy: ${info.options.VENDOR_STRAT}.`
123
+ );
124
+ }
125
+
126
+ if (detectedStrategy) {
127
+ log(
128
+ `Using ${info.vendorDirectory} as a ${detectedStrategy} vendoring target.`
129
+ );
130
+ return {
131
+ ...info,
132
+ vendorStrategy: /** @type {import('../parameters').VendorStrategy} */ (
133
+ detectedStrategy
134
+ ),
135
+ };
136
+ }
137
+
138
+ if (info.vendorStrategy === 'submodule') {
139
+ try {
140
+ await runGitMaybeHost(info, [
141
+ 'submodule',
142
+ 'add',
143
+ '--force',
144
+ '--name',
145
+ LIBDRAGON_SUBMODULE,
146
+ '--branch',
147
+ LIBDRAGON_BRANCH,
148
+ LIBDRAGON_GIT,
149
+ info.vendorDirectory,
150
+ ]);
151
+ } catch (e) {
152
+ if (!(e instanceof CommandError)) throw e;
153
+ // We speculate this is caused by the user, so replace it with a more useful error message.
154
+ e.message = `Unable to create submodule. If you have copied the executable in your project folder or you have a file named ${info.vendorDirectory}, removing it might solve this issue. Original error:\n${e.message}`;
155
+ throw e;
156
+ }
157
+
158
+ return info;
159
+ }
160
+
161
+ if (info.vendorStrategy === 'subtree') {
47
162
  // Create a commit if it does not exist. This is required for subtree.
48
163
  try {
49
- await runGitMaybeHost(libdragonInfo, ['rev-parse', 'HEAD']);
164
+ await runGitMaybeHost(info, ['rev-parse', 'HEAD']);
50
165
  } catch (e) {
51
166
  if (!(e instanceof CommandError)) throw e;
52
167
 
53
168
  // This will throw if git user name/email is not set up. Let's not assume
54
169
  // anything for now. This means subtree is not supported for someone without
55
170
  // git on the host machine.
56
- await runGitMaybeHost(libdragonInfo, [
171
+ await runGitMaybeHost(info, [
57
172
  'commit',
58
173
  '--allow-empty',
59
174
  '-n',
@@ -62,34 +177,32 @@ const autoVendor = async (libdragonInfo) => {
62
177
  ]);
63
178
  }
64
179
 
65
- await runGitMaybeHost(libdragonInfo, [
180
+ await runGitMaybeHost(info, [
66
181
  'subtree',
67
182
  'add',
68
183
  '--prefix',
69
- path.relative(libdragonInfo.root, libdragonInfo.vendorDirectory),
184
+ path.relative(info.root, info.vendorDirectory),
70
185
  LIBDRAGON_GIT,
71
186
  LIBDRAGON_BRANCH,
72
187
  '--squash',
73
188
  ]);
189
+ return info;
74
190
  }
75
-
76
- return libdragonInfo;
77
191
  };
78
192
 
79
193
  /**
80
194
  * Initialize a new libdragon project in current working directory
81
195
  * Also downloads the image
196
+ * @param {import('../project-info').LibdragonInfo} info
82
197
  */
83
198
  async function init(info) {
84
199
  log(`Initializing a libdragon project at ${info.root}`);
85
200
 
86
- let newInfo = info;
87
-
88
201
  // Validate manifest
89
- const manifestPath = path.join(newInfo.root, LIBDRAGON_PROJECT_MANIFEST);
202
+ const manifestPath = path.join(info.root, LIBDRAGON_PROJECT_MANIFEST);
90
203
  const manifestStats = await fs.stat(manifestPath).catch((e) => {
91
204
  if (e.code !== 'ENOENT') throw e;
92
- return false;
205
+ return /** @type {const} */ (false);
93
206
  });
94
207
 
95
208
  if (manifestStats && !manifestStats.isDirectory()) {
@@ -98,101 +211,58 @@ async function init(info) {
98
211
  );
99
212
  }
100
213
 
101
- // Validate vendoring strategy. Do not allow a switch after successful initialization
102
- if (
103
- newInfo.haveProjectConfig &&
104
- newInfo.options.VENDOR_STRAT &&
105
- newInfo.options.VENDOR_STRAT !== 'manual' &&
106
- newInfo.vendorStrategy !== newInfo.options.VENDOR_STRAT
107
- ) {
108
- throw new ParameterError(
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
111
- );
112
- }
113
-
114
- // Update the strategy information for the project if the flag is provided
115
- if (newInfo.options.VENDOR_STRAT) {
116
- newInfo.vendorStrategy = newInfo.options.VENDOR_STRAT;
117
- }
118
-
119
- // Update the directory information for the project if the flag is provided
120
- if (newInfo.options.VENDOR_DIR) {
121
- const relativeVendorDir = path.relative(info.root, info.options.VENDOR_DIR);
122
- // Validate vendoring path
123
- if (relativeVendorDir.startsWith('..')) {
124
- throw new ParameterError(
125
- `\`--directory=${info.options.VENDOR_DIR}\` is outside the project directory.`,
126
- info.options.CURRENT_ACTION.name
127
- );
128
- }
129
-
130
- // Immeditately convert it to a posix and relative path
131
- newInfo.vendorDirectory = toPosixPath(relativeVendorDir);
132
- }
133
-
134
- if (newInfo.haveProjectConfig) {
214
+ if (info.haveProjectConfig) {
135
215
  log(
136
216
  `${path.join(
137
- newInfo.root,
217
+ info.root,
138
218
  LIBDRAGON_PROJECT_MANIFEST
139
219
  )} exists. This is already a libdragon project, starting it...`
140
220
  );
141
- if (newInfo.options.DOCKER_IMAGE) {
221
+ if (info.options.DOCKER_IMAGE) {
142
222
  log(
143
223
  `Not changing docker image. Use the install action if you want to override the image.`
144
224
  );
145
225
  }
146
- // TODO: we may make sure git and submodule is initialized here
147
- return await install(newInfo);
226
+ if (info.options.DOCKER_IMAGE) {
227
+ info = await syncImageAndStart(info);
228
+ } else {
229
+ info = {
230
+ ...info,
231
+ containerId: await start(info),
232
+ };
233
+ }
234
+ info = await autoVendor(info);
235
+ await installDependencies(info);
236
+ return info;
148
237
  }
149
238
 
150
- await updateImage(newInfo, newInfo.imageName);
239
+ await updateImage(info, info.imageName);
151
240
 
152
241
  // Download image and start it
153
- newInfo.containerId = await start(newInfo);
242
+ info.containerId = await start(info);
154
243
 
155
244
  // We have created a new container, save the new info ASAP
156
- await initGitAndCacheContainerId(newInfo);
245
+ await initGitAndCacheContainerId(info);
157
246
 
158
- if (newInfo.vendorStrategy !== 'manual') {
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
- });
167
-
168
- if (vendorTargetExists) {
169
- throw new ValidationError(
170
- `${path.resolve(
171
- vendorTarget
172
- )} already exists. That is the libdragon vendoring target, please remove and retry.`
173
- );
174
- }
175
-
176
- newInfo = await autoVendor(newInfo);
177
- }
247
+ info = await autoVendor(info);
178
248
 
179
249
  log(`Preparing project files...`);
180
250
  const skeletonFolder = path.join(__dirname, '../../skeleton');
181
251
 
182
252
  await Promise.all([
183
- installDependencies(newInfo),
253
+ installDependencies(info),
184
254
  // node copy functions does not work with pkg
185
- copyDirContents(skeletonFolder, newInfo.root),
255
+ copyDirContents(skeletonFolder, info.root),
186
256
  ]);
187
257
 
188
- log(chalk.green(`libdragon ready at \`${newInfo.root}\`.`));
189
- return newInfo;
258
+ log(chalk.green(`libdragon ready at \`${info.root}\`.`));
259
+ return info;
190
260
  }
191
261
 
192
- module.exports = {
262
+ module.exports = /** @type {const} */ ({
193
263
  name: 'init',
194
264
  fn: init,
195
- mustHaveProject: false,
265
+ forwardsRestParams: false,
196
266
  usage: {
197
267
  name: 'init',
198
268
  summary: 'Create a libdragon project in the current directory.',
@@ -200,7 +270,9 @@ module.exports = {
200
270
 
201
271
  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
272
 
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.`,
273
+ 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.
274
+
275
+ If you have an existing project with an already vendored submodule or subtree libdragon copy, \`init\` will automatically detect it at the provided \`--directory\`.`,
204
276
  group: ['docker', 'vendoring'],
205
277
  },
206
- };
278
+ });
@@ -2,31 +2,26 @@ const chalk = require('chalk').stderr;
2
2
 
3
3
  const { installDependencies } = require('./utils');
4
4
  const { start } = require('./start');
5
- const { updateAndStart } = require('./update-and-start');
5
+ const { syncImageAndStart } = require('./update-and-start');
6
6
  const { log } = require('../helpers');
7
7
 
8
8
  /**
9
9
  * Updates the image if flag is provided and install vendors onto the container.
10
10
  * We should probably remove the image installation responsibility from this
11
11
  * action but it might be a breaking change.
12
- * @param libdragonInfo
13
- * @param skipUpdate This is added to skip the update when calling this from
14
- * the update action as it already does an update itself. install doing an image
15
- * update is pretty much a useless operation, but let's keep it in case someone
16
- * depends on it. It used to only update the image if the flag is provided and
17
- * we still keep that logic but with a deprecation warning.
12
+ * @param {import('../project-info').LibdragonInfo} libdragonInfo
18
13
  */
19
- const install = async (libdragonInfo, skipUpdate) => {
14
+ const install = async (libdragonInfo) => {
20
15
  let updatedInfo = libdragonInfo;
21
16
  const imageName = libdragonInfo.options.DOCKER_IMAGE;
22
17
  // If an image is provided, attempt to install
23
- if (imageName && skipUpdate !== true) {
18
+ if (imageName) {
24
19
  log(
25
20
  chalk.yellow(
26
21
  'Using `install` action to update the docker image is deprecated. Use the `update` action instead.'
27
22
  )
28
23
  );
29
- updatedInfo = await updateAndStart(libdragonInfo);
24
+ updatedInfo = await syncImageAndStart(libdragonInfo);
30
25
  } else {
31
26
  // Make sure existing one is running
32
27
  updatedInfo = {
@@ -41,9 +36,10 @@ const install = async (libdragonInfo, skipUpdate) => {
41
36
  return updatedInfo;
42
37
  };
43
38
 
44
- module.exports = {
39
+ module.exports = /** @type {const} */ ({
45
40
  name: 'install',
46
41
  fn: install,
42
+ forwardsRestParams: false,
47
43
  usage: {
48
44
  name: 'install',
49
45
  summary: 'Vendor libdragon as is.',
@@ -51,4 +47,4 @@ module.exports = {
51
47
 
52
48
  Must be run in an initialized libdragon project. This can be useful to recover from a half-baked container.`,
53
49
  },
54
- };
50
+ });
@@ -1,5 +1,8 @@
1
1
  const { fn: exec } = require('./exec');
2
2
 
3
+ /**
4
+ * @param {import('../project-info').LibdragonInfo} info
5
+ */
3
6
  const make = async (info) => {
4
7
  return await exec({
5
8
  ...info,
@@ -10,7 +13,7 @@ const make = async (info) => {
10
13
  });
11
14
  };
12
15
 
13
- module.exports = {
16
+ module.exports = /** @type {const} */ ({
14
17
  name: 'make',
15
18
  fn: make,
16
19
  forwardsRestParams: true,
@@ -21,4 +24,4 @@ module.exports = {
21
24
 
22
25
  Must be run in an initialized libdragon project. This action is a shortcut to the \`exec\` action under the hood.`,
23
26
  },
24
- };
27
+ });
@@ -27,7 +27,10 @@ async function findNPMRoot() {
27
27
  }
28
28
  }
29
29
 
30
- // Install other NPM dependencies if this is an NPM project
30
+ /**
31
+ * Install other NPM dependencies if this is an NPM project
32
+ * @param {import('../project-info').LibdragonInfo} libdragonInfo
33
+ */
31
34
  const installNPMDependencies = async (libdragonInfo) => {
32
35
  const npmRoot = await findNPMRoot();
33
36
  if (npmRoot) {
@@ -55,7 +58,7 @@ const installNPMDependencies = async (libdragonInfo) => {
55
58
  return new Promise((resolve, reject) => {
56
59
  fsClassic.access(
57
60
  path.join(paths[0], 'Makefile'),
58
- fsClassic.F_OK,
61
+ fsClassic.constants.F_OK,
59
62
  async (e) => {
60
63
  if (e) {
61
64
  // File does not exist - skip
@@ -110,6 +113,9 @@ const installNPMDependencies = async (libdragonInfo) => {
110
113
  }
111
114
  };
112
115
 
116
+ /**
117
+ * @param {string[]} params
118
+ */
113
119
  function runNPM(params) {
114
120
  return spawnProcess(
115
121
  /^win/.test(process.platform) ? 'npm.cmd' : 'npm',
@@ -11,11 +11,11 @@ const {
11
11
 
12
12
  /**
13
13
  * Create a new container
14
+ * @param {import('../project-info').LibdragonInfo} libdragonInfo
14
15
  */
15
16
  const initContainer = async (libdragonInfo) => {
16
17
  let newId;
17
18
  try {
18
- // Create a new container
19
19
  log('Creating new container...');
20
20
  newId = (
21
21
  await spawnProcess('docker', [
@@ -34,19 +34,20 @@ const initContainer = async (libdragonInfo) => {
34
34
  ])
35
35
  ).trim();
36
36
 
37
- const newInfo = {
38
- ...libdragonInfo,
39
- containerId: newId,
40
- };
41
-
42
37
  // chown the installation folder once on init
43
38
  const { uid, gid } = libdragonInfo.userInfo;
44
- await dockerExec(newInfo, [
45
- 'chown',
46
- '-R',
47
- `${uid >= 0 ? uid : ''}:${gid >= 0 ? gid : ''}`,
48
- '/n64_toolchain',
49
- ]);
39
+ await dockerExec(
40
+ {
41
+ ...libdragonInfo,
42
+ containerId: newId,
43
+ },
44
+ [
45
+ 'chown',
46
+ '-R',
47
+ `${uid >= 0 ? uid : ''}:${gid >= 0 ? gid : ''}`,
48
+ '/n64_toolchain',
49
+ ]
50
+ );
50
51
  } catch (e) {
51
52
  // Dispose the invalid container, clean and exit
52
53
  await destroyContainer({
@@ -74,6 +75,9 @@ const initContainer = async (libdragonInfo) => {
74
75
  return newId;
75
76
  };
76
77
 
78
+ /**
79
+ * @param {import('../project-info').LibdragonInfo} libdragonInfo
80
+ */
77
81
  const start = async (libdragonInfo) => {
78
82
  const running =
79
83
  libdragonInfo.containerId &&
@@ -98,14 +102,18 @@ const start = async (libdragonInfo) => {
98
102
  return id;
99
103
  };
100
104
 
101
- module.exports = {
105
+ module.exports = /** @type {const} */ ({
102
106
  name: 'start',
107
+ /**
108
+ * @param {import('../project-info').LibdragonInfo} libdragonInfo
109
+ */
103
110
  fn: async (libdragonInfo) => {
104
111
  const containerId = await start(libdragonInfo);
105
112
  print(containerId);
106
113
  return { ...libdragonInfo, containerId };
107
114
  },
108
115
  start,
116
+ forwardsRestParams: false,
109
117
  usage: {
110
118
  name: 'start',
111
119
  summary: 'Start the container for current project.',
@@ -113,4 +121,4 @@ module.exports = {
113
121
 
114
122
  Must be run in an initialized libdragon project.`,
115
123
  },
116
- };
124
+ });
@@ -2,6 +2,9 @@ const { spawnProcess } = require('../helpers');
2
2
 
3
3
  const { checkContainerRunning } = require('./utils');
4
4
 
5
+ /**
6
+ * @param {import('../project-info').LibdragonInfo} libdragonInfo
7
+ */
5
8
  const stop = async (libdragonInfo) => {
6
9
  const running =
7
10
  libdragonInfo.containerId &&
@@ -14,9 +17,10 @@ const stop = async (libdragonInfo) => {
14
17
  return libdragonInfo;
15
18
  };
16
19
 
17
- module.exports = {
20
+ module.exports = /** @type {const} */ ({
18
21
  name: 'stop',
19
22
  fn: stop,
23
+ forwardsRestParams: false,
20
24
  usage: {
21
25
  name: 'stop',
22
26
  summary: 'Stop the container for current project.',
@@ -24,4 +28,4 @@ module.exports = {
24
28
 
25
29
  Must be run in an initialized libdragon project.`,
26
30
  },
27
- };
31
+ });
@@ -2,7 +2,10 @@ const { log } = require('../helpers');
2
2
  const { updateImage, destroyContainer } = require('./utils');
3
3
  const { start } = require('./start');
4
4
 
5
- async function updateAndStart(libdragonInfo) {
5
+ /**
6
+ * @param {import('../project-info').LibdragonInfo} libdragonInfo
7
+ */
8
+ async function syncImageAndStart(libdragonInfo) {
6
9
  const oldImageName = libdragonInfo.imageName;
7
10
  const imageName = libdragonInfo.options.DOCKER_IMAGE ?? oldImageName;
8
11
  // If an image is provided, always attempt to install it
@@ -29,5 +32,5 @@ async function updateAndStart(libdragonInfo) {
29
32
  }
30
33
 
31
34
  module.exports = {
32
- updateAndStart,
35
+ syncImageAndStart,
33
36
  };
@@ -1,26 +1,28 @@
1
1
  const { log } = require('../helpers');
2
2
  const { LIBDRAGON_GIT, LIBDRAGON_BRANCH } = require('../constants');
3
- const { runGitMaybeHost } = require('./utils');
4
- const { fn: install } = require('./install');
5
- const { updateAndStart } = require('./update-and-start');
3
+ const { runGitMaybeHost, installDependencies } = require('./utils');
4
+ const { syncImageAndStart } = require('./update-and-start');
6
5
 
6
+ /**
7
+ * @param {import('../project-info').LibdragonInfo} info
8
+ */
7
9
  const update = async (info) => {
8
- const newInfo = await updateAndStart(info);
10
+ info = await syncImageAndStart(info);
9
11
 
10
- if (newInfo.vendorStrategy !== 'manual') {
11
- log(`Updating ${newInfo.vendorStrategy}...`);
12
+ if (info.vendorStrategy !== 'manual') {
13
+ log(`Updating ${info.vendorStrategy}...`);
12
14
  }
13
15
 
14
- if (newInfo.vendorStrategy === 'submodule') {
15
- await runGitMaybeHost(newInfo, [
16
+ if (info.vendorStrategy === 'submodule') {
17
+ await runGitMaybeHost(info, [
16
18
  'submodule',
17
19
  'update',
18
20
  '--remote',
19
21
  '--merge',
20
- newInfo.vendorDirectory,
22
+ info.vendorDirectory,
21
23
  ]);
22
- } else if (newInfo.vendorStrategy === 'subtree') {
23
- await runGitMaybeHost(newInfo, [
24
+ } else if (info.vendorStrategy === 'subtree') {
25
+ await runGitMaybeHost(info, [
24
26
  'subtree',
25
27
  'pull',
26
28
  '--prefix',
@@ -31,14 +33,13 @@ const update = async (info) => {
31
33
  ]);
32
34
  }
33
35
 
34
- // The second parameter forces it to skip the image update step as we already
35
- // do that above.
36
- return await install(newInfo, true);
36
+ await installDependencies(info);
37
37
  };
38
38
 
39
- module.exports = {
39
+ module.exports = /** @type {const} */ ({
40
40
  name: 'update',
41
41
  fn: update,
42
+ forwardsRestParams: false,
42
43
  usage: {
43
44
  name: 'update',
44
45
  summary: 'Update libdragon and do an install.',
@@ -47,4 +48,4 @@ module.exports = {
47
48
  Must be run in an initialized libdragon project.`,
48
49
  group: ['docker'],
49
50
  },
50
- };
51
+ });