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.
- package/CHANGELOG.md +75 -0
- package/index.js +17 -119
- package/modules/actions/destroy.js +34 -0
- package/modules/actions/disasm.js +121 -0
- package/modules/actions/docker-utils.js +8 -0
- package/modules/actions/exec.js +97 -39
- package/modules/actions/help.js +29 -84
- package/modules/actions/index.js +8 -17
- package/modules/actions/init.js +46 -41
- package/modules/actions/install.js +10 -4
- package/modules/actions/make.js +24 -0
- package/modules/actions/npm-utils.js +122 -0
- package/modules/actions/start.js +17 -15
- package/modules/actions/stop.js +9 -3
- package/modules/actions/update.js +13 -9
- package/modules/actions/utils.js +42 -162
- package/modules/actions/version.js +17 -0
- package/modules/helpers.js +117 -45
- package/modules/parameters.js +129 -0
- package/modules/project-info.js +62 -33
- package/package.json +1 -1
- package/skeleton/Makefile +8 -7
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const chalk = require('chalk').stderr;
|
|
2
|
+
|
|
3
|
+
const { log } = require('./helpers');
|
|
4
|
+
const actions = require('./actions');
|
|
5
|
+
const { fn: printUsage } = require('./actions/help');
|
|
6
|
+
const { STATUS_BAD_PARAM } = require('./constants');
|
|
7
|
+
const { globals } = require('./globals');
|
|
8
|
+
|
|
9
|
+
const parseParameters = async (argv) => {
|
|
10
|
+
const options = {
|
|
11
|
+
EXTRA_PARAMS: [],
|
|
12
|
+
CURRENT_ACTION: undefined,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
for (let i = 2; i < argv.length; i++) {
|
|
16
|
+
const val = argv[i];
|
|
17
|
+
|
|
18
|
+
if (['--verbose', '-v'].includes(val)) {
|
|
19
|
+
options.VERBOSE = true;
|
|
20
|
+
globals.verbose = true;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// TODO: we might move these to actions as well.
|
|
25
|
+
if (['--image', '-i'].includes(val)) {
|
|
26
|
+
options.DOCKER_IMAGE = argv[++i];
|
|
27
|
+
continue;
|
|
28
|
+
} else if (val.indexOf('--image=') === 0) {
|
|
29
|
+
options.DOCKER_IMAGE = val.split('=')[1];
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (['--directory', '-d'].includes(val)) {
|
|
34
|
+
options.VENDOR_DIR = argv[++i];
|
|
35
|
+
continue;
|
|
36
|
+
} else if (val.indexOf('--directory=') === 0) {
|
|
37
|
+
options.VENDOR_DIR = val.split('=')[1];
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (['--strategy', '-s'].includes(val)) {
|
|
42
|
+
options.VENDOR_STRAT = argv[++i];
|
|
43
|
+
continue;
|
|
44
|
+
} else if (val.indexOf('--strategy=') === 0) {
|
|
45
|
+
options.VENDOR_STRAT = val.split('=')[1];
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (['--file', '-f'].includes(val)) {
|
|
50
|
+
options.FILE = argv[++i];
|
|
51
|
+
continue;
|
|
52
|
+
} else if (val.indexOf('--file=') === 0) {
|
|
53
|
+
options.FILE = val.split('=')[1];
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (val.indexOf('-') == 0) {
|
|
58
|
+
log(chalk.red(`Invalid flag \`${val}\``));
|
|
59
|
+
printUsage();
|
|
60
|
+
process.exit(STATUS_BAD_PARAM);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (options.CURRENT_ACTION) {
|
|
64
|
+
log(chalk.red(`Expected only a single action, found: \`${val}\``));
|
|
65
|
+
printUsage();
|
|
66
|
+
process.exit(STATUS_BAD_PARAM);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
options.CURRENT_ACTION = actions[val];
|
|
70
|
+
|
|
71
|
+
if (!options.CURRENT_ACTION) {
|
|
72
|
+
log(chalk.red(`Invalid action \`${val}\``));
|
|
73
|
+
printUsage();
|
|
74
|
+
process.exit(STATUS_BAD_PARAM);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options.CURRENT_ACTION.forwardsRestParams) {
|
|
78
|
+
options.EXTRA_PARAMS = argv.slice(i + 1);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!options.CURRENT_ACTION) {
|
|
84
|
+
log(chalk.red('No action provided'));
|
|
85
|
+
printUsage();
|
|
86
|
+
process.exit(STATUS_BAD_PARAM);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (
|
|
90
|
+
options.CURRENT_ACTION === actions.exec &&
|
|
91
|
+
options.EXTRA_PARAMS.length === 0
|
|
92
|
+
) {
|
|
93
|
+
log(chalk.red('You should provide a command to exec'));
|
|
94
|
+
printUsage(undefined, [options.CURRENT_ACTION.name]);
|
|
95
|
+
process.exit(STATUS_BAD_PARAM);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (
|
|
99
|
+
![actions.init, actions.install, actions.update].includes(
|
|
100
|
+
options.CURRENT_ACTION
|
|
101
|
+
) &&
|
|
102
|
+
options.DOCKER_IMAGE
|
|
103
|
+
) {
|
|
104
|
+
log(chalk.red('Invalid flag: image'));
|
|
105
|
+
printUsage(undefined, [options.CURRENT_ACTION.name]);
|
|
106
|
+
process.exit(STATUS_BAD_PARAM);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (
|
|
110
|
+
options.VENDOR_STRAT &&
|
|
111
|
+
!['submodule', 'subtree', 'manual'].includes(options.VENDOR_STRAT)
|
|
112
|
+
) {
|
|
113
|
+
log(chalk.red(`Invalid strategy \`${options.VENDOR_STRAT}\``));
|
|
114
|
+
printUsage();
|
|
115
|
+
process.exit(STATUS_BAD_PARAM);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (![actions.disasm].includes(options.CURRENT_ACTION) && options.FILE) {
|
|
119
|
+
log(chalk.red('Invalid flag: file'));
|
|
120
|
+
printUsage(undefined, [options.CURRENT_ACTION.name]);
|
|
121
|
+
process.exit(STATUS_BAD_PARAM);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return { options };
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
module.exports = {
|
|
128
|
+
parseParameters,
|
|
129
|
+
};
|
package/modules/project-info.js
CHANGED
|
@@ -4,11 +4,11 @@ const fs = require('fs/promises');
|
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
6
|
checkContainerAndClean,
|
|
7
|
-
|
|
8
|
-
runGitMaybeHost,
|
|
9
|
-
tryCacheContainerId,
|
|
7
|
+
initGitAndCacheContainerId,
|
|
10
8
|
} = require('./actions/utils');
|
|
11
9
|
|
|
10
|
+
const { findNPMRoot } = require('./actions/npm-utils');
|
|
11
|
+
|
|
12
12
|
const {
|
|
13
13
|
LIBDRAGON_PROJECT_MANIFEST,
|
|
14
14
|
CONFIG_FILE,
|
|
@@ -20,7 +20,17 @@ const {
|
|
|
20
20
|
CONTAINER_TARGET_PATH,
|
|
21
21
|
} = require('./constants');
|
|
22
22
|
|
|
23
|
-
const {
|
|
23
|
+
const {
|
|
24
|
+
fileExists,
|
|
25
|
+
log,
|
|
26
|
+
spawnProcess,
|
|
27
|
+
toPosixPath,
|
|
28
|
+
assert,
|
|
29
|
+
ParameterError,
|
|
30
|
+
} = require('./helpers');
|
|
31
|
+
|
|
32
|
+
const initAction = require('./actions/init');
|
|
33
|
+
const destroyAction = require('./actions/destroy');
|
|
24
34
|
|
|
25
35
|
async function findContainerId(libdragonInfo) {
|
|
26
36
|
const idFile = path.join(libdragonInfo.root, '.git', CACHED_CONTAINER_FILE);
|
|
@@ -42,7 +52,13 @@ async function findContainerId(libdragonInfo) {
|
|
|
42
52
|
])
|
|
43
53
|
)
|
|
44
54
|
.split('\n')
|
|
45
|
-
|
|
55
|
+
// docker seem to save paths with posix separators but make sure we look for
|
|
56
|
+
// both, just in case
|
|
57
|
+
.filter(
|
|
58
|
+
(s) =>
|
|
59
|
+
s.includes(`${toPosixPath(libdragonInfo.root)} `) ||
|
|
60
|
+
s.includes(`${libdragonInfo.root} `)
|
|
61
|
+
);
|
|
46
62
|
|
|
47
63
|
if (candidates.length > 0) {
|
|
48
64
|
const str = candidates[0];
|
|
@@ -50,11 +66,12 @@ async function findContainerId(libdragonInfo) {
|
|
|
50
66
|
const idIndex = str.indexOf(shortId);
|
|
51
67
|
const longId = str.slice(idIndex, idIndex + 64);
|
|
52
68
|
if (longId.length === 64) {
|
|
53
|
-
|
|
54
|
-
if
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
69
|
+
const newInfo = { ...libdragonInfo, containerId: longId };
|
|
70
|
+
// This shouldn't happen but if the user somehow deleted the .git folder
|
|
71
|
+
// (we don't have the container id file at this point) we can recover the
|
|
72
|
+
// project. `git init` is safe anyways and it is not executed if strategy
|
|
73
|
+
// is `manual`
|
|
74
|
+
await initGitAndCacheContainerId(newInfo);
|
|
58
75
|
return longId;
|
|
59
76
|
}
|
|
60
77
|
}
|
|
@@ -83,20 +100,42 @@ async function findGitRoot() {
|
|
|
83
100
|
}
|
|
84
101
|
}
|
|
85
102
|
|
|
86
|
-
async function readProjectInfo() {
|
|
103
|
+
async function readProjectInfo(info) {
|
|
104
|
+
// No need to do anything here if the action does not depend on the project
|
|
105
|
+
// The only exception is the init and destroy actions, which do not need an
|
|
106
|
+
// existing project but readProjectInfo must always run to analyze the situation
|
|
107
|
+
const forceReadProjectInfo = [initAction, destroyAction].includes(
|
|
108
|
+
info.options.CURRENT_ACTION
|
|
109
|
+
);
|
|
110
|
+
if (
|
|
111
|
+
info.options.CURRENT_ACTION.mustHaveProject === false &&
|
|
112
|
+
!forceReadProjectInfo
|
|
113
|
+
) {
|
|
114
|
+
return info;
|
|
115
|
+
}
|
|
116
|
+
|
|
87
117
|
const projectRoot = await findLibdragonRoot();
|
|
88
118
|
|
|
89
|
-
|
|
119
|
+
if (!projectRoot && !forceReadProjectInfo) {
|
|
120
|
+
throw new ParameterError(
|
|
121
|
+
'This is not a libdragon project. Initialize with `libdragon init` first.',
|
|
122
|
+
info.options.CURRENT_ACTION.name
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
info = {
|
|
127
|
+
...info,
|
|
90
128
|
root: projectRoot ?? (await findNPMRoot()) ?? (await findGitRoot()),
|
|
91
129
|
userInfo: os.userInfo(),
|
|
92
130
|
|
|
93
131
|
// Use this to discriminate if there is a project when the command is run
|
|
132
|
+
// Only used for the init action ATM, and it is not ideal to have this here
|
|
94
133
|
haveProjectConfig: !!projectRoot,
|
|
95
134
|
|
|
96
135
|
// Set the defaults immediately, these should be present at all times even
|
|
97
136
|
// if we are migrating from the old config because they did not exist before
|
|
98
137
|
imageName: DOCKER_HUB_IMAGE,
|
|
99
|
-
vendorDirectory: path.join('.', LIBDRAGON_SUBMODULE),
|
|
138
|
+
vendorDirectory: toPosixPath(path.join('.', LIBDRAGON_SUBMODULE)),
|
|
100
139
|
vendorStrategy: DEFAULT_STRATEGY,
|
|
101
140
|
};
|
|
102
141
|
|
|
@@ -158,30 +197,16 @@ async function readProjectInfo() {
|
|
|
158
197
|
log(`Active vendor directory: ${info.vendorDirectory}`, true);
|
|
159
198
|
log(`Active vendor strategy: ${info.vendorStrategy}`, true);
|
|
160
199
|
|
|
161
|
-
// Cache the latest image name
|
|
162
|
-
setProjectInfoToSave(info);
|
|
163
200
|
return info;
|
|
164
201
|
}
|
|
165
202
|
|
|
166
|
-
let projectInfoToWrite = {};
|
|
167
203
|
/**
|
|
168
|
-
*
|
|
169
|
-
* changing the existing values. When the process exists successfully these will
|
|
170
|
-
* get written to the configuration file. Echoes back the given info.
|
|
171
|
-
* @param info This is only the base info without action properties like showStatus
|
|
204
|
+
* @param info This is only the base info without options
|
|
172
205
|
* fn and command line options
|
|
173
206
|
*/
|
|
174
|
-
function
|
|
175
|
-
projectInfoToWrite = { ...projectInfoToWrite, ...info };
|
|
176
|
-
return info;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* @param info This is only the base info without action properties like showStatus
|
|
181
|
-
* fn and command line options
|
|
182
|
-
*/
|
|
183
|
-
async function writeProjectInfo(info = projectInfoToWrite) {
|
|
207
|
+
async function writeProjectInfo(info) {
|
|
184
208
|
// Do not log anything here as it may litter the output being always run on exit
|
|
209
|
+
if (!info) return;
|
|
185
210
|
|
|
186
211
|
const projectPath = path.join(info.root, LIBDRAGON_PROJECT_MANIFEST);
|
|
187
212
|
|
|
@@ -195,13 +220,17 @@ async function writeProjectInfo(info = projectInfoToWrite) {
|
|
|
195
220
|
await fs.mkdir(projectPath);
|
|
196
221
|
}
|
|
197
222
|
|
|
223
|
+
assert(
|
|
224
|
+
toPosixPath(info.vendorDirectory) === info.vendorDirectory,
|
|
225
|
+
new Error('vendorDirectory should always be in posix format')
|
|
226
|
+
);
|
|
227
|
+
|
|
198
228
|
await fs.writeFile(
|
|
199
229
|
path.join(projectPath, CONFIG_FILE),
|
|
200
230
|
JSON.stringify(
|
|
201
231
|
{
|
|
202
232
|
imageName: info.imageName,
|
|
203
|
-
|
|
204
|
-
vendorDirectory: toPosixPath(info.vendorDirectory),
|
|
233
|
+
vendorDirectory: info.vendorDirectory,
|
|
205
234
|
vendorStrategy: info.vendorStrategy,
|
|
206
235
|
},
|
|
207
236
|
null,
|
|
@@ -211,4 +240,4 @@ async function writeProjectInfo(info = projectInfoToWrite) {
|
|
|
211
240
|
log(`Configuration file updated`, true);
|
|
212
241
|
}
|
|
213
242
|
|
|
214
|
-
module.exports = { readProjectInfo, writeProjectInfo
|
|
243
|
+
module.exports = { readProjectInfo, writeProjectInfo };
|
package/package.json
CHANGED
package/skeleton/Makefile
CHANGED
|
@@ -3,16 +3,17 @@ SOURCE_DIR=src
|
|
|
3
3
|
BUILD_DIR=build
|
|
4
4
|
include $(N64_INST)/include/n64.mk
|
|
5
5
|
|
|
6
|
-
src=main.c
|
|
7
|
-
|
|
8
6
|
all: hello.z64
|
|
7
|
+
.PHONY: all
|
|
8
|
+
|
|
9
|
+
OBJS = $(BUILD_DIR)/main.o
|
|
9
10
|
|
|
10
11
|
hello.z64: N64_ROM_TITLE="Hello World"
|
|
11
|
-
$(BUILD_DIR)/hello.elf: $(src:%.c=$(BUILD_DIR)/%.o)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
rm -f $(BUILD_DIR)/* hello.z64
|
|
13
|
+
$(BUILD_DIR)/hello.elf: $(OBJS)
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
clean:
|
|
16
|
+
rm -f $(BUILD_DIR)/* *.z64
|
|
17
|
+
.PHONY: clean
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
-include $(wildcard $(BUILD_DIR)/*.d)
|