libdragon 11.4.4 → 12.0.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,9 +6,7 @@ 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) (`>= 27.2.0`) installed on your system.
10
-
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.
9
+ You should have [docker](https://www.docker.com/products/docker-desktop) (`>= 27.2.0`) && [git](https://git-scm.com/downloads) installed on your system.
12
10
 
13
11
  ## Installation
14
12
 
@@ -65,7 +63,7 @@ Download the [pre-built executable](https://github.com/anacierdem/libdragon-dock
65
63
 
66
64
  ### via NPM
67
65
 
68
- Install [node.js](https://nodejs.org/en/download/) (`>= 18`) and install `libdragon` as a global NPM package;
66
+ Install [node.js](https://nodejs.org/en/download/) (`>= 22`) and install `libdragon` as a global NPM package;
69
67
 
70
68
  ```bash
71
69
  npm install -g libdragon
@@ -291,50 +289,6 @@ To create your own dev container backed project, you can use the contents of the
291
289
  - It will prepare the container and open it in the editor.
292
290
  </details>
293
291
 
294
- ## Dependency management
295
-
296
- > [!WARNING]
297
- > This is an experimental feature.
298
-
299
- ### As an NPM dependency
300
-
301
- 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;
302
-
303
- ```json
304
- "scripts": {
305
- "prepare": "libdragon init"
306
- "build": "libdragon make",
307
- "clean": "libdragon make clean"
308
- }
309
- ```
310
-
311
- See [here](https://github.com/anacierdem/ed64-example) for a full example.
312
-
313
- ### Developing a dependency
314
-
315
- 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.
316
-
317
- For example this `package.json` in the dependent project;
318
-
319
- ```json
320
- {
321
- "name": "libdragonDependentProject",
322
- "version": "1.0.0",
323
- "description": "...",
324
- "scripts": {
325
- "build": "libdragon make",
326
- "clean": "libdragon make clean",
327
- "prepare": "libdragon init"
328
- },
329
- "dependencies": {
330
- "libdragon": <version>,
331
- "ed64": <version>
332
- }
333
- }
334
- ```
335
-
336
- 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.
337
-
338
292
  ## Funding
339
293
 
340
294
  If this tool helped you, consider supporting its development by sponsoring it!
package/index.js CHANGED
@@ -33,7 +33,7 @@ const { readProjectInfo, writeProjectInfo } = require('./modules/project-info');
33
33
  // This is overridden when building for SEA. When running from local or NPM,
34
34
  // the package.json version is used by the version action. esbuild will give
35
35
  // a warning for this assignment, but it works as expected.
36
- globalThis.VERSION = "";
36
+ globalThis.VERSION = '';
37
37
 
38
38
  parseParameters(process.argv)
39
39
  .then(readProjectInfo)
@@ -10,7 +10,7 @@ const {
10
10
  installDependencies,
11
11
  initGitAndCacheContainerId,
12
12
  updateImage,
13
- runGitMaybeHost,
13
+ runGit,
14
14
  destroyContainer,
15
15
  ensureGit,
16
16
  } = require('../utils');
@@ -61,15 +61,11 @@ const autoDetect = async (info) => {
61
61
 
62
62
  if (
63
63
  vendorTargetExists &&
64
- (await runGitMaybeHost(
65
- info,
66
- ['submodule', 'status', info.vendorDirectory],
67
- {
68
- inheritStdin: false,
69
- inheritStdout: false,
70
- inheritStderr: false,
71
- }
72
- ).catch((e) => {
64
+ (await runGit(info, ['submodule', 'status', info.vendorDirectory], {
65
+ inheritStdin: false,
66
+ inheritStdout: false,
67
+ inheritStderr: false,
68
+ }).catch((e) => {
73
69
  if (!(e instanceof CommandError)) {
74
70
  throw e;
75
71
  }
@@ -80,7 +76,7 @@ const autoDetect = async (info) => {
80
76
  }
81
77
 
82
78
  if (vendorTargetExists) {
83
- const gitLogs = await runGitMaybeHost(info, ['log'], {
79
+ const gitLogs = await runGit(info, ['log'], {
84
80
  inheritStdin: false,
85
81
  inheritStdout: false,
86
82
  inheritStderr: false,
@@ -161,7 +157,7 @@ const autoVendor = async (info) => {
161
157
 
162
158
  if (info.vendorStrategy === 'submodule') {
163
159
  try {
164
- await runGitMaybeHost(info, [
160
+ await runGit(info, [
165
161
  'submodule',
166
162
  'add',
167
163
  '--force',
@@ -188,7 +184,7 @@ const autoVendor = async (info) => {
188
184
  if (info.vendorStrategy === 'subtree') {
189
185
  // Create a commit if it does not exist. This is required for subtree.
190
186
  try {
191
- await runGitMaybeHost(info, ['rev-parse', 'HEAD']);
187
+ await runGit(info, ['rev-parse', 'HEAD']);
192
188
  } catch (e) {
193
189
  if (!(e instanceof CommandError)) throw e;
194
190
 
@@ -197,16 +193,16 @@ const autoVendor = async (info) => {
197
193
  // git on the host machine.
198
194
  // TODO: this is probably creating an unnecessary commit for someone who
199
195
  // just created a git repo and knows what they are doing.
200
- await runGitMaybeHost(info, [
196
+ await runGit(info, [
201
197
  'commit',
202
198
  '--allow-empty',
203
199
  '-n',
204
200
  '-m',
205
- 'Initial commit.',
201
+ '"Initial commit."',
206
202
  ]);
207
203
  }
208
204
 
209
- await runGitMaybeHost(info, [
205
+ await runGit(info, [
210
206
  'subtree',
211
207
  'add',
212
208
  '--prefix',
@@ -321,7 +317,7 @@ async function init(info) {
321
317
 
322
318
  if ((await autoDetect(info)) === 'submodule') {
323
319
  try {
324
- const existingBranchName = await runGitMaybeHost(
320
+ const existingBranchName = await runGit(
325
321
  info,
326
322
  [
327
323
  '-C',
@@ -1,7 +1,7 @@
1
1
  const { log, assert } = require('../helpers');
2
2
  const { LIBDRAGON_GIT } = require('../constants');
3
3
  const {
4
- runGitMaybeHost,
4
+ runGit,
5
5
  installDependencies,
6
6
  updateImage,
7
7
  destroyContainer,
@@ -55,7 +55,7 @@ const update = async (info) => {
55
55
  }
56
56
 
57
57
  if (info.vendorStrategy === 'submodule') {
58
- await runGitMaybeHost(info, [
58
+ await runGit(info, [
59
59
  'submodule',
60
60
  'update',
61
61
  '--remote',
@@ -63,7 +63,7 @@ const update = async (info) => {
63
63
  info.vendorDirectory,
64
64
  ]);
65
65
  } else if (info.vendorStrategy === 'subtree') {
66
- await runGitMaybeHost(info, [
66
+ await runGit(info, [
67
67
  'subtree',
68
68
  'pull',
69
69
  '--prefix',
@@ -124,11 +124,12 @@ async function dirExists(path) {
124
124
  * }} SpawnOptions
125
125
  */
126
126
 
127
- // A simple Promise wrapper for child_process.spawn. Return the err/out streams
128
- // from the process by default. Specify inheritStdout / inheritStderr to disable
129
- // this and inherit the parent process's stream, passing through the TTY if any.
130
127
  /**
131
- *
128
+ * A simple Promise wrapper for child_process.spawn. Return the err/out streams
129
+ * from the process by default. Specify inheritStdout / inheritStderr to disable
130
+ * this and inherit the parent process's stream, passing through the TTY if any.
131
+ * Runs everything in a shell, so be careful with user input. By default, we get
132
+ * the input from user but this is the whole idea of most of the logic here.
132
133
  * @param {string} cmd
133
134
  * @param {string[]} params
134
135
  * @param {SpawnOptions} options
@@ -183,6 +184,11 @@ function spawnProcess(
183
184
  enableOutTTY ? 'inherit' : 'pipe',
184
185
  enableErrorTTY ? 'inherit' : 'pipe',
185
186
  ],
187
+ env: {
188
+ // Prevent the annoying docker "What's next?" message. It messes up everything.
189
+ DOCKER_CLI_HINTS: 'false',
190
+ },
191
+ shell: true,
186
192
  ...spawnOptions,
187
193
  });
188
194
 
@@ -348,17 +354,7 @@ const dockerExec = /** @type {DockerExec} */ (
348
354
  libdragonInfo.containerId,
349
355
  ...finalCmdWithParams,
350
356
  ],
351
- {
352
- ...options,
353
- spawnOptions: {
354
- env: {
355
- // Prevent the annoyin docker "What's next?" message. It messes up everything.
356
- DOCKER_CLI_HINTS: 'false',
357
- ...options?.spawnOptions?.env,
358
- },
359
- ...options?.spawnOptions,
360
- },
361
- }
357
+ options
362
358
  );
363
359
  }
364
360
  );
@@ -1,20 +1,6 @@
1
1
  const path = require('path');
2
- const fsClassic = require('fs');
3
- const fs = require('fs/promises');
4
2
 
5
- // TODO: stop using lodash just for a simple uniq function
6
- const _ = require('lodash');
7
-
8
- const { dockerHostUserParams } = require('./docker-utils');
9
-
10
- const { CONTAINER_TARGET_PATH } = require('./constants');
11
- const {
12
- fileExists,
13
- toPosixPath,
14
- spawnProcess,
15
- dockerExec,
16
- ValidationError,
17
- } = require('./helpers');
3
+ const { fileExists, spawnProcess } = require('./helpers');
18
4
 
19
5
  async function findNPMRoot() {
20
6
  try {
@@ -29,115 +15,15 @@ async function findNPMRoot() {
29
15
  }
30
16
  }
31
17
 
32
- /**
33
- * Install other NPM dependencies if this is an NPM project
34
- * @param {import('./project-info').LibdragonInfo} libdragonInfo
35
- */
36
- const installNPMDependencies = async (libdragonInfo) => {
37
- const npmRoot = await findNPMRoot();
38
- if (npmRoot) {
39
- const packageJsonPath = path.join(npmRoot, 'package.json');
40
-
41
- const { dependencies, devDependencies } = JSON.parse(
42
- await fs.readFile(packageJsonPath, { encoding: 'utf8' })
43
- );
44
-
45
- const deps = await Promise.all(
46
- Object.keys({
47
- ...dependencies,
48
- ...devDependencies,
49
- })
50
- .filter((dep) => dep !== 'libdragon')
51
- .map(async (dep) => {
52
- const npmPath = await runNPM(['ls', dep, '--parseable=true']);
53
- return {
54
- name: dep,
55
- paths: _.uniq(npmPath.split('\n').filter((f) => f)),
56
- };
57
- })
58
- );
59
-
60
- await Promise.all(
61
- deps.map(({ name, paths }) => {
62
- return /** @type Promise<void> */ (
63
- new Promise((resolve, reject) => {
64
- fsClassic.access(
65
- path.join(paths[0], 'Makefile'),
66
- fsClassic.constants.F_OK,
67
- async (e) => {
68
- if (e) {
69
- // File does not exist - skip
70
- resolve();
71
- return;
72
- }
73
-
74
- if (paths.length > 1) {
75
- reject(
76
- new ValidationError(
77
- `Using same dependency with different versions is not supported! ${name}`
78
- )
79
- );
80
- return;
81
- }
82
-
83
- try {
84
- const relativePath = toPosixPath(
85
- path.relative(libdragonInfo.root, paths[0])
86
- );
87
- const containerPath = path.posix.join(
88
- CONTAINER_TARGET_PATH,
89
- relativePath
90
- );
91
- const makePath = path.posix.join(containerPath, 'Makefile');
92
-
93
- await dockerExec(
94
- libdragonInfo,
95
- [...dockerHostUserParams(libdragonInfo)],
96
- [
97
- '/bin/bash',
98
- '-c',
99
- '[ -f ' +
100
- makePath +
101
- ' ] && make -C ' +
102
- containerPath +
103
- ' && make -C ' +
104
- containerPath +
105
- ' install',
106
- ]
107
- );
108
-
109
- resolve();
110
- } catch (e) {
111
- reject(e);
112
- }
113
- }
114
- );
115
- })
116
- );
117
- })
118
- );
119
- }
120
- };
121
-
122
18
  /**
123
19
  * @param {string[]} params
124
20
  */
125
21
  function runNPM(params) {
126
22
  return spawnProcess(
127
23
  /^win/.test(process.platform) ? 'npm.cmd' : 'npm',
128
- params,
129
- {
130
- userCommand: false,
131
- inheritStdin: true,
132
- inheritStdout: false,
133
- inheritStderr: false,
134
- spawnOptions: {
135
- shell: true,
136
- },
137
- }
24
+ params
138
25
  );
139
26
  }
140
27
  module.exports = {
141
- installNPMDependencies,
142
28
  findNPMRoot,
143
29
  };
package/modules/utils.js CHANGED
@@ -10,13 +10,11 @@ const {
10
10
  dockerExec,
11
11
  dirExists,
12
12
  assert,
13
- CommandError,
14
13
  ValidationError,
15
14
  toNativePath,
16
15
  } = require('./helpers');
17
16
 
18
17
  const { dockerHostUserParams } = require('./docker-utils');
19
- const { installNPMDependencies } = require('./npm-utils');
20
18
 
21
19
  /**
22
20
  * @param {import('./project-info').LibdragonInfo} libdragonInfo
@@ -44,8 +42,6 @@ const installDependencies = async (libdragonInfo) => {
44
42
  ],
45
43
  ['/bin/bash', './build.sh']
46
44
  );
47
-
48
- await installNPMDependencies(libdragonInfo);
49
45
  };
50
46
 
51
47
  /**
@@ -119,8 +115,7 @@ const destroyContainer = async (libdragonInfo) => {
119
115
  };
120
116
 
121
117
  /**
122
- * Invokes host git with provided params. If host does not have git, falls back
123
- * to the docker git, with the nix user set to the user running libdragon.
118
+ * Invokes host git with provided params.
124
119
  */
125
120
 
126
121
  /**
@@ -129,43 +124,23 @@ const destroyContainer = async (libdragonInfo) => {
129
124
  * @param {string[]} params
130
125
  * @param {import('./helpers').SpawnOptions} options
131
126
  */
132
- async function runGitMaybeHost(libdragonInfo, params, options = {}) {
127
+ async function runGit(libdragonInfo, params, options = {}) {
133
128
  assert(
134
129
  libdragonInfo.vendorStrategy !== 'manual',
135
130
  new Error('Should never run git if vendoring strategy is manual.')
136
131
  );
137
- try {
138
- const isWin = /^win/.test(process.platform);
139
-
140
- return await spawnProcess(
141
- 'git',
142
- ['-C', libdragonInfo.root, ...params],
143
- // Windows git is breaking the TTY somehow - disable TTY for now
144
- // We are not able to display progress for the initial clone b/c of this
145
- // Enable progress otherwise.
146
- isWin
147
- ? { inheritStdin: false, ...options }
148
- : { inheritStdout: true, inheritStderr: true, ...options }
149
- );
150
- } catch (e) {
151
- if (e instanceof CommandError) {
152
- throw e;
153
- }
154
-
155
- assert(
156
- !process.env.DOCKER_CONTAINER,
157
- new Error('[runGitMaybeHost] Native git should exist in a container.')
158
- );
159
-
160
- return await dockerExec(
161
- libdragonInfo,
162
- // Use the host user when initializing git as we will need access
163
- [...dockerHostUserParams(libdragonInfo)],
164
- ['git', ...params],
165
- // Let's enable tty here to show the progress
166
- { inheritStdout: true, inheritStderr: true, ...options }
167
- );
168
- }
132
+ const isWin = /^win/.test(process.platform);
133
+
134
+ return await spawnProcess(
135
+ 'git',
136
+ ['-C', libdragonInfo.root, ...params],
137
+ // Windows git is breaking the TTY somehow - disable TTY for now
138
+ // We are not able to display progress for the initial clone b/c of this
139
+ // Enable progress otherwise.
140
+ isWin
141
+ ? { inheritStdin: false, ...options }
142
+ : { inheritStdout: true, inheritStderr: true, ...options }
143
+ );
169
144
  }
170
145
 
171
146
  /**
@@ -267,7 +242,7 @@ async function initGitAndCacheContainerId(libdragonInfo) {
267
242
  */
268
243
  async function ensureGit(info) {
269
244
  const gitRoot = (
270
- await runGitMaybeHost(info, ['rev-parse', '--show-toplevel'], {
245
+ await runGit(info, ['rev-parse', '--show-toplevel'], {
271
246
  inheritStdin: false,
272
247
  inheritStdout: false,
273
248
  inheritStderr: false,
@@ -283,7 +258,7 @@ async function ensureGit(info) {
283
258
  // where there is a git working tree higher in the host filesystem, which
284
259
  // the container does not have access to.
285
260
  if (!gitRoot) {
286
- await runGitMaybeHost(info, ['init']);
261
+ await runGit(info, ['init']);
287
262
  }
288
263
  }
289
264
 
@@ -294,6 +269,6 @@ module.exports = {
294
269
  checkContainerRunning,
295
270
  checkContainerAndClean,
296
271
  initGitAndCacheContainerId,
297
- runGitMaybeHost,
272
+ runGit,
298
273
  ensureGit,
299
274
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libdragon",
3
- "version": "11.4.4",
3
+ "version": "12.0.0",
4
4
  "description": "This is a docker wrapper for libdragon",
5
5
  "main": "index.js",
6
6
  "engines": {
@@ -41,7 +41,6 @@
41
41
  "dependencies": {
42
42
  "chalk": "^4.1.0",
43
43
  "command-line-usage": "^6.1.1",
44
- "lodash": "^4.17.20",
45
44
  "zx": "^8.1.8"
46
45
  },
47
46
  "devDependencies": {
@@ -49,11 +48,9 @@
49
48
  "@semantic-release/exec": "^6.0.3",
50
49
  "@semantic-release/git": "^10.0.1",
51
50
  "@types/command-line-usage": "^5.0.2",
52
- "@types/lodash": "^4.14.182",
53
51
  "commitizen": "^4.2.4",
54
52
  "cz-conventional-changelog": "^3.3.0",
55
53
  "esbuild": "^0.20.0",
56
- "ed64": "^2.0.4",
57
54
  "eslint": "^9.11.0",
58
55
  "jest": "^29.5.0",
59
56
  "postject": "^1.0.0-alpha.6",