@teambit/workspace-root 0.0.1

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/dist/clone.js ADDED
@@ -0,0 +1,548 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.cloneWorkspace = cloneWorkspace;
7
+ exports.ensureEmptyDir = ensureEmptyDir;
8
+ exports.resolveClonePath = resolveClonePath;
9
+ exports.resolveComponentDir = resolveComponentDir;
10
+ exports.resolveThroughExistingAncestors = resolveThroughExistingAncestors;
11
+ exports.resolveWriteToPathPerId = resolveWriteToPathPerId;
12
+ exports.throwForOverlappingDirs = throwForOverlappingDirs;
13
+ exports.topmostAbsentDir = topmostAbsentDir;
14
+ function _path() {
15
+ const data = _interopRequireDefault(require("path"));
16
+ _path = function () {
17
+ return data;
18
+ };
19
+ return data;
20
+ }
21
+ function _fsExtra() {
22
+ const data = _interopRequireDefault(require("fs-extra"));
23
+ _fsExtra = function () {
24
+ return data;
25
+ };
26
+ return data;
27
+ }
28
+ function _bitError() {
29
+ const data = require("@teambit/bit-error");
30
+ _bitError = function () {
31
+ return data;
32
+ };
33
+ return data;
34
+ }
35
+ function _hostInitializer() {
36
+ const data = require("@teambit/host-initializer");
37
+ _hostInitializer = function () {
38
+ return data;
39
+ };
40
+ return data;
41
+ }
42
+ function _importer() {
43
+ const data = require("@teambit/importer");
44
+ _importer = function () {
45
+ return data;
46
+ };
47
+ return data;
48
+ }
49
+ function _install() {
50
+ const data = require("@teambit/install");
51
+ _install = function () {
52
+ return data;
53
+ };
54
+ return data;
55
+ }
56
+ function _laneId() {
57
+ const data = require("@teambit/lane-id");
58
+ _laneId = function () {
59
+ return data;
60
+ };
61
+ return data;
62
+ }
63
+ function _legacy() {
64
+ const data = require("@teambit/legacy.bit-map");
65
+ _legacy = function () {
66
+ return data;
67
+ };
68
+ return data;
69
+ }
70
+ function _legacy2() {
71
+ const data = require("@teambit/legacy.constants");
72
+ _legacy2 = function () {
73
+ return data;
74
+ };
75
+ return data;
76
+ }
77
+ function _legacy3() {
78
+ const data = require("@teambit/legacy.utils");
79
+ _legacy3 = function () {
80
+ return data;
81
+ };
82
+ return data;
83
+ }
84
+ function _scope() {
85
+ const data = require("@teambit/scope");
86
+ _scope = function () {
87
+ return data;
88
+ };
89
+ return data;
90
+ }
91
+ function _scope2() {
92
+ const data = require("@teambit/scope.remotes");
93
+ _scope2 = function () {
94
+ return data;
95
+ };
96
+ return data;
97
+ }
98
+ function _workspace() {
99
+ const data = require("@teambit/workspace");
100
+ _workspace = function () {
101
+ return data;
102
+ };
103
+ return data;
104
+ }
105
+ function _workspaceModules() {
106
+ const data = require("@teambit/workspace.modules.workspace-locator");
107
+ _workspaceModules = function () {
108
+ return data;
109
+ };
110
+ return data;
111
+ }
112
+ function _workspaceRootData() {
113
+ const data = require("./workspace-root-data");
114
+ _workspaceRootData = function () {
115
+ return data;
116
+ };
117
+ return data;
118
+ }
119
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
120
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
121
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
122
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
123
+ /**
124
+ * runs against the new workspace, so it works on the aspects loaded for it rather than on the ones
125
+ * of the process, which loaded without a workspace.
126
+ */
127
+ class WorkspaceCloner {
128
+ constructor(harmony, workspacePath) {
129
+ this.workspacePath = workspacePath;
130
+ _defineProperty(this, "workspace", void 0);
131
+ _defineProperty(this, "importer", void 0);
132
+ _defineProperty(this, "scope", void 0);
133
+ _defineProperty(this, "install", void 0);
134
+ this.workspace = harmony.get(_workspace().WorkspaceAspect.id);
135
+ this.importer = harmony.get(_importer().ImporterAspect.id);
136
+ this.scope = harmony.get(_scope().ScopeAspect.id);
137
+ this.install = harmony.get(_install().InstallAspect.id);
138
+ }
139
+ async clone(rootId, options) {
140
+ if (options.remote) await this.addRemote(options.remote);
141
+ const laneId = options.lane ? await this.switchToLane(options.lane) : undefined;
142
+ const {
143
+ versionedRootId,
144
+ entries
145
+ } = await this.fetchRoot(rootId);
146
+ await this.writeRoot(versionedRootId);
147
+ const {
148
+ components,
149
+ missing
150
+ } = await this.writeMembers(entries, versionedRootId);
151
+ const installationError = options.skipDependencyInstallation ? undefined : await this.installGracefully();
152
+ return {
153
+ rootId: versionedRootId,
154
+ workspacePath: this.workspacePath,
155
+ components,
156
+ missing,
157
+ laneId,
158
+ installationError
159
+ };
160
+ }
161
+ async addRemote(url) {
162
+ const remote = new (_scope2().Remote)(url);
163
+ remote.name = (await remote.scope()).name;
164
+ const scopeJson = this.scope.legacyScope.scopeJson;
165
+ scopeJson.addRemote(remote);
166
+ await scopeJson.write();
167
+ }
168
+
169
+ /**
170
+ * the workspace comes out on the lane with nothing written, the way a lane switch leaves it when it
171
+ * has nothing to check out (see LaneSwitcher.saveLanesData): the lane and the objects of its
172
+ * components are fetched, the lane is tracked and made current. the imports that follow take the
173
+ * lane heads because the workspace is on it.
174
+ */
175
+ async switchToLane(lane) {
176
+ if (!lane.includes('/')) {
177
+ throw new (_bitError().BitError)(`unable to clone from lane "${lane}", the lane must be given with its scope, e.g. "my-org.my-scope/${lane}"`);
178
+ }
179
+ const laneId = _laneId().LaneId.parse(lane);
180
+ const remoteLane = await this.importer.importLaneObject(laneId);
181
+ await this.importer.fetchLaneComponents(remoteLane);
182
+ const consumer = this.workspace.consumer;
183
+ consumer.scope.lanes.trackLane({
184
+ localLane: laneId.name,
185
+ remoteLane: laneId.name,
186
+ remoteScope: laneId.scope
187
+ });
188
+ consumer.setCurrentLane(laneId, true);
189
+ consumer.scope.objects.clearObjectsFromCache();
190
+ await consumer.writeBitMap('clone');
191
+ return laneId;
192
+ }
193
+
194
+ /**
195
+ * brings the root's objects, settles its version - the one asked for, or its head on the lane or on
196
+ * main - and reads the components it lists from its versioned `.bitmap`.
197
+ */
198
+ async fetchRoot(rootId) {
199
+ const {
200
+ importedIds,
201
+ missingIds
202
+ } = await this.importer.import({
203
+ ids: [rootId.toString()],
204
+ objectsOnly: true,
205
+ installNpmPackages: false,
206
+ writeConfigFiles: false
207
+ });
208
+ const versionedRootId = importedIds.find(id => id.isEqualWithoutVersion(rootId));
209
+ if (!versionedRootId) {
210
+ // the importer reports a component the remote does not have rather than throwing
211
+ if (missingIds?.length) {
212
+ throw new (_bitError().BitError)(`unable to clone, the remote scope "${rootId.scope}" does not have "${rootId.toString()}". a workspace is cloned from an exported workspace-root component, run "bit export" in its workspace first`);
213
+ }
214
+ throw new (_bitError().BitError)(`unable to clone, "${rootId.toString()}" was not imported`);
215
+ }
216
+ const rootComponent = await this.scope.legacyScope.getConsumerComponent(versionedRootId);
217
+ if (!(0, _workspaceRootData().isWorkspaceRootComponent)(rootComponent.extensions)) {
218
+ throw new (_bitError().BitError)(`unable to clone "${versionedRootId.toString()}", it is not a workspace-root component. a workspace is cloned from the component tracked at its root, run "bit add ." there to create one`);
219
+ }
220
+ const bitmapFile = rootComponent.files.find(file => (0, _legacy().isWorkspaceMapFile)((0, _legacy3().pathNormalizeToLinux)(file.relative)));
221
+ const entries = bitmapFile ? (0, _legacy().readVersionedBitmapEntries)(bitmapFile.contents.toString()) : [];
222
+ return {
223
+ versionedRootId,
224
+ entries
225
+ };
226
+ }
227
+
228
+ /**
229
+ * the root's own files, onto the workspace directory, as `bit import <id> --path <dir>` does. it
230
+ * goes before the members: the guards of the root let the files `bit init` generated be replaced
231
+ * only while the workspace is still empty of components.
232
+ */
233
+ async writeRoot(versionedRootId) {
234
+ const {
235
+ importedIds
236
+ } = await this.importer.import({
237
+ ids: [versionedRootId.toString()],
238
+ writeToPath: this.workspacePath,
239
+ installNpmPackages: false,
240
+ writeConfigFiles: false
241
+ });
242
+ if (!importedIds.length) throw new (_bitError().BitError)(`unable to clone, "${versionedRootId.toString()}" was not imported`);
243
+ }
244
+
245
+ /**
246
+ * every component the root lists, in one import - each to the directory the root recorded for it.
247
+ *
248
+ * a component the remote does not have is reported rather than fetched: a root versioned before the
249
+ * first export lists its members by their default scope, and a member may have stayed behind.
250
+ */
251
+ async writeMembers(entries, rootId) {
252
+ const writeToPathPerId = resolveWriteToPathPerId(this.workspacePath, entries, rootId);
253
+ throwForOverlappingDirs(writeToPathPerId);
254
+ const ids = Object.keys(writeToPathPerId);
255
+ if (!ids.length) return {
256
+ components: [],
257
+ missing: []
258
+ };
259
+ const {
260
+ importedIds,
261
+ missingIds
262
+ } = await this.importer.import({
263
+ ids,
264
+ writeToPathPerId,
265
+ installNpmPackages: false,
266
+ writeConfigFiles: false
267
+ });
268
+ const components = importedIds.filter(id => writeToPathPerId[id.toStringWithoutVersion()]);
269
+ return {
270
+ components,
271
+ missing: missingIds || []
272
+ };
273
+ }
274
+
275
+ /**
276
+ * the same install `bit import` runs once its components are written, compile included. a failure
277
+ * does not undo the clone, the workspace is complete without it.
278
+ */
279
+ async installGracefully() {
280
+ try {
281
+ await this.install.install(undefined, {
282
+ dedupe: true,
283
+ updateExisting: false,
284
+ import: false,
285
+ writeConfigFiles: true
286
+ });
287
+ return undefined;
288
+ } catch (err) {
289
+ return err;
290
+ }
291
+ }
292
+ }
293
+
294
+ /**
295
+ * makes a workspace out of a workspace-root component, the way `git clone` makes a working tree out of
296
+ * a repository: a fresh workspace in an empty directory, the root's files at its root, every component
297
+ * the root's `.bitmap` lists in the directory it records, then install. the versioned `.bitmap` has
298
+ * no versions on purpose (see normalizeBitmapContentForVersioning), so the components come at their
299
+ * heads - on main, or on the lane when one is given - and a root version pins the root files only.
300
+ *
301
+ * the directory must be empty or absent, and outside any workspace. there is no override: this is a
302
+ * new workspace, not an import into one, so nothing at the target is the user's.
303
+ */
304
+ async function cloneWorkspace(rootId, dir, options, loadBit) {
305
+ const workspacePath = await resolveThroughExistingAncestors(resolveClonePath(dir, rootId));
306
+ await throwForWorkspaceAbove(workspacePath);
307
+ // before anything is made: ensureDir below creates every missing level, not only the destination,
308
+ // so this is the point a failure has to undo from
309
+ const topmostCreated = await topmostAbsentDir(workspacePath);
310
+ const createdDir = await ensureEmptyDir(workspacePath);
311
+ const originalCwd = process.cwd();
312
+ try {
313
+ // the code paths below, from the workspace init to the install, take the workspace from the cwd.
314
+ // inside the try, so that a directory made here is removed even when entering it is what failed
315
+ process.chdir(workspacePath);
316
+ // only workspace.jsonc, .bitmap and the scope dir. the root files come from the component, and
317
+ // only what the component versions belongs at the root: no package.json, agent file or mcp config
318
+ await _hostInitializer().HostInitializerMain.init(workspacePath, false, true, false, false, false, false, false, false, {}, undefined, undefined, {
319
+ skipDefaultMcp: true,
320
+ skipAgentInstructions: true
321
+ });
322
+ const harmony = await loadBit(workspacePath);
323
+ return await new WorkspaceCloner(harmony, workspacePath).clone(rootId, options);
324
+ } catch (err) {
325
+ // leave the directory before removing it, and leave nothing half-made behind: it was empty or
326
+ // absent to begin with. removing the topmost level that was made here takes the ones below it
327
+ // along, so "clone into new-parent/ws" does not leave an empty "new-parent" standing.
328
+ process.chdir(originalCwd);
329
+ if (createdDir) await _fsExtra().default.remove(topmostCreated || workspacePath);else await _fsExtra().default.emptyDir(workspacePath);
330
+ throw err;
331
+ } finally {
332
+ // the clone itself runs with the new workspace as the cwd, its install included. the caller, which
333
+ // may be a program that goes on to do other things, keeps the directory it was in.
334
+ process.chdir(originalCwd);
335
+ }
336
+ }
337
+
338
+ /**
339
+ * the directories a component is never written into, at any depth: bit's own object store and temp
340
+ * dir, git's, and the installed packages. they are the machinery of the workspace being made rather
341
+ * than part of it, and the scan that builds a component's file-set skips them for the same reason
342
+ * (see SCAN_IGNORE_LIST). a map that lists a member in one of them writes into the workings of the
343
+ * clone - `.bit` holds the objects the clone is being read from.
344
+ */
345
+ const RESERVED_DIRS = [_legacy2().BIT_HIDDEN_DIR, _legacy2().DOT_GIT_DIR, _legacy2().BIT_WORKSPACE_TMP_DIRNAME, 'node_modules'].map(dir => dir.toLowerCase());
346
+
347
+ /**
348
+ * the directory of a component the root lists, inside the workspace. the list comes from a remote,
349
+ * so a root-dir that escapes the workspace - "../x", an absolute path - is refused, and so are the
350
+ * workspace root itself, which only the root component owns, a directory bit or git keeps for
351
+ * itself, and a missing root-dir, which no `.bitmap` of the current schema has.
352
+ */
353
+ function resolveComponentDir(workspacePath, entry) {
354
+ const {
355
+ rootDir
356
+ } = entry;
357
+ // the absolute check goes before the resolve: an absolute path that happens to sit under this
358
+ // workspace resolves to an ordinary relative one and would pass every check below, though it is
359
+ // still a directory of the machine the root was snapped on rather than one of this workspace.
360
+ // the type is checked, not assumed: the entry is parsed from a `.bitmap` that came from a remote, and
361
+ // the parser asserts its shape without looking at the values. handing a number or an object to
362
+ // path.isAbsolute would abort the clone with a node type error instead of the message below.
363
+ const isUsable = typeof rootDir === 'string' && rootDir.length > 0 && !_path().default.isAbsolute(rootDir);
364
+ const target = isUsable ? _path().default.resolve(workspacePath, rootDir) : undefined;
365
+ const relative = target ? _path().default.relative(workspacePath, target) : undefined;
366
+ // a leading ".." is only a way out when it is the whole segment: a directory may be named "..cache"
367
+ const climbsOut = relative === '..' || relative?.startsWith(`..${_path().default.sep}`);
368
+ // case-folded: on a case-insensitive filesystem ".BIT/objects" is the local scope the clone is
369
+ // being read out of. nothing legitimate is named this way on the filesystems that tell them apart
370
+ // either, so the same list is refused everywhere rather than by platform
371
+ const isReserved = relative?.split(_path().default.sep).some(segment => RESERVED_DIRS.includes(segment.toLowerCase()));
372
+ if (!target || !relative || climbsOut || isReserved || _path().default.isAbsolute(relative)) {
373
+ throw new (_bitError().BitError)(`unable to clone, the root component lists "${entry.id}" at "${entry.rootDir}", which is not a directory inside the workspace`);
374
+ }
375
+ return target;
376
+ }
377
+
378
+ /**
379
+ * where each member the root lists is written to, by id.
380
+ *
381
+ * built through a Map rather than straight onto the object the importer takes, because an id read
382
+ * out of a remote `.bitmap` is an arbitrary string: assigning one that reads `__proto__` runs the
383
+ * inherited setter instead of creating an own property, and two entries can resolve to a single id
384
+ * (the key and the name/scope fields are independent, see readVersionedBitmapEntries) so the later
385
+ * one overwrites the earlier. either way that member leaves no trace here - it is absent from the
386
+ * import request, and absent from the missing-members report too, since that reports what the remote
387
+ * did not have. the clone comes out short of a component with nothing to say why, so a collision is
388
+ * refused instead.
389
+ */
390
+ function resolveWriteToPathPerId(workspacePath, entries, rootId) {
391
+ const dirPerId = new Map();
392
+ let rootSeen = false;
393
+ entries.forEach(entry => {
394
+ if (entry.rootDir === _legacy().WORKSPACE_ROOT_DIR) {
395
+ // the root's own entry, skipped because the root is written before the members (see writeRoot).
396
+ // anything else at the workspace root is a map bit did not write - it refuses a second entry
397
+ // there on load - and passing over it would leave that member out of the clone without a word.
398
+ // matched on the name rather than the whole id: a root versioned before its first export lists
399
+ // itself by its default scope, which is not necessarily the scope it was exported to
400
+ if (rootSeen || nameOfVersionedId(entry.id) !== rootId.fullName) {
401
+ throw new (_bitError().BitError)(`unable to clone, the root component lists "${entry.id}" at the workspace root, which only "${rootId.toStringWithoutVersion()}" occupies`);
402
+ }
403
+ rootSeen = true;
404
+ return;
405
+ }
406
+ if (dirPerId.has(entry.id)) {
407
+ throw new (_bitError().BitError)(`unable to clone, the root component lists "${entry.id}" more than once`);
408
+ }
409
+ dirPerId.set(entry.id, resolveComponentDir(workspacePath, entry));
410
+ });
411
+ // defines every key as an own property, `__proto__` included
412
+ return Object.fromEntries(dirPerId);
413
+ }
414
+
415
+ /** an id out of a versioned `.bitmap` is "scope/name", or "name" for a component never exported */
416
+ function nameOfVersionedId(id) {
417
+ return id.split('/').slice(1).join('/') || id;
418
+ }
419
+
420
+ /**
421
+ * two members the root lists may not share a directory, nor sit one inside another. a `.bitmap` bit
422
+ * wrote holds neither - it refuses a duplicate root-dir, and a component under another component's
423
+ * directory - but this one came from a remote. left to the writer, a collision is relocated and then
424
+ * moved back to the path each component was asked for, so the later one lands on the earlier one's
425
+ * files and the clone comes out missing a component it reported as written.
426
+ */
427
+ function throwForOverlappingDirs(dirPerId) {
428
+ const idByDir = new Map();
429
+ const refuse = (id, otherId, dir) => {
430
+ throw new (_bitError().BitError)(`unable to clone, the root component lists "${id}" at "${dir}", which overlaps the directory it lists "${otherId}" at`);
431
+ };
432
+ // the question here is which destinations land on one another, not what a path is named, so the
433
+ // comparison is case-folded: on a case-insensitive filesystem "Packages/Foo" and "packages/foo" are
434
+ // one directory. a workspace whose members differ only by the case of their directories cannot be
435
+ // cloned on macOS or Windows at all, so it is refused everywhere rather than on some platforms -
436
+ // one behaviour, and a message instead of one member's files landing on the other's. the paths
437
+ // themselves are untouched, the writes and the message keep their own spelling
438
+ const sameDir = dir => dir.toLowerCase();
439
+ Object.entries(dirPerId).forEach(([id, dir]) => {
440
+ const taken = idByDir.get(sameDir(dir));
441
+ if (taken) refuse(id, taken, dir);
442
+ idByDir.set(sameDir(dir), id);
443
+ });
444
+ Object.entries(dirPerId).forEach(([id, dir]) => {
445
+ // every level above it, so a component nested any number of levels inside another is caught
446
+ for (let parent = _path().default.dirname(dir); parent !== _path().default.dirname(parent); parent = _path().default.dirname(parent)) {
447
+ const owner = idByDir.get(sameDir(parent));
448
+ if (owner) refuse(id, owner, dir);
449
+ }
450
+ });
451
+ }
452
+
453
+ /**
454
+ * where the clone lands: the directory given, or one named after the component, as `git clone` names
455
+ * the working tree after the repository. relative to the cwd, the clone runs outside a workspace.
456
+ */
457
+ function resolveClonePath(dir, rootId) {
458
+ return _path().default.resolve(dir || rootId.name);
459
+ }
460
+
461
+ /**
462
+ * the destination with the directories above it resolved through any symbolic link, and its own last
463
+ * segment left as it is.
464
+ *
465
+ * a link above the target redirects everything that follows - the directory creation, the init, the
466
+ * files, and the cleanup of a failed clone - while the lexical path says nothing about it, so the
467
+ * workspace check would look in one place and the writes land in another, inside someone else's
468
+ * workspace. the last segment is deliberately not resolved: a link *at* the destination is refused
469
+ * rather than followed, which is ensureEmptyDir's rule.
470
+ */
471
+ async function resolveThroughExistingAncestors(dirPath) {
472
+ const parent = _path().default.dirname(dirPath);
473
+ if (parent === dirPath) return dirPath;
474
+ return _path().default.join(await realpathOfNearestExisting(parent), _path().default.basename(dirPath));
475
+ }
476
+
477
+ /**
478
+ * the highest directory on the way to the destination that does not exist yet, or undefined when the
479
+ * destination is already there. what a failed clone removes, so that the levels made on the way to it
480
+ * go too rather than being left standing empty.
481
+ */
482
+ async function topmostAbsentDir(dirPath) {
483
+ if (await _fsExtra().default.pathExists(dirPath)) return undefined;
484
+ const parent = _path().default.dirname(dirPath);
485
+ if (parent === dirPath) return dirPath;
486
+ return (await topmostAbsentDir(parent)) || dirPath;
487
+ }
488
+
489
+ /**
490
+ * the deepest part of the path that exists, resolved, with the part that does not exist yet appended
491
+ * as it is. the destination of a clone is normally absent, so there is nothing to resolve on it.
492
+ */
493
+ async function realpathOfNearestExisting(dirPath) {
494
+ const parent = _path().default.dirname(dirPath);
495
+ if (parent === dirPath) return dirPath;
496
+ try {
497
+ return await _fsExtra().default.realpath(dirPath);
498
+ } catch (err) {
499
+ if (err.code !== 'ENOENT') throw err;
500
+ return _path().default.join(await realpathOfNearestExisting(parent), _path().default.basename(dirPath));
501
+ }
502
+ }
503
+
504
+ /**
505
+ * a clone makes its own workspace. the init below takes the nearest workspace at or above the target
506
+ * instead of making one when there is a workspace above it, and the clone then writes its components
507
+ * into that workspace's `.bitmap` - reporting success while leaving someone else's workspace holding
508
+ * entries for a tree it does not own.
509
+ */
510
+ async function throwForWorkspaceAbove(workspacePath) {
511
+ const workspaceInfo = await (0, _workspaceModules().getWorkspaceInfo)(workspacePath);
512
+ if (!workspaceInfo) return;
513
+ throw new (_bitError().BitError)(`unable to clone into "${workspacePath}", it is inside the workspace at "${workspaceInfo.path}".
514
+ a clone creates a workspace of its own, run it outside any workspace`);
515
+ }
516
+
517
+ /**
518
+ * the workspace is written into this directory and a failed clone empties it again, so it has to be
519
+ * the directory it appears to be: a symbolic link would put the workspace, and then the cleanup,
520
+ * wherever it points. the same rule the writer applies to the files of a root (see
521
+ * throwForSymlinksInTheWay).
522
+ *
523
+ * @returns whether the directory was created here, so a failed clone knows to remove it
524
+ */
525
+ async function ensureEmptyDir(dirPath) {
526
+ const stat = await lstatIfExists(dirPath);
527
+ if (!stat) {
528
+ await _fsExtra().default.ensureDir(dirPath);
529
+ return true;
530
+ }
531
+ if (stat.isSymbolicLink()) {
532
+ throw new (_bitError().BitError)(`unable to clone into "${dirPath}", it is a symbolic link and the workspace would be written through it`);
533
+ }
534
+ if (!stat.isDirectory()) throw new (_bitError().BitError)(`unable to clone into "${dirPath}", it is not a directory`);
535
+ const entries = await _fsExtra().default.readdir(dirPath);
536
+ if (entries.length) throw new (_bitError().BitError)(`unable to clone into "${dirPath}", the directory is not empty`);
537
+ return false;
538
+ }
539
+ async function lstatIfExists(dirPath) {
540
+ try {
541
+ return await _fsExtra().default.lstat(dirPath);
542
+ } catch (err) {
543
+ if (err.code === 'ENOENT') return undefined;
544
+ throw err;
545
+ }
546
+ }
547
+
548
+ //# sourceMappingURL=clone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_path","data","_interopRequireDefault","require","_fsExtra","_bitError","_hostInitializer","_importer","_install","_laneId","_legacy","_legacy2","_legacy3","_scope","_scope2","_workspace","_workspaceModules","_workspaceRootData","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","WorkspaceCloner","constructor","harmony","workspacePath","workspace","get","WorkspaceAspect","id","importer","ImporterAspect","scope","ScopeAspect","install","InstallAspect","clone","rootId","options","remote","addRemote","laneId","lane","switchToLane","undefined","versionedRootId","entries","fetchRoot","writeRoot","components","missing","writeMembers","installationError","skipDependencyInstallation","installGracefully","url","Remote","name","scopeJson","legacyScope","write","includes","BitError","LaneId","parse","remoteLane","importLaneObject","fetchLaneComponents","consumer","lanes","trackLane","localLane","remoteScope","setCurrentLane","objects","clearObjectsFromCache","writeBitMap","importedIds","missingIds","import","ids","toString","objectsOnly","installNpmPackages","writeConfigFiles","find","isEqualWithoutVersion","length","rootComponent","getConsumerComponent","isWorkspaceRootComponent","extensions","bitmapFile","files","file","isWorkspaceMapFile","pathNormalizeToLinux","relative","readVersionedBitmapEntries","contents","writeToPath","writeToPathPerId","resolveWriteToPathPerId","throwForOverlappingDirs","keys","filter","toStringWithoutVersion","dedupe","updateExisting","err","cloneWorkspace","dir","loadBit","resolveThroughExistingAncestors","resolveClonePath","throwForWorkspaceAbove","topmostCreated","topmostAbsentDir","createdDir","ensureEmptyDir","originalCwd","process","cwd","chdir","HostInitializerMain","init","skipDefaultMcp","skipAgentInstructions","fs","remove","emptyDir","RESERVED_DIRS","BIT_HIDDEN_DIR","DOT_GIT_DIR","BIT_WORKSPACE_TMP_DIRNAME","map","toLowerCase","resolveComponentDir","entry","rootDir","isUsable","path","isAbsolute","target","resolve","climbsOut","startsWith","sep","isReserved","split","some","segment","dirPerId","Map","rootSeen","forEach","WORKSPACE_ROOT_DIR","nameOfVersionedId","fullName","has","set","fromEntries","slice","join","idByDir","refuse","otherId","sameDir","taken","parent","dirname","owner","dirPath","realpathOfNearestExisting","basename","pathExists","realpath","code","workspaceInfo","getWorkspaceInfo","stat","lstatIfExists","ensureDir","isSymbolicLink","isDirectory","readdir","lstat"],"sources":["clone.ts"],"sourcesContent":["import path from 'path';\nimport type { Stats } from 'fs-extra';\nimport fs from 'fs-extra';\nimport { BitError } from '@teambit/bit-error';\nimport type { ComponentID } from '@teambit/component-id';\nimport type { Harmony } from '@teambit/harmony';\nimport { HostInitializerMain } from '@teambit/host-initializer';\nimport type { ImporterMain } from '@teambit/importer';\nimport { ImporterAspect } from '@teambit/importer';\nimport type { InstallMain } from '@teambit/install';\nimport { InstallAspect } from '@teambit/install';\nimport { LaneId } from '@teambit/lane-id';\nimport type { VersionedBitmapEntry } from '@teambit/legacy.bit-map';\nimport { isWorkspaceMapFile, readVersionedBitmapEntries, WORKSPACE_ROOT_DIR } from '@teambit/legacy.bit-map';\nimport { BIT_HIDDEN_DIR, BIT_WORKSPACE_TMP_DIRNAME, DOT_GIT_DIR } from '@teambit/legacy.constants';\nimport { pathNormalizeToLinux } from '@teambit/legacy.utils';\nimport type { ScopeMain } from '@teambit/scope';\nimport { ScopeAspect } from '@teambit/scope';\nimport { Remote } from '@teambit/scope.remotes';\nimport type { Workspace } from '@teambit/workspace';\nimport { WorkspaceAspect } from '@teambit/workspace';\nimport { getWorkspaceInfo } from '@teambit/workspace.modules.workspace-locator';\nimport { isWorkspaceRootComponent } from './workspace-root-data';\n\nexport type LoadBit = (workspacePath?: string) => Promise<Harmony>;\n\nexport type CloneOptions = {\n /**\n * clone the workspace as it is on this lane, \"scope/name\". the workspace comes out on the lane,\n * and the components at their heads there; a component the lane does not have comes from main.\n */\n lane?: string;\n /**\n * url of the scope hosting the components, for a scope that is neither on bit.cloud nor in the\n * global remotes. it is registered in the new workspace.\n */\n remote?: string;\n skipDependencyInstallation?: boolean;\n};\n\nexport type CloneResult = {\n /** the root, at the version the workspace was made from */\n rootId: ComponentID;\n workspacePath: string;\n /** the components the root lists, at the versions they were written with */\n components: ComponentID[];\n /**\n * components the root lists that their remote does not have - never exported, or exported to\n * another scope - so the clone is without them.\n */\n missing: string[];\n laneId?: LaneId;\n /** the clone is complete without the install; the user re-runs it in the workspace */\n installationError?: Error;\n};\n\n/**\n * runs against the new workspace, so it works on the aspects loaded for it rather than on the ones\n * of the process, which loaded without a workspace.\n */\nclass WorkspaceCloner {\n private workspace: Workspace;\n private importer: ImporterMain;\n private scope: ScopeMain;\n private install: InstallMain;\n\n constructor(\n harmony: Harmony,\n private workspacePath: string\n ) {\n this.workspace = harmony.get<Workspace>(WorkspaceAspect.id);\n this.importer = harmony.get<ImporterMain>(ImporterAspect.id);\n this.scope = harmony.get<ScopeMain>(ScopeAspect.id);\n this.install = harmony.get<InstallMain>(InstallAspect.id);\n }\n\n async clone(rootId: ComponentID, options: CloneOptions): Promise<CloneResult> {\n if (options.remote) await this.addRemote(options.remote);\n const laneId = options.lane ? await this.switchToLane(options.lane) : undefined;\n const { versionedRootId, entries } = await this.fetchRoot(rootId);\n await this.writeRoot(versionedRootId);\n const { components, missing } = await this.writeMembers(entries, versionedRootId);\n const installationError = options.skipDependencyInstallation ? undefined : await this.installGracefully();\n return {\n rootId: versionedRootId,\n workspacePath: this.workspacePath,\n components,\n missing,\n laneId,\n installationError,\n };\n }\n\n private async addRemote(url: string) {\n const remote = new Remote(url);\n remote.name = (await remote.scope()).name;\n const scopeJson = this.scope.legacyScope.scopeJson;\n scopeJson.addRemote(remote);\n await scopeJson.write();\n }\n\n /**\n * the workspace comes out on the lane with nothing written, the way a lane switch leaves it when it\n * has nothing to check out (see LaneSwitcher.saveLanesData): the lane and the objects of its\n * components are fetched, the lane is tracked and made current. the imports that follow take the\n * lane heads because the workspace is on it.\n */\n private async switchToLane(lane: string): Promise<LaneId> {\n if (!lane.includes('/')) {\n throw new BitError(\n `unable to clone from lane \"${lane}\", the lane must be given with its scope, e.g. \"my-org.my-scope/${lane}\"`\n );\n }\n const laneId = LaneId.parse(lane);\n const remoteLane = await this.importer.importLaneObject(laneId);\n await this.importer.fetchLaneComponents(remoteLane);\n const consumer = this.workspace.consumer;\n consumer.scope.lanes.trackLane({ localLane: laneId.name, remoteLane: laneId.name, remoteScope: laneId.scope });\n consumer.setCurrentLane(laneId, true);\n consumer.scope.objects.clearObjectsFromCache();\n await consumer.writeBitMap('clone');\n return laneId;\n }\n\n /**\n * brings the root's objects, settles its version - the one asked for, or its head on the lane or on\n * main - and reads the components it lists from its versioned `.bitmap`.\n */\n private async fetchRoot(\n rootId: ComponentID\n ): Promise<{ versionedRootId: ComponentID; entries: VersionedBitmapEntry[] }> {\n const { importedIds, missingIds } = await this.importer.import({\n ids: [rootId.toString()],\n objectsOnly: true,\n installNpmPackages: false,\n writeConfigFiles: false,\n });\n const versionedRootId = importedIds.find((id) => id.isEqualWithoutVersion(rootId));\n if (!versionedRootId) {\n // the importer reports a component the remote does not have rather than throwing\n if (missingIds?.length) {\n throw new BitError(\n `unable to clone, the remote scope \"${rootId.scope}\" does not have \"${rootId.toString()}\". a workspace is cloned from an exported workspace-root component, run \"bit export\" in its workspace first`\n );\n }\n throw new BitError(`unable to clone, \"${rootId.toString()}\" was not imported`);\n }\n const rootComponent = await this.scope.legacyScope.getConsumerComponent(versionedRootId);\n if (!isWorkspaceRootComponent(rootComponent.extensions)) {\n throw new BitError(\n `unable to clone \"${versionedRootId.toString()}\", it is not a workspace-root component. a workspace is cloned from the component tracked at its root, run \"bit add .\" there to create one`\n );\n }\n const bitmapFile = rootComponent.files.find((file) => isWorkspaceMapFile(pathNormalizeToLinux(file.relative)));\n const entries = bitmapFile ? readVersionedBitmapEntries(bitmapFile.contents.toString()) : [];\n return { versionedRootId, entries };\n }\n\n /**\n * the root's own files, onto the workspace directory, as `bit import <id> --path <dir>` does. it\n * goes before the members: the guards of the root let the files `bit init` generated be replaced\n * only while the workspace is still empty of components.\n */\n private async writeRoot(versionedRootId: ComponentID) {\n const { importedIds } = await this.importer.import({\n ids: [versionedRootId.toString()],\n writeToPath: this.workspacePath,\n installNpmPackages: false,\n writeConfigFiles: false,\n });\n if (!importedIds.length) throw new BitError(`unable to clone, \"${versionedRootId.toString()}\" was not imported`);\n }\n\n /**\n * every component the root lists, in one import - each to the directory the root recorded for it.\n *\n * a component the remote does not have is reported rather than fetched: a root versioned before the\n * first export lists its members by their default scope, and a member may have stayed behind.\n */\n private async writeMembers(\n entries: VersionedBitmapEntry[],\n rootId: ComponentID\n ): Promise<{ components: ComponentID[]; missing: string[] }> {\n const writeToPathPerId = resolveWriteToPathPerId(this.workspacePath, entries, rootId);\n throwForOverlappingDirs(writeToPathPerId);\n const ids = Object.keys(writeToPathPerId);\n if (!ids.length) return { components: [], missing: [] };\n const { importedIds, missingIds } = await this.importer.import({\n ids,\n writeToPathPerId,\n installNpmPackages: false,\n writeConfigFiles: false,\n });\n const components = importedIds.filter((id) => writeToPathPerId[id.toStringWithoutVersion()]);\n return { components, missing: missingIds || [] };\n }\n\n /**\n * the same install `bit import` runs once its components are written, compile included. a failure\n * does not undo the clone, the workspace is complete without it.\n */\n private async installGracefully(): Promise<Error | undefined> {\n try {\n await this.install.install(undefined, {\n dedupe: true,\n updateExisting: false,\n import: false,\n writeConfigFiles: true,\n });\n return undefined;\n } catch (err: any) {\n return err;\n }\n }\n}\n\n/**\n * makes a workspace out of a workspace-root component, the way `git clone` makes a working tree out of\n * a repository: a fresh workspace in an empty directory, the root's files at its root, every component\n * the root's `.bitmap` lists in the directory it records, then install. the versioned `.bitmap` has\n * no versions on purpose (see normalizeBitmapContentForVersioning), so the components come at their\n * heads - on main, or on the lane when one is given - and a root version pins the root files only.\n *\n * the directory must be empty or absent, and outside any workspace. there is no override: this is a\n * new workspace, not an import into one, so nothing at the target is the user's.\n */\nexport async function cloneWorkspace(\n rootId: ComponentID,\n dir: string | undefined,\n options: CloneOptions,\n loadBit: LoadBit\n): Promise<CloneResult> {\n const workspacePath = await resolveThroughExistingAncestors(resolveClonePath(dir, rootId));\n await throwForWorkspaceAbove(workspacePath);\n // before anything is made: ensureDir below creates every missing level, not only the destination,\n // so this is the point a failure has to undo from\n const topmostCreated = await topmostAbsentDir(workspacePath);\n const createdDir = await ensureEmptyDir(workspacePath);\n const originalCwd = process.cwd();\n try {\n // the code paths below, from the workspace init to the install, take the workspace from the cwd.\n // inside the try, so that a directory made here is removed even when entering it is what failed\n process.chdir(workspacePath);\n // only workspace.jsonc, .bitmap and the scope dir. the root files come from the component, and\n // only what the component versions belongs at the root: no package.json, agent file or mcp config\n await HostInitializerMain.init(\n workspacePath,\n false,\n true,\n false,\n false,\n false,\n false,\n false,\n false,\n {},\n undefined,\n undefined,\n {\n skipDefaultMcp: true,\n skipAgentInstructions: true,\n }\n );\n const harmony = await loadBit(workspacePath);\n return await new WorkspaceCloner(harmony, workspacePath).clone(rootId, options);\n } catch (err) {\n // leave the directory before removing it, and leave nothing half-made behind: it was empty or\n // absent to begin with. removing the topmost level that was made here takes the ones below it\n // along, so \"clone into new-parent/ws\" does not leave an empty \"new-parent\" standing.\n process.chdir(originalCwd);\n if (createdDir) await fs.remove(topmostCreated || workspacePath);\n else await fs.emptyDir(workspacePath);\n throw err;\n } finally {\n // the clone itself runs with the new workspace as the cwd, its install included. the caller, which\n // may be a program that goes on to do other things, keeps the directory it was in.\n process.chdir(originalCwd);\n }\n}\n\n/**\n * the directories a component is never written into, at any depth: bit's own object store and temp\n * dir, git's, and the installed packages. they are the machinery of the workspace being made rather\n * than part of it, and the scan that builds a component's file-set skips them for the same reason\n * (see SCAN_IGNORE_LIST). a map that lists a member in one of them writes into the workings of the\n * clone - `.bit` holds the objects the clone is being read from.\n */\nconst RESERVED_DIRS = [BIT_HIDDEN_DIR, DOT_GIT_DIR, BIT_WORKSPACE_TMP_DIRNAME, 'node_modules'].map((dir) =>\n dir.toLowerCase()\n);\n\n/**\n * the directory of a component the root lists, inside the workspace. the list comes from a remote,\n * so a root-dir that escapes the workspace - \"../x\", an absolute path - is refused, and so are the\n * workspace root itself, which only the root component owns, a directory bit or git keeps for\n * itself, and a missing root-dir, which no `.bitmap` of the current schema has.\n */\nexport function resolveComponentDir(workspacePath: string, entry: VersionedBitmapEntry): string {\n const { rootDir } = entry;\n // the absolute check goes before the resolve: an absolute path that happens to sit under this\n // workspace resolves to an ordinary relative one and would pass every check below, though it is\n // still a directory of the machine the root was snapped on rather than one of this workspace.\n // the type is checked, not assumed: the entry is parsed from a `.bitmap` that came from a remote, and\n // the parser asserts its shape without looking at the values. handing a number or an object to\n // path.isAbsolute would abort the clone with a node type error instead of the message below.\n const isUsable = typeof rootDir === 'string' && rootDir.length > 0 && !path.isAbsolute(rootDir);\n const target = isUsable ? path.resolve(workspacePath, rootDir) : undefined;\n const relative = target ? path.relative(workspacePath, target) : undefined;\n // a leading \"..\" is only a way out when it is the whole segment: a directory may be named \"..cache\"\n const climbsOut = relative === '..' || relative?.startsWith(`..${path.sep}`);\n // case-folded: on a case-insensitive filesystem \".BIT/objects\" is the local scope the clone is\n // being read out of. nothing legitimate is named this way on the filesystems that tell them apart\n // either, so the same list is refused everywhere rather than by platform\n const isReserved = relative?.split(path.sep).some((segment) => RESERVED_DIRS.includes(segment.toLowerCase()));\n if (!target || !relative || climbsOut || isReserved || path.isAbsolute(relative)) {\n throw new BitError(\n `unable to clone, the root component lists \"${entry.id}\" at \"${entry.rootDir}\", which is not a directory inside the workspace`\n );\n }\n return target;\n}\n\n/**\n * where each member the root lists is written to, by id.\n *\n * built through a Map rather than straight onto the object the importer takes, because an id read\n * out of a remote `.bitmap` is an arbitrary string: assigning one that reads `__proto__` runs the\n * inherited setter instead of creating an own property, and two entries can resolve to a single id\n * (the key and the name/scope fields are independent, see readVersionedBitmapEntries) so the later\n * one overwrites the earlier. either way that member leaves no trace here - it is absent from the\n * import request, and absent from the missing-members report too, since that reports what the remote\n * did not have. the clone comes out short of a component with nothing to say why, so a collision is\n * refused instead.\n */\nexport function resolveWriteToPathPerId(\n workspacePath: string,\n entries: VersionedBitmapEntry[],\n rootId: ComponentID\n): Record<string, string> {\n const dirPerId = new Map<string, string>();\n let rootSeen = false;\n entries.forEach((entry) => {\n if (entry.rootDir === WORKSPACE_ROOT_DIR) {\n // the root's own entry, skipped because the root is written before the members (see writeRoot).\n // anything else at the workspace root is a map bit did not write - it refuses a second entry\n // there on load - and passing over it would leave that member out of the clone without a word.\n // matched on the name rather than the whole id: a root versioned before its first export lists\n // itself by its default scope, which is not necessarily the scope it was exported to\n if (rootSeen || nameOfVersionedId(entry.id) !== rootId.fullName) {\n throw new BitError(\n `unable to clone, the root component lists \"${entry.id}\" at the workspace root, which only \"${rootId.toStringWithoutVersion()}\" occupies`\n );\n }\n rootSeen = true;\n return;\n }\n if (dirPerId.has(entry.id)) {\n throw new BitError(`unable to clone, the root component lists \"${entry.id}\" more than once`);\n }\n dirPerId.set(entry.id, resolveComponentDir(workspacePath, entry));\n });\n // defines every key as an own property, `__proto__` included\n return Object.fromEntries(dirPerId);\n}\n\n/** an id out of a versioned `.bitmap` is \"scope/name\", or \"name\" for a component never exported */\nfunction nameOfVersionedId(id: string): string {\n return id.split('/').slice(1).join('/') || id;\n}\n\n/**\n * two members the root lists may not share a directory, nor sit one inside another. a `.bitmap` bit\n * wrote holds neither - it refuses a duplicate root-dir, and a component under another component's\n * directory - but this one came from a remote. left to the writer, a collision is relocated and then\n * moved back to the path each component was asked for, so the later one lands on the earlier one's\n * files and the clone comes out missing a component it reported as written.\n */\nexport function throwForOverlappingDirs(dirPerId: Record<string, string>): void {\n const idByDir = new Map<string, string>();\n const refuse = (id: string, otherId: string, dir: string) => {\n throw new BitError(\n `unable to clone, the root component lists \"${id}\" at \"${dir}\", which overlaps the directory it lists \"${otherId}\" at`\n );\n };\n // the question here is which destinations land on one another, not what a path is named, so the\n // comparison is case-folded: on a case-insensitive filesystem \"Packages/Foo\" and \"packages/foo\" are\n // one directory. a workspace whose members differ only by the case of their directories cannot be\n // cloned on macOS or Windows at all, so it is refused everywhere rather than on some platforms -\n // one behaviour, and a message instead of one member's files landing on the other's. the paths\n // themselves are untouched, the writes and the message keep their own spelling\n const sameDir = (dir: string) => dir.toLowerCase();\n Object.entries(dirPerId).forEach(([id, dir]) => {\n const taken = idByDir.get(sameDir(dir));\n if (taken) refuse(id, taken, dir);\n idByDir.set(sameDir(dir), id);\n });\n Object.entries(dirPerId).forEach(([id, dir]) => {\n // every level above it, so a component nested any number of levels inside another is caught\n for (let parent = path.dirname(dir); parent !== path.dirname(parent); parent = path.dirname(parent)) {\n const owner = idByDir.get(sameDir(parent));\n if (owner) refuse(id, owner, dir);\n }\n });\n}\n\n/**\n * where the clone lands: the directory given, or one named after the component, as `git clone` names\n * the working tree after the repository. relative to the cwd, the clone runs outside a workspace.\n */\nexport function resolveClonePath(dir: string | undefined, rootId: ComponentID): string {\n return path.resolve(dir || rootId.name);\n}\n\n/**\n * the destination with the directories above it resolved through any symbolic link, and its own last\n * segment left as it is.\n *\n * a link above the target redirects everything that follows - the directory creation, the init, the\n * files, and the cleanup of a failed clone - while the lexical path says nothing about it, so the\n * workspace check would look in one place and the writes land in another, inside someone else's\n * workspace. the last segment is deliberately not resolved: a link *at* the destination is refused\n * rather than followed, which is ensureEmptyDir's rule.\n */\nexport async function resolveThroughExistingAncestors(dirPath: string): Promise<string> {\n const parent = path.dirname(dirPath);\n if (parent === dirPath) return dirPath;\n return path.join(await realpathOfNearestExisting(parent), path.basename(dirPath));\n}\n\n/**\n * the highest directory on the way to the destination that does not exist yet, or undefined when the\n * destination is already there. what a failed clone removes, so that the levels made on the way to it\n * go too rather than being left standing empty.\n */\nexport async function topmostAbsentDir(dirPath: string): Promise<string | undefined> {\n if (await fs.pathExists(dirPath)) return undefined;\n const parent = path.dirname(dirPath);\n if (parent === dirPath) return dirPath;\n return (await topmostAbsentDir(parent)) || dirPath;\n}\n\n/**\n * the deepest part of the path that exists, resolved, with the part that does not exist yet appended\n * as it is. the destination of a clone is normally absent, so there is nothing to resolve on it.\n */\nasync function realpathOfNearestExisting(dirPath: string): Promise<string> {\n const parent = path.dirname(dirPath);\n if (parent === dirPath) return dirPath;\n try {\n return await fs.realpath(dirPath);\n } catch (err: any) {\n if (err.code !== 'ENOENT') throw err;\n return path.join(await realpathOfNearestExisting(parent), path.basename(dirPath));\n }\n}\n\n/**\n * a clone makes its own workspace. the init below takes the nearest workspace at or above the target\n * instead of making one when there is a workspace above it, and the clone then writes its components\n * into that workspace's `.bitmap` - reporting success while leaving someone else's workspace holding\n * entries for a tree it does not own.\n */\nasync function throwForWorkspaceAbove(workspacePath: string): Promise<void> {\n const workspaceInfo = await getWorkspaceInfo(workspacePath);\n if (!workspaceInfo) return;\n throw new BitError(\n `unable to clone into \"${workspacePath}\", it is inside the workspace at \"${workspaceInfo.path}\".\na clone creates a workspace of its own, run it outside any workspace`\n );\n}\n\n/**\n * the workspace is written into this directory and a failed clone empties it again, so it has to be\n * the directory it appears to be: a symbolic link would put the workspace, and then the cleanup,\n * wherever it points. the same rule the writer applies to the files of a root (see\n * throwForSymlinksInTheWay).\n *\n * @returns whether the directory was created here, so a failed clone knows to remove it\n */\nexport async function ensureEmptyDir(dirPath: string): Promise<boolean> {\n const stat = await lstatIfExists(dirPath);\n if (!stat) {\n await fs.ensureDir(dirPath);\n return true;\n }\n if (stat.isSymbolicLink()) {\n throw new BitError(\n `unable to clone into \"${dirPath}\", it is a symbolic link and the workspace would be written through it`\n );\n }\n if (!stat.isDirectory()) throw new BitError(`unable to clone into \"${dirPath}\", it is not a directory`);\n const entries = await fs.readdir(dirPath);\n if (entries.length) throw new BitError(`unable to clone into \"${dirPath}\", the directory is not empty`);\n return false;\n}\n\nasync function lstatIfExists(dirPath: string): Promise<Stats | undefined> {\n try {\n return await fs.lstat(dirPath);\n } catch (err: any) {\n if (err.code === 'ENOENT') return undefined;\n throw err;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export {};