libdragon 10.4.0 → 10.5.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 +59 -1
- package/index.js +31 -5
- package/modules/actions/clean.js +35 -0
- package/modules/actions/disasm.js +116 -0
- package/modules/actions/docker-utils.js +8 -0
- package/modules/actions/exec.js +18 -3
- package/modules/actions/help.js +21 -72
- package/modules/actions/index.js +6 -32
- package/modules/actions/init.js +59 -36
- package/modules/actions/install.js +35 -31
- package/modules/actions/make.js +19 -0
- package/modules/actions/npm-utils.js +122 -0
- package/modules/actions/start.js +16 -8
- package/modules/actions/stop.js +29 -0
- package/modules/actions/update-and-start.js +33 -0
- package/modules/actions/update.js +16 -12
- package/modules/actions/utils.js +23 -120
- package/modules/actions/version.js +17 -0
- package/modules/constants.js +1 -0
- package/modules/helpers.js +17 -1
- package/modules/project-info.js +43 -64
- package/package.json +1 -1
- package/skeleton/Makefile +8 -7
package/modules/actions/init.js
CHANGED
|
@@ -4,7 +4,7 @@ const path = require('path');
|
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
|
|
6
6
|
const { fn: install } = require('./install');
|
|
7
|
-
const {
|
|
7
|
+
const { start } = require('./start');
|
|
8
8
|
const {
|
|
9
9
|
installDependencies,
|
|
10
10
|
tryCacheContainerId,
|
|
@@ -23,8 +23,10 @@ const {
|
|
|
23
23
|
copyDirContents,
|
|
24
24
|
CommandError,
|
|
25
25
|
ParameterError,
|
|
26
|
+
ValidationError,
|
|
27
|
+
toPosixPath,
|
|
28
|
+
toNativePath,
|
|
26
29
|
} = require('../helpers');
|
|
27
|
-
const { setProjectInfoToSave } = require('../project-info');
|
|
28
30
|
|
|
29
31
|
const autoVendor = async (libdragonInfo) => {
|
|
30
32
|
await runGitMaybeHost(libdragonInfo, ['init']);
|
|
@@ -81,55 +83,60 @@ const autoVendor = async (libdragonInfo) => {
|
|
|
81
83
|
async function init(libdragonInfo) {
|
|
82
84
|
log(`Initializing a libdragon project at ${libdragonInfo.root}`);
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
const files = await fs.readdir(libdragonInfo.root);
|
|
86
|
+
let newInfo = libdragonInfo;
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
)
|
|
88
|
+
// Validate manifest
|
|
89
|
+
const manifestPath = path.join(newInfo.root, LIBDRAGON_PROJECT_MANIFEST);
|
|
90
|
+
const manifestStats = await fs.stat(manifestPath).catch((e) => {
|
|
91
|
+
if (e.code !== 'ENOENT') throw e;
|
|
92
|
+
return false;
|
|
93
|
+
});
|
|
90
94
|
|
|
91
|
-
|
|
95
|
+
if (manifestStats && !manifestStats.isDirectory()) {
|
|
96
|
+
throw new ValidationError(
|
|
97
|
+
'There is already a `.libdragon` file and it is not a directory.'
|
|
98
|
+
);
|
|
99
|
+
}
|
|
92
100
|
|
|
93
101
|
// Validate vendoring strategy. Do not allow a switch after successful initialization
|
|
94
102
|
if (
|
|
95
|
-
|
|
103
|
+
newInfo.haveProjectConfig &&
|
|
96
104
|
newInfo.options.VENDOR_STRAT &&
|
|
97
105
|
newInfo.options.VENDOR_STRAT !== 'manual' &&
|
|
98
106
|
newInfo.vendorStrategy !== newInfo.options.VENDOR_STRAT
|
|
99
107
|
) {
|
|
100
|
-
throw new
|
|
108
|
+
throw new ParameterError(
|
|
101
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.`
|
|
102
110
|
);
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
// Update the strategy information for the project if the flag is provided
|
|
106
114
|
if (newInfo.options.VENDOR_STRAT) {
|
|
107
|
-
newInfo =
|
|
108
|
-
...newInfo,
|
|
109
|
-
vendorStrategy: newInfo.options.VENDOR_STRAT,
|
|
110
|
-
});
|
|
115
|
+
newInfo.vendorStrategy = newInfo.options.VENDOR_STRAT;
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
// Update the directory information for the project if the flag is provided
|
|
114
119
|
if (newInfo.options.VENDOR_DIR) {
|
|
120
|
+
const relativeVendorDir = path.relative(
|
|
121
|
+
libdragonInfo.root,
|
|
122
|
+
libdragonInfo.options.VENDOR_DIR
|
|
123
|
+
);
|
|
115
124
|
// Validate vendoring path
|
|
116
|
-
if (
|
|
125
|
+
if (relativeVendorDir.startsWith('..')) {
|
|
117
126
|
throw new ParameterError(
|
|
118
|
-
|
|
127
|
+
`\`--directory=${libdragonInfo.options.VENDOR_DIR}\` is outside the project directory.`
|
|
119
128
|
);
|
|
120
129
|
}
|
|
121
130
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
vendorDirectory: newInfo.options.VENDOR_DIR,
|
|
125
|
-
});
|
|
131
|
+
// Immeditately convert it to a posix and relative path
|
|
132
|
+
newInfo.vendorDirectory = toPosixPath(relativeVendorDir);
|
|
126
133
|
}
|
|
127
134
|
|
|
128
|
-
if (
|
|
135
|
+
if (newInfo.haveProjectConfig) {
|
|
129
136
|
log(
|
|
130
137
|
`${path.join(
|
|
131
138
|
newInfo.root,
|
|
132
|
-
|
|
139
|
+
LIBDRAGON_PROJECT_MANIFEST
|
|
133
140
|
)} exists. This is already a libdragon project, starting it...`
|
|
134
141
|
);
|
|
135
142
|
if (newInfo.options.DOCKER_IMAGE) {
|
|
@@ -137,31 +144,36 @@ async function init(libdragonInfo) {
|
|
|
137
144
|
`Not changing docker image. Use the install action if you want to override the image.`
|
|
138
145
|
);
|
|
139
146
|
}
|
|
140
|
-
|
|
141
|
-
return;
|
|
147
|
+
// TODO: we may make sure git and submodule is initialized here
|
|
148
|
+
return await install(newInfo);
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
newInfo.imageName
|
|
145
|
-
|
|
151
|
+
await updateImage(newInfo, newInfo.imageName);
|
|
152
|
+
|
|
146
153
|
// Download image and start it
|
|
147
|
-
const containerReadyPromise = start(newInfo).then((newId) => ({
|
|
154
|
+
const containerReadyPromise = start(newInfo, true).then((newId) => ({
|
|
148
155
|
...newInfo,
|
|
149
156
|
containerId: newId,
|
|
150
157
|
}));
|
|
151
158
|
|
|
152
159
|
let vendorAndGitReadyPromise = containerReadyPromise;
|
|
153
160
|
if (newInfo.vendorStrategy !== 'manual') {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
)
|
|
161
|
+
const vendorTarget = path.relative(
|
|
162
|
+
newInfo.root,
|
|
163
|
+
toNativePath(newInfo.vendorDirectory)
|
|
158
164
|
);
|
|
165
|
+
const [vendorTargetExists] = await Promise.all([
|
|
166
|
+
fs.stat(vendorTarget).catch((e) => {
|
|
167
|
+
if (e.code !== 'ENOENT') throw e;
|
|
168
|
+
return false;
|
|
169
|
+
}),
|
|
170
|
+
containerReadyPromise,
|
|
171
|
+
]);
|
|
159
172
|
|
|
160
|
-
if (
|
|
161
|
-
throw new
|
|
162
|
-
`${path.
|
|
163
|
-
|
|
164
|
-
libdragonFile
|
|
173
|
+
if (vendorTargetExists) {
|
|
174
|
+
throw new ValidationError(
|
|
175
|
+
`${path.resolve(
|
|
176
|
+
vendorTarget
|
|
165
177
|
)} already exists. That is the libdragon vendoring target, please remove and retry.`
|
|
166
178
|
);
|
|
167
179
|
}
|
|
@@ -181,10 +193,21 @@ async function init(libdragonInfo) {
|
|
|
181
193
|
]);
|
|
182
194
|
|
|
183
195
|
log(chalk.green(`libdragon ready at \`${newInfo.root}\`.`));
|
|
196
|
+
return newInfo;
|
|
184
197
|
}
|
|
185
198
|
|
|
186
199
|
module.exports = {
|
|
187
200
|
name: 'init',
|
|
188
201
|
fn: init,
|
|
189
202
|
showStatus: true,
|
|
203
|
+
usage: {
|
|
204
|
+
name: 'init',
|
|
205
|
+
summary: 'Create a libdragon project in the current directory.',
|
|
206
|
+
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.
|
|
207
|
+
|
|
208
|
+
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.
|
|
209
|
+
|
|
210
|
+
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.`,
|
|
211
|
+
group: ['docker', 'vendoring'],
|
|
212
|
+
},
|
|
190
213
|
};
|
|
@@ -1,52 +1,56 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
const { installDependencies, mustHaveProject } = require('./utils');
|
|
4
|
+
const { start } = require('./start');
|
|
5
|
+
const { updateAndStart } = require('./update-and-start');
|
|
1
6
|
const { log } = require('../helpers');
|
|
2
|
-
const {
|
|
3
|
-
destroyContainer,
|
|
4
|
-
installDependencies,
|
|
5
|
-
updateImage,
|
|
6
|
-
} = require('./utils');
|
|
7
|
-
const { fn: start } = require('./start');
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Updates the image if flag is provided and install vendors onto the container.
|
|
11
10
|
* We should probably remove the image installation responsibility from this
|
|
12
|
-
* action but it might be a breaking change.
|
|
13
|
-
* compatible with additional flags.
|
|
11
|
+
* action but it might be a breaking change.
|
|
14
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.
|
|
15
18
|
*/
|
|
16
|
-
const install = async (libdragonInfo) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
const install = async (libdragonInfo, skipUpdate) => {
|
|
20
|
+
await mustHaveProject(libdragonInfo);
|
|
21
|
+
let updatedInfo = libdragonInfo;
|
|
19
22
|
const imageName = libdragonInfo.options.DOCKER_IMAGE;
|
|
20
|
-
// If an image is provided,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
containerId = await start({
|
|
31
|
-
...libdragonInfo,
|
|
32
|
-
imageName,
|
|
33
|
-
});
|
|
23
|
+
// If an image is provided, attempt to install
|
|
24
|
+
if (imageName && skipUpdate !== true) {
|
|
25
|
+
log(
|
|
26
|
+
chalk.yellow(
|
|
27
|
+
'Using `install` action to update the docker image is deprecated. Use the `update` action instead.'
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
updatedInfo = await updateAndStart(libdragonInfo);
|
|
34
31
|
} else {
|
|
35
32
|
// Make sure existing one is running
|
|
36
|
-
|
|
33
|
+
updatedInfo = {
|
|
34
|
+
...updatedInfo,
|
|
35
|
+
containerId: await start(libdragonInfo),
|
|
36
|
+
};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
// Re-install vendors on new image
|
|
40
40
|
// TODO: skip this if unnecessary
|
|
41
|
-
await installDependencies(
|
|
42
|
-
|
|
43
|
-
imageName,
|
|
44
|
-
containerId,
|
|
45
|
-
});
|
|
41
|
+
await installDependencies(updatedInfo);
|
|
42
|
+
return updatedInfo;
|
|
46
43
|
};
|
|
47
44
|
|
|
48
45
|
module.exports = {
|
|
49
46
|
name: 'install',
|
|
50
47
|
fn: install,
|
|
51
48
|
showStatus: true,
|
|
49
|
+
usage: {
|
|
50
|
+
name: 'install',
|
|
51
|
+
summary: 'Vendor libdragon as is.',
|
|
52
|
+
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.
|
|
53
|
+
|
|
54
|
+
Must be run in an initialized libdragon project. This can be useful to recover from a half-baked container.`,
|
|
55
|
+
},
|
|
52
56
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const { fn: exec } = require('./exec');
|
|
2
|
+
|
|
3
|
+
const make = async (libdragonInfo, params) => {
|
|
4
|
+
return await exec(libdragonInfo, ['make', ...params]);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
name: 'make',
|
|
9
|
+
fn: make,
|
|
10
|
+
forwardsRestParams: true,
|
|
11
|
+
showStatus: true,
|
|
12
|
+
usage: {
|
|
13
|
+
name: 'make [params]',
|
|
14
|
+
summary: 'Run the libdragon build system in the current directory.',
|
|
15
|
+
description: `Runs the libdragon build system in the current directory. It will mirror your current working directory to the container.
|
|
16
|
+
|
|
17
|
+
Must be run in an initialized libdragon project. This action is a shortcut to the \`exec\` action under the hood.`,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
@@ -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
|
+
};
|
package/modules/actions/start.js
CHANGED
|
@@ -2,12 +2,12 @@ const chalk = require('chalk');
|
|
|
2
2
|
|
|
3
3
|
const { CONTAINER_TARGET_PATH } = require('../constants');
|
|
4
4
|
const { spawnProcess, log, dockerExec } = require('../helpers');
|
|
5
|
-
const { setProjectInfoToSave } = require('../project-info');
|
|
6
5
|
|
|
7
6
|
const {
|
|
8
7
|
checkContainerAndClean,
|
|
9
8
|
checkContainerRunning,
|
|
10
9
|
destroyContainer,
|
|
10
|
+
mustHaveProject,
|
|
11
11
|
} = require('./utils');
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -75,19 +75,17 @@ const initContainer = async (libdragonInfo) => {
|
|
|
75
75
|
chalk.green(`Successfully initialized docker container: ${name.trim()}`)
|
|
76
76
|
);
|
|
77
77
|
|
|
78
|
-
// Schedule an update to write image name
|
|
79
|
-
setProjectInfoToSave(libdragonInfo);
|
|
80
78
|
return newId;
|
|
81
79
|
};
|
|
82
80
|
|
|
83
|
-
const start = async (libdragonInfo) => {
|
|
81
|
+
const start = async (libdragonInfo, skipProjectCheck) => {
|
|
82
|
+
!skipProjectCheck && (await mustHaveProject(libdragonInfo));
|
|
84
83
|
const running =
|
|
85
84
|
libdragonInfo.containerId &&
|
|
86
85
|
(await checkContainerRunning(libdragonInfo.containerId));
|
|
87
86
|
|
|
88
87
|
if (running) {
|
|
89
88
|
log(`Container ${running} already running.`, true);
|
|
90
|
-
log(libdragonInfo.containerId);
|
|
91
89
|
return running;
|
|
92
90
|
}
|
|
93
91
|
|
|
@@ -96,19 +94,29 @@ const start = async (libdragonInfo) => {
|
|
|
96
94
|
if (!id) {
|
|
97
95
|
log(`Container does not exist, re-initializing...`, true);
|
|
98
96
|
id = await initContainer(libdragonInfo);
|
|
99
|
-
log(id);
|
|
100
97
|
return id;
|
|
101
98
|
}
|
|
102
99
|
|
|
103
100
|
log(`Starting container: ${id}`, true);
|
|
104
101
|
await spawnProcess('docker', ['container', 'start', id]);
|
|
105
102
|
|
|
106
|
-
log(id);
|
|
107
103
|
return id;
|
|
108
104
|
};
|
|
109
105
|
|
|
110
106
|
module.exports = {
|
|
111
107
|
name: 'start',
|
|
112
|
-
fn:
|
|
108
|
+
fn: async (libdragonInfo) => {
|
|
109
|
+
const containerId = await start(libdragonInfo);
|
|
110
|
+
log(containerId);
|
|
111
|
+
return { ...libdragonInfo, containerId };
|
|
112
|
+
},
|
|
113
|
+
start,
|
|
113
114
|
showStatus: false, // This will only print out the id
|
|
115
|
+
usage: {
|
|
116
|
+
name: 'start',
|
|
117
|
+
summary: 'Start the container for current project.',
|
|
118
|
+
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.
|
|
119
|
+
|
|
120
|
+
Must be run in an initialized libdragon project.`,
|
|
121
|
+
},
|
|
114
122
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const { spawnProcess } = require('../helpers');
|
|
2
|
+
|
|
3
|
+
const { checkContainerRunning, mustHaveProject } = require('./utils');
|
|
4
|
+
|
|
5
|
+
const stop = async (libdragonInfo) => {
|
|
6
|
+
await mustHaveProject(libdragonInfo);
|
|
7
|
+
const running =
|
|
8
|
+
libdragonInfo.containerId &&
|
|
9
|
+
(await checkContainerRunning(libdragonInfo.containerId));
|
|
10
|
+
if (!running) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
await spawnProcess('docker', ['container', 'stop', running]);
|
|
15
|
+
return libdragonInfo;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
name: 'stop',
|
|
20
|
+
fn: stop,
|
|
21
|
+
showStatus: false, // This will only print out the id
|
|
22
|
+
usage: {
|
|
23
|
+
name: 'stop',
|
|
24
|
+
summary: 'Stop the container for current project.',
|
|
25
|
+
description: `Stop the container assigned to the current libdragon project.
|
|
26
|
+
|
|
27
|
+
Must be run in an initialized libdragon project.`,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const { log } = require('../helpers');
|
|
2
|
+
const { updateImage, destroyContainer } = require('./utils');
|
|
3
|
+
const { start } = require('./start');
|
|
4
|
+
|
|
5
|
+
async function updateAndStart(libdragonInfo) {
|
|
6
|
+
const oldImageName = libdragonInfo.imageName;
|
|
7
|
+
const imageName = libdragonInfo.options.DOCKER_IMAGE ?? oldImageName;
|
|
8
|
+
// If an image is provided, always attempt to install it
|
|
9
|
+
// See https://github.com/anacierdem/libdragon-docker/issues/47
|
|
10
|
+
if (oldImageName !== imageName) {
|
|
11
|
+
log(`Updating image from \`${oldImageName}\` to \`${imageName}\``);
|
|
12
|
+
} else {
|
|
13
|
+
log(`Updating image \`${oldImageName}\``);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Download the new image and if it is different, re-create the container
|
|
17
|
+
if (await updateImage(libdragonInfo, imageName)) {
|
|
18
|
+
await destroyContainer(libdragonInfo);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
...libdragonInfo,
|
|
23
|
+
imageName,
|
|
24
|
+
containerId: await start({
|
|
25
|
+
...libdragonInfo,
|
|
26
|
+
imageName,
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
updateAndStart,
|
|
33
|
+
};
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
|
|
3
1
|
const { log } = require('../helpers');
|
|
4
2
|
const { LIBDRAGON_GIT, LIBDRAGON_BRANCH } = require('../constants');
|
|
5
|
-
const { runGitMaybeHost } = require('./utils');
|
|
6
|
-
const { fn: start } = require('./start');
|
|
3
|
+
const { runGitMaybeHost, mustHaveProject } = require('./utils');
|
|
7
4
|
const { fn: install } = require('./install');
|
|
5
|
+
const { updateAndStart } = require('./update-and-start');
|
|
8
6
|
|
|
9
7
|
const update = async (libdragonInfo) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const newInfo = {
|
|
13
|
-
...libdragonInfo,
|
|
14
|
-
containerId,
|
|
15
|
-
};
|
|
8
|
+
await mustHaveProject(libdragonInfo);
|
|
9
|
+
const newInfo = await updateAndStart(libdragonInfo);
|
|
16
10
|
|
|
17
11
|
if (newInfo.vendorStrategy !== 'manual') {
|
|
18
12
|
log(`Updating ${newInfo.vendorStrategy}...`);
|
|
@@ -31,18 +25,28 @@ const update = async (libdragonInfo) => {
|
|
|
31
25
|
'subtree',
|
|
32
26
|
'pull',
|
|
33
27
|
'--prefix',
|
|
34
|
-
|
|
28
|
+
libdragonInfo.vendorDirectory,
|
|
35
29
|
LIBDRAGON_GIT,
|
|
36
30
|
LIBDRAGON_BRANCH,
|
|
37
31
|
'--squash',
|
|
38
32
|
]);
|
|
39
33
|
}
|
|
40
34
|
|
|
41
|
-
|
|
35
|
+
// The second parameter forces it to skip the image update step as we already
|
|
36
|
+
// do that above.
|
|
37
|
+
return await install(newInfo, true);
|
|
42
38
|
};
|
|
43
39
|
|
|
44
40
|
module.exports = {
|
|
45
41
|
name: 'update',
|
|
46
42
|
fn: update,
|
|
47
43
|
showStatus: true,
|
|
44
|
+
usage: {
|
|
45
|
+
name: 'update',
|
|
46
|
+
summary: 'Update libdragon and do an install.',
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
Must be run in an initialized libdragon project.`,
|
|
50
|
+
group: ['docker'],
|
|
51
|
+
},
|
|
48
52
|
};
|