submodule-version 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/src/entryStore.d.ts +1 -0
- package/dist/src/entryStore.js +29 -0
- package/dist/src/entryStore.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/entryStore.test.ts +92 -0
- package/src/entryStore.ts +34 -0
package/README.md
CHANGED
|
@@ -111,6 +111,7 @@ The constructor accepts `(projectDir, modulesDir?, { githubToken? })`. The modul
|
|
|
111
111
|
|
|
112
112
|
- `sv.init()` resolves `package.json#sv` with PubGrub and installs/syncs submodules to the resolved versions. It also adds the modules dir to `workspaces` in `package.json` when it is missing, and runs `npm install` when anything changed. All mutations (`put`, `delete`, updates) run `npm install` automatically after applying.
|
|
113
113
|
- `sv.getResolution()` returns the selected version and selected-version dependencies for every resolved module.
|
|
114
|
+
- The working copy of an installed submodule is the source of truth for its checked-out version: dependencies edited locally but not yet published as a tag take part in the resolution immediately. The overlay applies only to the version tag `HEAD` points at, and only when that version exists on the remote — a `HEAD` without a version tag (mid-publish) or a local-only tag falls back to the remote manifest.
|
|
114
115
|
- `new PubGrub(source).resolve(rootDeps)` runs the resolver with a custom entry source, which is useful for tests and non-GitHub registries.
|
|
115
116
|
|
|
116
117
|
### Installing, updating and deleting modules
|
package/dist/src/entryStore.d.ts
CHANGED
package/dist/src/entryStore.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.entryStore = exports.EntryStore = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
4
8
|
const errors_1 = require("./errors");
|
|
5
9
|
const git_1 = require("./git");
|
|
10
|
+
const pkgJSONManager_1 = require("./pkgJSONManager");
|
|
11
|
+
const runOptions_1 = require("./runOptions");
|
|
12
|
+
const versionUtil_1 = require("./versionUtil");
|
|
6
13
|
/*
|
|
7
14
|
* Оверрайды без parent применяются к корню: add добавляет/меняет
|
|
8
15
|
* диапазон по url, delete убирает зависимость по имени модуля.
|
|
@@ -52,12 +59,34 @@ class EntryStore {
|
|
|
52
59
|
this.rememberUrl(name, depUrl);
|
|
53
60
|
return [name, constraint];
|
|
54
61
|
}));
|
|
62
|
+
/*
|
|
63
|
+
* Рабочая копия сабмодуля — источник правды для checkout'нутой версии:
|
|
64
|
+
* зависимости, изменённые локально и ещё не опубликованные тегом,
|
|
65
|
+
* видны резолверу сразу. Применяется только к версии на HEAD (по тегам)
|
|
66
|
+
* и только если такая версия есть в remote-наборе: HEAD без тега
|
|
67
|
+
* (середина publish) или локальный тег вне remote — оверлей пропускается.
|
|
68
|
+
*/
|
|
69
|
+
this.localOverlay = async (name, versions) => {
|
|
70
|
+
if (!runOptions_1.RunOptions.cwd || !runOptions_1.RunOptions.modulesDir)
|
|
71
|
+
return;
|
|
72
|
+
const dir = path_1.default.join(runOptions_1.RunOptions.cwd, runOptions_1.RunOptions.modulesDir, name);
|
|
73
|
+
if (!await git_1.git.local.isGitRepo(dir))
|
|
74
|
+
return;
|
|
75
|
+
const version = versionUtil_1.versionUtil.latest(await git_1.git.local.tagsAtHead(dir));
|
|
76
|
+
if (!version || !versions[version])
|
|
77
|
+
return;
|
|
78
|
+
const pkg = await pkgJSONManager_1.pkgJSONManager.read(name);
|
|
79
|
+
if (!pkg)
|
|
80
|
+
return;
|
|
81
|
+
versions[version] = this.normalizeDependencies(pkg.sv || {});
|
|
82
|
+
};
|
|
55
83
|
this.load = async (url, name) => {
|
|
56
84
|
const fetched = await git_1.git.api.fetchVersions(url);
|
|
57
85
|
const versions = {};
|
|
58
86
|
fetched.forEach(({ version, pkg }) => {
|
|
59
87
|
versions[version] = this.normalizeDependencies(pkg?.sv || {});
|
|
60
88
|
});
|
|
89
|
+
await this.localOverlay(name, versions);
|
|
61
90
|
return { name, url, versions };
|
|
62
91
|
};
|
|
63
92
|
this.resolveIdentity = (depPath) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entryStore.js","sourceRoot":"","sources":["../../src/entryStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entryStore.js","sourceRoot":"","sources":["../../src/entryStore.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { entryStore } from '../entryStore';
|
|
2
2
|
import { git } from '../git';
|
|
3
|
+
import { pkgJSONManager } from '../pkgJSONManager';
|
|
4
|
+
import { RunOptions } from '../runOptions';
|
|
3
5
|
|
|
4
6
|
jest.mock('../git', () => {
|
|
5
7
|
const actual = jest.requireActual('../git');
|
|
@@ -9,11 +11,21 @@ jest.mock('../git', () => {
|
|
|
9
11
|
git: {
|
|
10
12
|
...actual.git,
|
|
11
13
|
api: { fetchVersions: jest.fn() },
|
|
14
|
+
local: {
|
|
15
|
+
...actual.git.local,
|
|
16
|
+
isGitRepo: jest.fn(),
|
|
17
|
+
tagsAtHead: jest.fn(),
|
|
18
|
+
},
|
|
12
19
|
},
|
|
13
20
|
};
|
|
14
21
|
});
|
|
15
22
|
|
|
23
|
+
jest.mock('../pkgJSONManager');
|
|
24
|
+
|
|
16
25
|
const fetchVersionsMock = git.api.fetchVersions as jest.Mock;
|
|
26
|
+
const isGitRepoMock = git.local.isGitRepo as jest.Mock;
|
|
27
|
+
const tagsAtHeadMock = git.local.tagsAtHead as jest.Mock;
|
|
28
|
+
const readPkgMock = pkgJSONManager.read as jest.Mock;
|
|
17
29
|
const url = (name: string) => `git@git:repo/${name}.git`;
|
|
18
30
|
|
|
19
31
|
beforeEach(() => {
|
|
@@ -246,3 +258,83 @@ describe('entryStore.simulate', () => {
|
|
|
246
258
|
expect(cb).not.toHaveBeenCalled();
|
|
247
259
|
});
|
|
248
260
|
});
|
|
261
|
+
|
|
262
|
+
describe('entryStore local overlay', () => {
|
|
263
|
+
beforeEach(() => {
|
|
264
|
+
RunOptions.cwd = '/project';
|
|
265
|
+
RunOptions.modulesDir = 'addons';
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
afterEach(() => {
|
|
269
|
+
RunOptions.cwd = '';
|
|
270
|
+
RunOptions.modulesDir = '';
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('overlays the local manifest on the checked-out version', async () => {
|
|
274
|
+
fetchVersionsMock.mockResolvedValueOnce([
|
|
275
|
+
{ version: '1.0.0', pkg: { sv: { [url('C')]: '^1.0.0' } } },
|
|
276
|
+
{ version: '2.0.0', pkg: { sv: { [url('C')]: '^2.0.0' } } },
|
|
277
|
+
]);
|
|
278
|
+
isGitRepoMock.mockResolvedValueOnce(true);
|
|
279
|
+
tagsAtHeadMock.mockResolvedValueOnce(['1.0.0']);
|
|
280
|
+
readPkgMock.mockResolvedValueOnce({ sv: { [url('B')]: '^0.2.0' } });
|
|
281
|
+
|
|
282
|
+
const entry = await entryStore.fetch(url('A'));
|
|
283
|
+
|
|
284
|
+
expect(entry.versions['1.0.0']).toEqual({ B: '^0.2.0' });
|
|
285
|
+
expect(entry.versions['2.0.0']).toEqual({ C: '^2.0.0' });
|
|
286
|
+
expect(entryStore.urlOf('B')).toBe(url('B'));
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('keeps the remote manifest when HEAD has no version tag', async () => {
|
|
290
|
+
fetchVersionsMock.mockResolvedValueOnce([
|
|
291
|
+
{ version: '1.0.0', pkg: { sv: { [url('C')]: '^1.0.0' } } },
|
|
292
|
+
]);
|
|
293
|
+
isGitRepoMock.mockResolvedValueOnce(true);
|
|
294
|
+
tagsAtHeadMock.mockResolvedValueOnce([]);
|
|
295
|
+
|
|
296
|
+
const entry = await entryStore.fetch(url('A'));
|
|
297
|
+
|
|
298
|
+
expect(entry.versions['1.0.0']).toEqual({ C: '^1.0.0' });
|
|
299
|
+
expect(readPkgMock).not.toHaveBeenCalled();
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('keeps the remote manifest when the module is not installed', async () => {
|
|
303
|
+
fetchVersionsMock.mockResolvedValueOnce([
|
|
304
|
+
{ version: '1.0.0', pkg: { sv: { [url('C')]: '^1.0.0' } } },
|
|
305
|
+
]);
|
|
306
|
+
isGitRepoMock.mockResolvedValueOnce(false);
|
|
307
|
+
|
|
308
|
+
const entry = await entryStore.fetch(url('A'));
|
|
309
|
+
|
|
310
|
+
expect(entry.versions['1.0.0']).toEqual({ C: '^1.0.0' });
|
|
311
|
+
expect(tagsAtHeadMock).not.toHaveBeenCalled();
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
it('skips the overlay when the local tag is not on remote', async () => {
|
|
315
|
+
fetchVersionsMock.mockResolvedValueOnce([
|
|
316
|
+
{ version: '1.0.0', pkg: { sv: { [url('C')]: '^1.0.0' } } },
|
|
317
|
+
]);
|
|
318
|
+
isGitRepoMock.mockResolvedValueOnce(true);
|
|
319
|
+
tagsAtHeadMock.mockResolvedValueOnce(['9.9.9']);
|
|
320
|
+
|
|
321
|
+
const entry = await entryStore.fetch(url('A'));
|
|
322
|
+
|
|
323
|
+
expect(entry.versions['1.0.0']).toEqual({ C: '^1.0.0' });
|
|
324
|
+
expect(entry.versions['9.9.9']).toBeUndefined();
|
|
325
|
+
expect(readPkgMock).not.toHaveBeenCalled();
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('keeps the remote manifest without a local package.json', async () => {
|
|
329
|
+
fetchVersionsMock.mockResolvedValueOnce([
|
|
330
|
+
{ version: '1.0.0', pkg: { sv: { [url('C')]: '^1.0.0' } } },
|
|
331
|
+
]);
|
|
332
|
+
isGitRepoMock.mockResolvedValueOnce(true);
|
|
333
|
+
tagsAtHeadMock.mockResolvedValueOnce(['1.0.0']);
|
|
334
|
+
readPkgMock.mockResolvedValueOnce(null);
|
|
335
|
+
|
|
336
|
+
const entry = await entryStore.fetch(url('A'));
|
|
337
|
+
|
|
338
|
+
expect(entry.versions['1.0.0']).toEqual({ C: '^1.0.0' });
|
|
339
|
+
});
|
|
340
|
+
});
|
package/src/entryStore.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import path from 'path';
|
|
1
2
|
import { SVError } from './errors';
|
|
2
3
|
import { git } from './git';
|
|
4
|
+
import { pkgJSONManager } from './pkgJSONManager';
|
|
5
|
+
import { RunOptions } from './runOptions';
|
|
6
|
+
import { versionUtil } from './versionUtil';
|
|
3
7
|
import type {
|
|
4
8
|
IEntrySource,
|
|
5
9
|
IOverride,
|
|
@@ -80,6 +84,34 @@ export class EntryStore implements IEntrySource {
|
|
|
80
84
|
}),
|
|
81
85
|
);
|
|
82
86
|
|
|
87
|
+
/*
|
|
88
|
+
* Рабочая копия сабмодуля — источник правды для checkout'нутой версии:
|
|
89
|
+
* зависимости, изменённые локально и ещё не опубликованные тегом,
|
|
90
|
+
* видны резолверу сразу. Применяется только к версии на HEAD (по тегам)
|
|
91
|
+
* и только если такая версия есть в remote-наборе: HEAD без тега
|
|
92
|
+
* (середина publish) или локальный тег вне remote — оверлей пропускается.
|
|
93
|
+
*/
|
|
94
|
+
private localOverlay = async (
|
|
95
|
+
name: string,
|
|
96
|
+
versions: Record<string, TDependencies>,
|
|
97
|
+
): Promise<void> => {
|
|
98
|
+
if (!RunOptions.cwd || !RunOptions.modulesDir) return;
|
|
99
|
+
|
|
100
|
+
const dir = path.join(RunOptions.cwd, RunOptions.modulesDir, name);
|
|
101
|
+
|
|
102
|
+
if (!await git.local.isGitRepo(dir)) return;
|
|
103
|
+
|
|
104
|
+
const version = versionUtil.latest(await git.local.tagsAtHead(dir));
|
|
105
|
+
|
|
106
|
+
if (!version || !versions[version]) return;
|
|
107
|
+
|
|
108
|
+
const pkg = await pkgJSONManager.read(name);
|
|
109
|
+
|
|
110
|
+
if (!pkg) return;
|
|
111
|
+
|
|
112
|
+
versions[version] = this.normalizeDependencies(pkg.sv || {});
|
|
113
|
+
};
|
|
114
|
+
|
|
83
115
|
private load = async (url: string, name: string): Promise<IPackageEntry> => {
|
|
84
116
|
const fetched = await git.api.fetchVersions(url);
|
|
85
117
|
const versions: Record<string, TDependencies> = {};
|
|
@@ -88,6 +120,8 @@ export class EntryStore implements IEntrySource {
|
|
|
88
120
|
versions[version] = this.normalizeDependencies(pkg?.sv || {});
|
|
89
121
|
});
|
|
90
122
|
|
|
123
|
+
await this.localOverlay(name, versions);
|
|
124
|
+
|
|
91
125
|
return { name, url, versions };
|
|
92
126
|
};
|
|
93
127
|
|