libdragon 11.1.3 → 11.3.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.
package/README.md CHANGED
@@ -6,30 +6,34 @@ This is a wrapper for a docker container to make managing the libdragon toolchai
6
6
 
7
7
  ## Prerequisites
8
8
 
9
- You should have [docker](https://www.docker.com/products/docker-desktop) (`>= 24`) installed on your system.
9
+ You should have [docker](https://www.docker.com/products/docker-desktop) (`>= 27.2.0`) installed on your system.
10
10
 
11
11
  `git` is not strictly required to use the tool. Still, it is highly recommended to have git on your host machine as it will be used instead of the one in the container.
12
12
 
13
13
  ## Installation
14
14
 
15
- This is primarily a node.js script which is also packaged as an executable. You have two options:
15
+ This is primarily a node.js script which is also packaged as an executable. You have a few options:
16
16
 
17
- ### pre-built
17
+ ### installer
18
18
 
19
- Download the [pre-built executable](https://github.com/anacierdem/libdragon-docker/releases/latest) for your system and put it somewhere on your PATH. It is discouraged to put it in your project folder.
19
+ Download the [windows installer](https://github.com/anacierdem/libdragon-docker/releases/latest) and run it. This option is currently only available on Windows.
20
20
 
21
21
  <details>
22
- <summary>Windows instructions</summary>
22
+ <summary>Detailed instructions</summary>
23
23
 
24
24
  - Download the Windows installer and run it
25
- - It can show a "Windows protected your PC" warning. In that case click "More info" and "Run anyway".
25
+ - It can show a "Windows protected your PC" warning. Click "More info" and "Run anyway".
26
26
  - You should now be able to use the `libdragon` on a command line or PowerShell.
27
27
  - To update it with a new version, download a newer installer and repeat the steps above.
28
28
 
29
29
  </details>
30
30
 
31
+ ### pre-built executable
32
+
33
+ Download the [pre-built executable](https://github.com/anacierdem/libdragon-docker/releases/latest) for your system and put it somewhere on your PATH. It is discouraged to put it in your project folder.
34
+
31
35
  <details>
32
- <summary>Windows instructions (manual)</summary>
36
+ <summary>Windows instructions</summary>
33
37
 
34
38
  - Download the Windows executable and copy it to `C:\bin`
35
39
  - Press `Windows + R` key combination and then enter `rundll32 sysdm.cpl,EditEnvironmentVariables`
@@ -101,15 +105,19 @@ Run `libdragon help [action]` for more details on individual actions.
101
105
 
102
106
  ## Recipes
103
107
 
104
- ### Using a different branch of libdragon
108
+ ### Using a different libdragon branch
105
109
 
106
- Initialize your project as usual:
110
+ Use the `--branch` flag to set up a custom libdragon branch when initializing your project:
107
111
 
108
112
  ```bash
109
- libdragon init
113
+ libdragon init --branch unstable
110
114
  ```
111
115
 
112
- Then switch the submodule to the desired branch:
116
+ This will use the `unstable` toolchain and code.
117
+
118
+ ### Switching to a different branch of libdragon
119
+
120
+ On an already initialized project, switch the submodule to the desired branch:
113
121
 
114
122
  ```bash
115
123
  git -C ./libdragon checkout opengl
@@ -157,7 +165,7 @@ To be able to share your project with the library change, you just commit your c
157
165
 
158
166
  ## Working on this repository
159
167
 
160
- After cloning this repository on a system with node.js (`>= 18`) & docker (`>= 24`), in this repository's root do;
168
+ After cloning this repository on a system with node.js (`>= 18`) & docker (`>= 27.2.0`), in this repository's root do;
161
169
 
162
170
  ```bash
163
171
  npm install
@@ -200,7 +208,9 @@ Similarly to run the `clean` recipe, run;
200
208
  npm run libdragon -- make clean
201
209
  ```
202
210
 
203
- Keep in mind that `--` is necessary for actual arguments when using npm scripts.
211
+ > [!IMPORTANT]
212
+ > Keep in mind that `--` is necessary for actual arguments when using npm scripts.
213
+
204
214
 
205
215
  To update the submodule and re-build everything;
206
216
 
@@ -214,7 +224,8 @@ The root `bench` recipe is for building the code in root `src` folder. This is a
214
224
 
215
225
  There are also vscode launch configurations to quickly build the examples, tests and the bench. If you have the `N64_EMU` environment variable set pointing at your favourite emulator ([ares](https://ares-emu.net/) is highly recommended), the launch configurations ending in `(emu)` will kick your emulator with the selected example/code. You can also just hit F5 to launch the selected configuration.
216
226
 
217
- This repository also uses [ed64](https://github.com/anacierdem/ed64), so you can use the launch configurations without `(emu)` to run the code if you have an everdrive plugged in and your active configuration will just boot up.
227
+ > [!NOTE]
228
+ > This repository also uses [ed64](https://github.com/anacierdem/ed64), so you can use the launch configurations without `(emu)` to run the code if you have an everdrive plugged in and your active configuration will just boot up.
218
229
 
219
230
  You can clean everything with the `clean` recipe/task (open the command palette and choose `Run Task -> clean`).
220
231
 
@@ -278,7 +289,12 @@ To create your own dev container backed project, you can use the contents of the
278
289
  - It will prepare the container and open it in the editor.
279
290
  </details>
280
291
 
281
- ## As an NPM dependency
292
+ ## Dependency management
293
+
294
+ > [!WARNING]
295
+ > This is an experimental feature.
296
+
297
+ ### As an NPM dependency
282
298
 
283
299
  You can install libdragon as an NPM dependency by `npm install libdragon --save` in order to use docker in your N64 projects. A `libdragon` command similar to global intallation is provided that can be used in your NPM scripts as follows;
284
300
 
@@ -292,7 +308,7 @@ You can install libdragon as an NPM dependency by `npm install libdragon --save`
292
308
 
293
309
  See [here](https://github.com/anacierdem/ed64-example) for a full example.
294
310
 
295
- ## Developing a dependency
311
+ ### Developing a dependency
296
312
 
297
313
  You can make an NPM package that a `libdragon` project can depend on. Just include a `Makefile` on the repository root with a default recipe and an `install` recipe. On the depending project, after installing libdragon and the dependency with `npm install <dep name> --save`, one can install libdragon dependencies on the current docker container using `package.json` scripts.
298
314
 
@@ -317,8 +333,6 @@ For example this `package.json` in the dependent project;
317
333
 
318
334
  will init the container for this project and run `make && make install` for `ed64` upon running `npm install`. To develop a dependency [this](https://github.com/anacierdem/libdragon-dependency) is a good starting point.
319
335
 
320
- This is an experimental dependency management.
321
-
322
336
  ## Funding
323
337
 
324
338
  If this tool helped you, consider supporting its development by sponsoring it!
@@ -1,5 +1,9 @@
1
+ /// <reference path="../../globals.d.ts" />
2
+
1
3
  const fs = require('fs/promises');
4
+ const _fs = require('fs');
2
5
  const path = require('path');
6
+ const sea = require('node:sea');
3
7
 
4
8
  const chalk = require('chalk').stderr;
5
9
 
@@ -16,19 +20,33 @@ const {
16
20
  const {
17
21
  LIBDRAGON_PROJECT_MANIFEST,
18
22
  LIBDRAGON_SUBMODULE,
19
- LIBDRAGON_BRANCH,
20
23
  LIBDRAGON_GIT,
21
24
  } = require('../constants');
22
25
  const {
23
26
  log,
24
- copyDirContents,
25
27
  CommandError,
26
28
  ParameterError,
27
29
  ValidationError,
28
30
  toPosixPath,
29
31
  toNativePath,
32
+ getImageName,
30
33
  } = require('../helpers');
31
34
 
35
+ // TODO: use https://nodejs.org/api/single-executable-applications.html#seagetassetkey-encoding &&
36
+ // https://nodejs.org/api/single-executable-applications.html#assets instead
37
+ const main_c = sea.isSea()
38
+ ? // @ts-ignore-next-line
39
+ /** @type {string} */ (require('../../skeleton/src/main.c'))
40
+ : _fs.readFileSync(path.join(__dirname, '../../skeleton/src/main.c'), 'utf8');
41
+
42
+ const makefile = sea.isSea()
43
+ ? // @ts-ignore-next-line
44
+ /** @type {string} */ require('../../skeleton/Makefile.mk')
45
+ : _fs.readFileSync(
46
+ path.join(__dirname, '../../skeleton/Makefile.mk'),
47
+ 'utf8'
48
+ );
49
+
32
50
  /**
33
51
  * @param {import('../project-info').LibdragonInfo} info
34
52
  * @returns {Promise<"submodule" | "subtree" | undefined>}
@@ -45,11 +63,15 @@ const autoDetect = async (info) => {
45
63
 
46
64
  if (
47
65
  vendorTargetExists &&
48
- (await runGitMaybeHost(info, [
49
- 'submodule',
50
- 'status',
51
- info.vendorDirectory,
52
- ]).catch((e) => {
66
+ (await runGitMaybeHost(
67
+ info,
68
+ ['submodule', 'status', info.vendorDirectory],
69
+ {
70
+ inheritStdin: false,
71
+ inheritStdout: false,
72
+ inheritStderr: false,
73
+ }
74
+ ).catch((e) => {
53
75
  if (!(e instanceof CommandError)) {
54
76
  throw e;
55
77
  }
@@ -148,7 +170,7 @@ const autoVendor = async (info) => {
148
170
  '--name',
149
171
  LIBDRAGON_SUBMODULE,
150
172
  '--branch',
151
- LIBDRAGON_BRANCH,
173
+ info.activeBranchName,
152
174
  LIBDRAGON_GIT,
153
175
  info.vendorDirectory,
154
176
  ]);
@@ -156,6 +178,9 @@ const autoVendor = async (info) => {
156
178
  if (!(e instanceof CommandError)) throw e;
157
179
  // We speculate this is caused by the user, so replace it with a more useful error message.
158
180
  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}`;
181
+ if (e.out) {
182
+ e.message += `\n${e.out}`;
183
+ }
159
184
  throw e;
160
185
  }
161
186
 
@@ -189,7 +214,7 @@ const autoVendor = async (info) => {
189
214
  '--prefix',
190
215
  path.relative(info.root, info.vendorDirectory),
191
216
  LIBDRAGON_GIT,
192
- LIBDRAGON_BRANCH,
217
+ info.activeBranchName,
193
218
  '--squash',
194
219
  ]);
195
220
  return info;
@@ -198,6 +223,47 @@ const autoVendor = async (info) => {
198
223
  return info;
199
224
  };
200
225
 
226
+ /**
227
+ * @param {import('../project-info').LibdragonInfo} info
228
+ */
229
+ async function copyFiles(info) {
230
+ // TODO: make use of VFS, this is far from ideal
231
+ const srcPath = path.join(info.root, 'src');
232
+
233
+ const srcStat = await fs.stat(srcPath).catch((e) => {
234
+ if (e.code !== 'ENOENT') throw e;
235
+ return null;
236
+ });
237
+
238
+ if (srcStat && !srcStat.isDirectory()) {
239
+ log(`${srcPath} is not a directory, skipping.`);
240
+ return;
241
+ }
242
+
243
+ if (!srcStat) {
244
+ log(`Creating a directory at ${srcPath}.`, true);
245
+ await fs.mkdir(srcPath);
246
+ }
247
+
248
+ const makefilePath = path.join(info.root, 'Makefile');
249
+ await fs
250
+ .writeFile(makefilePath, makefile, {
251
+ flag: 'wx',
252
+ })
253
+ .catch(() => {
254
+ log(`${makefilePath} already exists, skipping.`);
255
+ });
256
+
257
+ const mainPath = path.join(info.root, 'src', 'main.c');
258
+ await fs
259
+ .writeFile(mainPath, main_c, {
260
+ flag: 'wx',
261
+ })
262
+ .catch(() => {
263
+ log(`${mainPath} already exists, skipping.`);
264
+ });
265
+ }
266
+
201
267
  /**
202
268
  * Initialize a new libdragon project in current working directory
203
269
  * Also downloads the image
@@ -252,11 +318,44 @@ async function init(info) {
252
318
  }
253
319
 
254
320
  if (!process.env.DOCKER_CONTAINER) {
255
- // We don't have a config yet, this is a fresh project, override with the
256
- // image flag if provided. Also see https://github.com/anacierdem/libdragon-docker/issues/66
321
+ let activeBranchName = info.options.BRANCH ?? info.activeBranchName;
322
+ let shouldOverrideBranch = !!info.options.BRANCH;
323
+
324
+ if ((await autoDetect(info)) === 'submodule') {
325
+ try {
326
+ const existingBranchName = await runGitMaybeHost(
327
+ info,
328
+ [
329
+ '-C',
330
+ path.relative(info.root, info.vendorDirectory),
331
+ 'rev-parse',
332
+ '--abbrev-ref',
333
+ 'HEAD',
334
+ ],
335
+ {
336
+ inheritStdin: false,
337
+ inheritStdout: false,
338
+ inheritStderr: false,
339
+ }
340
+ );
341
+ activeBranchName = existingBranchName.trim();
342
+ shouldOverrideBranch = !!activeBranchName;
343
+ } catch {
344
+ // If we can't get the branch name, we will use the default
345
+ }
346
+ }
347
+
257
348
  info = {
258
349
  ...info,
259
- imageName: info.options.DOCKER_IMAGE ?? info.imageName,
350
+ activeBranchName,
351
+ // We don't have a config yet, this is a fresh project, override with the
352
+ // image flag if provided. Also see https://github.com/anacierdem/libdragon-docker/issues/66
353
+ // Next, if `--branch` flag is provided use that or the one recovered from
354
+ // the submodule.
355
+ imageName:
356
+ (info.options.DOCKER_IMAGE ??
357
+ (shouldOverrideBranch && getImageName(activeBranchName))) ||
358
+ info.imageName,
260
359
  };
261
360
  // Download image and start it
262
361
  await updateImage(info, info.imageName);
@@ -273,13 +372,8 @@ async function init(info) {
273
372
  info = await autoVendor(info);
274
373
 
275
374
  log(`Preparing project files...`);
276
- const skeletonFolder = path.join(__dirname, '../../skeleton');
277
375
 
278
- await Promise.all([
279
- installDependencies(info),
280
- // node copy functions does not work with pkg
281
- copyDirContents(skeletonFolder, info.root),
282
- ]);
376
+ await Promise.all([installDependencies(info), copyFiles(info)]);
283
377
 
284
378
  log(chalk.green(`libdragon ready at \`${info.root}\`.`));
285
379
  return info;
@@ -299,6 +393,16 @@ module.exports = /** @type {const} */ ({
299
393
  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 without any parameter, it will act like \`start\` thus can be used to revive an existing project without modifying it.
300
394
 
301
395
  If you have an existing project with an already vendored submodule or subtree libdragon copy, \`init\` will automatically detect it at the provided \`--directory\`.`,
302
- group: ['docker', 'vendoring'],
396
+ group: ['docker', 'vendoring', '_none'],
397
+
398
+ optionList: [
399
+ {
400
+ name: 'branch',
401
+ description:
402
+ 'Provide a different branch to initialize libdragon. It will also change the toolchain docker image to be based on the given branch but `--image` will have precedence. Defaults to `trunk` & `latest` image.',
403
+ alias: 'b',
404
+ typeLabel: '<branch>',
405
+ },
406
+ ],
303
407
  },
304
408
  });
@@ -1,5 +1,5 @@
1
1
  const { log, assert } = require('../helpers');
2
- const { LIBDRAGON_GIT, LIBDRAGON_BRANCH } = require('../constants');
2
+ const { LIBDRAGON_GIT } = require('../constants');
3
3
  const {
4
4
  runGitMaybeHost,
5
5
  installDependencies,
@@ -69,7 +69,7 @@ const update = async (info) => {
69
69
  '--prefix',
70
70
  info.vendorDirectory,
71
71
  LIBDRAGON_GIT,
72
- LIBDRAGON_BRANCH,
72
+ info.activeBranchName,
73
73
  '--squash',
74
74
  ]);
75
75
  }
@@ -1,5 +1,5 @@
1
1
  module.exports = /** @type {const} */ ({
2
- DOCKER_HUB_IMAGE: 'ghcr.io/dragonminded/libdragon:latest',
2
+ DOCKER_HUB_IMAGE: 'ghcr.io/dragonminded/libdragon',
3
3
  LIBDRAGON_GIT: 'https://github.com/DragonMinded/libdragon',
4
4
  LIBDRAGON_BRANCH: 'trunk',
5
5
  LIBDRAGON_SUBMODULE: 'libdragon',
@@ -1,11 +1,14 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs/promises');
3
- const fsClassic = require('fs');
4
3
  const chalk = require('chalk').stderr;
5
4
  const { spawn } = require('child_process');
6
5
 
7
6
  const { globals } = require('./globals');
8
- const { NO_PROJECT_ACTIONS } = require('./constants');
7
+ const {
8
+ NO_PROJECT_ACTIONS,
9
+ LIBDRAGON_BRANCH,
10
+ DOCKER_HUB_IMAGE,
11
+ } = require('./constants');
9
12
 
10
13
  /**
11
14
  * A structure to keep additional error information
@@ -117,7 +120,7 @@ async function dirExists(path) {
117
120
  * inheritStdout?: boolean,
118
121
  * inheritStderr?: boolean,
119
122
  * spawnOptions?: import('child_process').SpawnOptions,
120
- * stdin?: fsClassic.ReadStream,
123
+ * stdin?: import('fs').ReadStream,
121
124
  * }} SpawnOptions
122
125
  */
123
126
 
@@ -347,60 +350,6 @@ const dockerExec = /** @type {DockerExec} */ (
347
350
  }
348
351
  );
349
352
 
350
- /**
351
- * Recursively copies directories and files
352
- * @param {string} src
353
- * @param {string} dst
354
- */
355
- async function copyDirContents(src, dst) {
356
- log(`Copying from ${src} to ${dst}`, true);
357
-
358
- const dstStat = await fs.stat(dst).catch((e) => {
359
- if (e.code !== 'ENOENT') throw e;
360
- return null;
361
- });
362
-
363
- if (dstStat && !dstStat.isDirectory()) {
364
- log(`${dst} is not a directory, skipping.`);
365
- return;
366
- }
367
-
368
- if (!dstStat) {
369
- log(`Creating a directory at ${dst}.`, true);
370
- await fs.mkdir(dst);
371
- }
372
-
373
- const files = await fs.readdir(src);
374
- return Promise.all(
375
- files.map(async (name) => {
376
- const source = path.join(src, name);
377
- const dest = path.join(dst, name);
378
- // promise version does not work on snapshot filesystem
379
- // Also see https://github.com/vercel/pkg/issues/1561
380
- const stats = await new Promise((res, rej) =>
381
- fsClassic.stat(source, (err, stats) => {
382
- if (err) return rej(err);
383
- res(stats);
384
- })
385
- );
386
- if (stats.isDirectory()) {
387
- await copyDirContents(source, dest);
388
- } else if (stats.isFile()) {
389
- const content = await fs.readFile(source);
390
- try {
391
- log(`Writing to ${dest}`, true);
392
- await fs.writeFile(dest, content, {
393
- flag: 'wx',
394
- });
395
- } catch (e) {
396
- log(`${dest} already exists, skipping.`);
397
- return;
398
- }
399
- }
400
- })
401
- );
402
- }
403
-
404
353
  /**
405
354
  * @param {string} p
406
355
  */
@@ -442,8 +391,10 @@ function print(text) {
442
391
  */
443
392
  function log(text, verboseOnly = false) {
444
393
  if (!verboseOnly) {
394
+ // New default color for console.err is red
395
+ // Also see https://github.com/nodejs/node/issues/53661
445
396
  // eslint-disable-next-line no-console
446
- console.error(text);
397
+ console.error(chalk.white(text));
447
398
  return;
448
399
  }
449
400
  if (globals.verbose) {
@@ -454,8 +405,8 @@ function log(text, verboseOnly = false) {
454
405
  }
455
406
 
456
407
  /**
457
- * @param {import('./project-info').CLIInfo | import('./project-info').LibdragonInfo} info
458
- * @returns {info is import('./project-info').LibdragonInfo}
408
+ * @param {import('./project-info').CLIInfo} info
409
+ * @returns {info is import('./project-info').ProjectInfo}
459
410
  */
460
411
  function isProjectAction(info) {
461
412
  return !NO_PROJECT_ACTIONS.includes(
@@ -465,6 +416,18 @@ function isProjectAction(info) {
465
416
  );
466
417
  }
467
418
 
419
+ /**
420
+ * @param {string} branchName
421
+ * @returns {string}
422
+ */
423
+ function getImageName(branchName) {
424
+ return (
425
+ DOCKER_HUB_IMAGE +
426
+ ':' +
427
+ (branchName === LIBDRAGON_BRANCH ? 'latest' : branchName)
428
+ );
429
+ }
430
+
468
431
  module.exports = {
469
432
  spawnProcess,
470
433
  toPosixPath,
@@ -475,9 +438,9 @@ module.exports = {
475
438
  assert,
476
439
  fileExists,
477
440
  dirExists,
478
- copyDirContents,
479
441
  CommandError,
480
442
  ParameterError,
481
443
  ValidationError,
482
444
  isProjectAction,
445
+ getImageName,
483
446
  };
@@ -1,6 +1,8 @@
1
1
  const path = require('path');
2
2
  const fsClassic = require('fs');
3
+ const fs = require('fs/promises');
3
4
 
5
+ // TODO: stop using lodash just for a simple uniq function
4
6
  const _ = require('lodash');
5
7
 
6
8
  const { dockerHostUserParams } = require('./docker-utils');
@@ -36,7 +38,9 @@ const installNPMDependencies = async (libdragonInfo) => {
36
38
  if (npmRoot) {
37
39
  const packageJsonPath = path.join(npmRoot, 'package.json');
38
40
 
39
- const { dependencies, devDependencies } = require(packageJsonPath);
41
+ const { dependencies, devDependencies } = JSON.parse(
42
+ await fs.readFile(packageJsonPath, { encoding: 'utf8' })
43
+ );
40
44
 
41
45
  const deps = await Promise.all(
42
46
  Object.keys({
@@ -121,7 +125,16 @@ const installNPMDependencies = async (libdragonInfo) => {
121
125
  function runNPM(params) {
122
126
  return spawnProcess(
123
127
  /^win/.test(process.platform) ? 'npm.cmd' : 'npm',
124
- params
128
+ params,
129
+ {
130
+ userCommand: false,
131
+ inheritStdin: true,
132
+ inheritStdout: false,
133
+ inheritStderr: false,
134
+ spawnOptions: {
135
+ shell: true,
136
+ },
137
+ }
125
138
  );
126
139
  }
127
140
  module.exports = {
@@ -19,6 +19,7 @@ const { globals } = require('./globals');
19
19
  * VENDOR_DIR?: string;
20
20
  * VENDOR_STRAT?: VendorStrategy;
21
21
  * FILE?: string;
22
+ * BRANCH?: string;
22
23
  * }} CommandlineOptions
23
24
  */
24
25
 
@@ -81,6 +82,14 @@ const parseParameters = async (argv) => {
81
82
  continue;
82
83
  }
83
84
 
85
+ if (['--branch', '-b'].includes(val)) {
86
+ options.BRANCH = argv[++i];
87
+ continue;
88
+ } else if (val.indexOf('--branch=') === 0) {
89
+ options.BRANCH = val.split('=')[1];
90
+ continue;
91
+ }
92
+
84
93
  if (val.indexOf('-') == 0) {
85
94
  log(chalk.red(`Invalid flag \`${val}\``));
86
95
  process.exit(STATUS_BAD_PARAM);
@@ -126,7 +135,7 @@ const parseParameters = async (argv) => {
126
135
  ) &&
127
136
  options.DOCKER_IMAGE
128
137
  ) {
129
- log(chalk.red('Invalid flag: image'));
138
+ log(chalk.red('Invalid flag: --image'));
130
139
  process.exit(STATUS_BAD_PARAM);
131
140
  }
132
141
 
@@ -138,7 +147,19 @@ const parseParameters = async (argv) => {
138
147
  ) &&
139
148
  options.FILE
140
149
  ) {
141
- log(chalk.red('Invalid flag: file'));
150
+ log(chalk.red('Invalid flag: --file'));
151
+ process.exit(STATUS_BAD_PARAM);
152
+ }
153
+
154
+ if (
155
+ !(
156
+ /** @type {typeof actions[keyof actions][]} */ ([actions.init]).includes(
157
+ options.CURRENT_ACTION
158
+ )
159
+ ) &&
160
+ options.BRANCH
161
+ ) {
162
+ log(chalk.red('Invalid flag: --branch'));
142
163
  process.exit(STATUS_BAD_PARAM);
143
164
  }
144
165
 
@@ -12,11 +12,11 @@ const { findNPMRoot } = require('./npm-utils');
12
12
  const {
13
13
  LIBDRAGON_PROJECT_MANIFEST,
14
14
  CONFIG_FILE,
15
- DOCKER_HUB_IMAGE,
16
15
  DEFAULT_STRATEGY,
17
16
  LIBDRAGON_SUBMODULE,
18
17
  CACHED_CONTAINER_FILE,
19
18
  CONTAINER_TARGET_PATH,
19
+ LIBDRAGON_BRANCH,
20
20
  } = require('./constants');
21
21
 
22
22
  const {
@@ -27,6 +27,7 @@ const {
27
27
  assert,
28
28
  ParameterError,
29
29
  isProjectAction,
30
+ getImageName,
30
31
  } = require('./helpers');
31
32
 
32
33
  /**
@@ -49,13 +50,18 @@ const {
49
50
  *
50
51
  * @typedef { {
51
52
  * options: ActionsWithProjectOptions
53
+ * } } ProjectInfo
54
+ *
55
+ * @typedef { {
56
+ * options: ActionsWithProjectOptions
52
57
  * root: string;
53
58
  * userInfo: os.UserInfo<string>;
54
59
  * haveProjectConfig: boolean;
55
60
  * imageName: string;
56
61
  * vendorDirectory: string;
57
62
  * vendorStrategy: import('./parameters').VendorStrategy;
58
- * containerId?: string
63
+ * containerId?: string;
64
+ * activeBranchName: string;
59
65
  * } } LibdragonInfo
60
66
  */
61
67
 
@@ -189,6 +195,13 @@ const readProjectInfo = async function (optionInfo) {
189
195
 
190
196
  vendorDirectory: toPosixPath(path.join('.', LIBDRAGON_SUBMODULE)),
191
197
  vendorStrategy: DEFAULT_STRATEGY,
198
+
199
+ activeBranchName: LIBDRAGON_BRANCH,
200
+
201
+ // This is invalid at this point, but is overridden below from config file
202
+ // or container if it doesn't exist in the file. If a flag is provided, it
203
+ // will be overridden later.
204
+ imageName: '',
192
205
  };
193
206
 
194
207
  log(`Project root: ${info.root}`, true);
@@ -231,15 +244,16 @@ const readProjectInfo = async function (optionInfo) {
231
244
 
232
245
  // For imageName, flag has the highest priority followed by the one read from
233
246
  // the file and then if there is any matching container, name is read from it.
234
- // As last option fallback to default value.
247
+ // Next if `--branch` flag and as last option fallback to default value.
235
248
  // This represents the current value, so the flag should be processed later.
236
249
  // If we were to update it here, it would be impossible to know the change
237
250
  // with how we structure the code right now.
238
- info.imageName = info.imageName ?? DOCKER_HUB_IMAGE;
251
+ info.imageName = info.imageName || getImageName(info.activeBranchName);
239
252
 
240
253
  log(`Active image name: ${info.imageName}`, true);
241
254
  log(`Active vendor directory: ${info.vendorDirectory}`, true);
242
255
  log(`Active vendor strategy: ${info.vendorStrategy}`, true);
256
+ log(`Active branch: ${info.activeBranchName}`, true);
243
257
 
244
258
  return info;
245
259
  };
package/modules/utils.js CHANGED
@@ -137,29 +137,9 @@ async function runGitMaybeHost(libdragonInfo, params, options = {}) {
137
137
  try {
138
138
  const isWin = /^win/.test(process.platform);
139
139
 
140
- // When using host's git the actual top level can be higher in the tree
141
- // rather that at the root of the project. We need to find it to run some
142
- // git operations like subtree.
143
- const gitRoot = (
144
- await spawnProcess(
145
- 'git',
146
- ['-C', libdragonInfo.root, 'rev-parse', '--show-toplevel'],
147
- { inheritStdin: false }
148
- ).catch(() => {
149
- // Either this is not a git repo or the host does not have git
150
- // We might also screw something up but we can live with it for now
151
- return '';
152
- })
153
- ).trim();
154
-
155
140
  return await spawnProcess(
156
141
  'git',
157
- [
158
- '-C',
159
- libdragonInfo.root,
160
- ...(gitRoot ? ['--git-dir', `${gitRoot}/.git`] : []),
161
- ...params,
162
- ],
142
+ ['-C', libdragonInfo.root, ...params],
163
143
  // Windows git is breaking the TTY somehow - disable TTY for now
164
144
  // We are not able to display progress for the initial clone b/c of this
165
145
  // Enable progress otherwise.
@@ -287,7 +267,11 @@ async function initGitAndCacheContainerId(libdragonInfo) {
287
267
  */
288
268
  async function ensureGit(info) {
289
269
  const gitRoot = (
290
- await runGitMaybeHost(info, ['rev-parse', '--show-toplevel']).catch(() => {
270
+ await runGitMaybeHost(info, ['rev-parse', '--show-toplevel'], {
271
+ inheritStdin: false,
272
+ inheritStdout: false,
273
+ inheritStderr: false,
274
+ }).catch(() => {
291
275
  // Probably host does not have git, can ignore
292
276
  return '';
293
277
  })
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "libdragon",
3
- "version": "11.1.3",
3
+ "version": "11.3.0",
4
4
  "description": "This is a docker wrapper for libdragon",
5
5
  "main": "index.js",
6
6
  "engines": {
7
- "node": ">=18",
8
- "npm": ">=8"
7
+ "node": ">=22",
8
+ "npm": ">=10"
9
9
  },
10
10
  "bin": {
11
11
  "libdragon": "./index.js"
@@ -16,11 +16,11 @@
16
16
  "libdragon": "node index.js",
17
17
  "start": "node index.js start",
18
18
  "stop": "node index.js stop",
19
- "pack": "pkg ./",
20
- "format": "prettier **/*.js --write",
21
- "format-check": "prettier **/*.js --check",
22
- "lint": "eslint --fix **/*.js",
23
- "lint-check": "eslint **/*.js",
19
+ "pack": "node pack.mjs",
20
+ "format": "prettier **/*.js **/*.mjs **/*.cjs --write",
21
+ "format-check": "prettier **/*.js **/*.mjs **/*.cjs --check",
22
+ "lint": "eslint --fix modules/**/*.js *.js *.mjs *.cjs",
23
+ "lint-check": "eslint modules/**/*.js *.js *.mjs *.cjs",
24
24
  "tsc": "tsc"
25
25
  },
26
26
  "repository": {
@@ -40,7 +40,8 @@
40
40
  "dependencies": {
41
41
  "chalk": "^4.1.0",
42
42
  "command-line-usage": "^6.1.1",
43
- "lodash": "^4.17.20"
43
+ "lodash": "^4.17.20",
44
+ "zx": "^8.1.8"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@semantic-release/changelog": "^6.0.1",
@@ -50,23 +51,19 @@
50
51
  "@types/lodash": "^4.14.182",
51
52
  "commitizen": "^4.2.4",
52
53
  "cz-conventional-changelog": "^3.3.0",
54
+ "esbuild": "^0.20.0",
53
55
  "ed64": "^2.0.4",
54
- "eslint": "^7.32.0",
56
+ "eslint": "^9.11.0",
55
57
  "jest": "^29.5.0",
56
- "pkg": "^5.5.2",
58
+ "postject": "^1.0.0-alpha.6",
57
59
  "prettier": "^2.4.0",
60
+ "ref-napi": "^3.0.3",
58
61
  "semantic-release": "^24.0.0",
59
- "typescript": "^4.7.4"
62
+ "typescript": "^4.7.4",
63
+ "zx": "^7.2.2"
60
64
  },
61
- "pkg": {
62
- "targets": [
63
- "node14-win-x64",
64
- "node14-linux-x64",
65
- "node14-macos-x64"
66
- ],
67
- "assets": [
68
- "skeleton/**"
69
- ]
65
+ "overrides": {
66
+ "minimist": "1.2.6"
70
67
  },
71
68
  "release": {
72
69
  "plugins": [
@@ -0,0 +1,4 @@
1
+ declare module './src/main.c' {
2
+ type tmp = string;
3
+ export = tmp;
4
+ }
File without changes