libdragon 11.0.2 → 11.0.3

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.
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs/promises');
2
2
  const path = require('path');
3
3
 
4
- const { destroyContainer } = require('./utils');
4
+ const { destroyContainer } = require('../utils');
5
5
  const { CONFIG_FILE, LIBDRAGON_PROJECT_MANIFEST } = require('../constants');
6
6
  const { fileExists, dirExists, log, ValidationError } = require('../helpers');
7
7
  const chalk = require('chalk');
@@ -13,8 +13,8 @@ const {
13
13
  } = require('../helpers');
14
14
 
15
15
  const { start } = require('./start');
16
- const { dockerHostUserParams } = require('./docker-utils');
17
- const { installDependencies } = require('./utils');
16
+ const { dockerHostUserParams } = require('../docker-utils');
17
+ const { installDependencies } = require('../utils');
18
18
 
19
19
  /**
20
20
  * @param {import('../project-info').LibdragonInfo} libdragonInfo
@@ -10,7 +10,8 @@ const {
10
10
  updateImage,
11
11
  runGitMaybeHost,
12
12
  destroyContainer,
13
- } = require('./utils');
13
+ ensureGit,
14
+ } = require('../utils');
14
15
 
15
16
  const {
16
17
  LIBDRAGON_PROJECT_MANIFEST,
@@ -109,9 +110,8 @@ const autoVendor = async (info) => {
109
110
  }
110
111
 
111
112
  // Container re-init breaks file modes assume there is git for this case.
112
- // TODO: we should remove the unnecessary inits in the future.
113
113
  if (!process.env.DOCKER_CONTAINER) {
114
- await runGitMaybeHost(info, ['init']);
114
+ await ensureGit(info);
115
115
  }
116
116
 
117
117
  // TODO: TS thinks this is already defined
@@ -172,6 +172,8 @@ const autoVendor = async (info) => {
172
172
  // This will throw if git user name/email is not set up. Let's not assume
173
173
  // anything for now. This means subtree is not supported for someone without
174
174
  // git on the host machine.
175
+ // TODO: this is probably creating an unnecessary commit for someone who
176
+ // just created a git repo and knows what they are doing.
175
177
  await runGitMaybeHost(info, [
176
178
  'commit',
177
179
  '--allow-empty',
@@ -262,6 +264,7 @@ async function init(info) {
262
264
  // We have created a new container, save the new info ASAP
263
265
  // When in a container, we should already have git
264
266
  // Re-initing breaks file modes anyways
267
+ // TODO: if this fails, we leave the project in a bad state
265
268
  await initGitAndCacheContainerId(
266
269
  /** @type Parameters<initGitAndCacheContainerId>[0] */ (info)
267
270
  );
@@ -1,4 +1,4 @@
1
- const { installDependencies } = require('./utils');
1
+ const { installDependencies } = require('../utils');
2
2
  const { start } = require('./start');
3
3
 
4
4
  /**
@@ -14,7 +14,7 @@ const {
14
14
  checkContainerAndClean,
15
15
  checkContainerRunning,
16
16
  destroyContainer,
17
- } = require('./utils');
17
+ } = require('../utils');
18
18
 
19
19
  /**
20
20
  * Create a new container
@@ -1,6 +1,6 @@
1
1
  const { spawnProcess, ValidationError } = require('../helpers');
2
2
 
3
- const { checkContainerRunning } = require('./utils');
3
+ const { checkContainerRunning } = require('../utils');
4
4
 
5
5
  /**
6
6
  * @param {import('../project-info').LibdragonInfo} libdragonInfo
@@ -5,7 +5,7 @@ const {
5
5
  installDependencies,
6
6
  updateImage,
7
7
  destroyContainer,
8
- } = require('./utils');
8
+ } = require('../utils');
9
9
  const { start } = require('./start');
10
10
 
11
11
  /**
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  *
3
- * @param {import('../project-info').LibdragonInfo} libdragonInfo
3
+ * @param {import('./project-info').LibdragonInfo} libdragonInfo
4
4
  */
5
5
  function dockerHostUserParams(libdragonInfo) {
6
6
  const { uid, gid } = libdragonInfo.userInfo;
@@ -5,14 +5,14 @@ const _ = require('lodash');
5
5
 
6
6
  const { dockerHostUserParams } = require('./docker-utils');
7
7
 
8
- const { CONTAINER_TARGET_PATH } = require('../constants');
8
+ const { CONTAINER_TARGET_PATH } = require('./constants');
9
9
  const {
10
10
  fileExists,
11
11
  toPosixPath,
12
12
  spawnProcess,
13
13
  dockerExec,
14
14
  ValidationError,
15
- } = require('../helpers');
15
+ } = require('./helpers');
16
16
 
17
17
  async function findNPMRoot() {
18
18
  try {
@@ -29,7 +29,7 @@ async function findNPMRoot() {
29
29
 
30
30
  /**
31
31
  * Install other NPM dependencies if this is an NPM project
32
- * @param {import('../project-info').LibdragonInfo} libdragonInfo
32
+ * @param {import('./project-info').LibdragonInfo} libdragonInfo
33
33
  */
34
34
  const installNPMDependencies = async (libdragonInfo) => {
35
35
  const npmRoot = await findNPMRoot();
@@ -5,9 +5,9 @@ const fs = require('fs/promises');
5
5
  const {
6
6
  checkContainerAndClean,
7
7
  initGitAndCacheContainerId,
8
- } = require('./actions/utils');
8
+ } = require('./utils');
9
9
 
10
- const { findNPMRoot } = require('./actions/npm-utils');
10
+ const { findNPMRoot } = require('./npm-utils');
11
11
 
12
12
  const {
13
13
  LIBDRAGON_PROJECT_MANIFEST,
@@ -105,8 +105,7 @@ async function findContainerId(libdragonInfo) {
105
105
  if (longId.length === 64) {
106
106
  // This shouldn't happen but if the user somehow deleted the .git folder
107
107
  // (we don't have the container id file at this point) we can recover the
108
- // project. `git init` is safe anyways and it is not executed if strategy
109
- // is `manual`
108
+ // project. This is safe and it is not executed if strategy is `manual`
110
109
  await initGitAndCacheContainerId({
111
110
  ...libdragonInfo,
112
111
  containerId: longId,
@@ -1,10 +1,7 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs/promises');
3
3
 
4
- const {
5
- CONTAINER_TARGET_PATH,
6
- CACHED_CONTAINER_FILE,
7
- } = require('../constants');
4
+ const { CONTAINER_TARGET_PATH, CACHED_CONTAINER_FILE } = require('./constants');
8
5
 
9
6
  const {
10
7
  fileExists,
@@ -16,13 +13,13 @@ const {
16
13
  CommandError,
17
14
  ValidationError,
18
15
  toNativePath,
19
- } = require('../helpers');
16
+ } = require('./helpers');
20
17
 
21
18
  const { dockerHostUserParams } = require('./docker-utils');
22
19
  const { installNPMDependencies } = require('./npm-utils');
23
20
 
24
21
  /**
25
- * @param {import('../project-info').LibdragonInfo} libdragonInfo
22
+ * @param {import('./project-info').LibdragonInfo} libdragonInfo
26
23
  */
27
24
  const installDependencies = async (libdragonInfo) => {
28
25
  const buildScriptPath = path.join(
@@ -54,7 +51,7 @@ const installDependencies = async (libdragonInfo) => {
54
51
  /**
55
52
  * Downloads the given docker image. Returns false if the local image is the
56
53
  * same, true otherwise.
57
- * @param {import('../project-info').LibdragonInfo} libdragonInfo
54
+ * @param {import('./project-info').LibdragonInfo} libdragonInfo
58
55
  * @param {string} newImageName
59
56
  */
60
57
  const updateImage = async (libdragonInfo, newImageName) => {
@@ -98,7 +95,7 @@ const updateImage = async (libdragonInfo, newImageName) => {
98
95
  };
99
96
 
100
97
  /**
101
- * @param {import('../project-info').LibdragonInfo} libdragonInfo
98
+ * @param {import('./project-info').LibdragonInfo} libdragonInfo
102
99
  */
103
100
  const destroyContainer = async (libdragonInfo) => {
104
101
  assert(
@@ -128,9 +125,9 @@ const destroyContainer = async (libdragonInfo) => {
128
125
 
129
126
  /**
130
127
  *
131
- * @param {import('../project-info').LibdragonInfo} libdragonInfo
128
+ * @param {import('./project-info').LibdragonInfo} libdragonInfo
132
129
  * @param {string[]} params
133
- * @param {import('../helpers').SpawnOptions} options
130
+ * @param {import('./helpers').SpawnOptions} options
134
131
  */
135
132
  async function runGitMaybeHost(libdragonInfo, params, options = {}) {
136
133
  assert(
@@ -139,9 +136,30 @@ async function runGitMaybeHost(libdragonInfo, params, options = {}) {
139
136
  );
140
137
  try {
141
138
  const isWin = /^win/.test(process.platform);
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
+
142
155
  return await spawnProcess(
143
156
  'git',
144
- ['-C', libdragonInfo.root, ...params],
157
+ [
158
+ '-C',
159
+ libdragonInfo.root,
160
+ ...(gitRoot ? ['--git-dir', `${gitRoot}/.git`] : []),
161
+ ...params,
162
+ ],
145
163
  // Windows git is breaking the TTY somehow - disable TTY for now
146
164
  // We are not able to display progress for the initial clone b/c of this
147
165
  // Enable progress otherwise.
@@ -171,7 +189,7 @@ async function runGitMaybeHost(libdragonInfo, params, options = {}) {
171
189
  }
172
190
 
173
191
  /**
174
- * @param {import('../project-info').LibdragonInfo} libdragonInfo
192
+ * @param {import('./project-info').LibdragonInfo} libdragonInfo
175
193
  */
176
194
  async function checkContainerAndClean(libdragonInfo) {
177
195
  assert(
@@ -229,17 +247,16 @@ async function checkContainerRunning(containerId) {
229
247
  }
230
248
 
231
249
  /**
232
- * @param {import('../project-info').LibdragonInfo & {containerId: string}} libdragonInfo
250
+ * @param {import('./project-info').LibdragonInfo & {containerId: string}} libdragonInfo
233
251
  */
234
252
  async function initGitAndCacheContainerId(libdragonInfo) {
235
253
  if (!libdragonInfo.containerId) {
236
254
  return;
237
255
  }
238
256
 
239
- // If there is managed vendoring, make sure we have a git repo. `git init` is
240
- // safe anyways...
257
+ // If there is managed vendoring, make sure we have a git repo.
241
258
  if (libdragonInfo.vendorStrategy !== 'manual') {
242
- await runGitMaybeHost(libdragonInfo, ['init']);
259
+ await ensureGit(libdragonInfo);
243
260
  }
244
261
 
245
262
  const rootGitFolder = (
@@ -263,6 +280,29 @@ async function initGitAndCacheContainerId(libdragonInfo) {
263
280
  }
264
281
  }
265
282
 
283
+ /**
284
+ * Makes sure there is a parent git repository. If not, it will create one at
285
+ * project root.
286
+ * @param {import('./project-info').LibdragonInfo} info
287
+ */
288
+ async function ensureGit(info) {
289
+ const gitRoot = (
290
+ await runGitMaybeHost(info, ['rev-parse', '--show-toplevel']).catch(() => {
291
+ // Probably host does not have git, can ignore
292
+ return '';
293
+ })
294
+ ).trim();
295
+
296
+ // If the host does not have git installed, this will not run unless we
297
+ // have already initialized it via the container, in which case we would
298
+ // have it as the git root. This is not expected to mess with host git flows
299
+ // where there is a git working tree higher in the host filesystem, which
300
+ // the container does not have access to.
301
+ if (!gitRoot) {
302
+ await runGitMaybeHost(info, ['init']);
303
+ }
304
+ }
305
+
266
306
  module.exports = {
267
307
  installDependencies,
268
308
  updateImage,
@@ -271,4 +311,5 @@ module.exports = {
271
311
  checkContainerAndClean,
272
312
  initGitAndCacheContainerId,
273
313
  runGitMaybeHost,
314
+ ensureGit,
274
315
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libdragon",
3
- "version": "11.0.2",
3
+ "version": "11.0.3",
4
4
  "description": "This is a docker wrapper for libdragon",
5
5
  "main": "index.js",
6
6
  "engines": {