@yarnpkg/plugin-pnpm 2.0.0-rc.11 → 2.0.0-rc.15
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/lib/PnpmLinker.d.ts +5 -1
- package/lib/PnpmLinker.js +75 -71
- package/package.json +9 -9
package/lib/PnpmLinker.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Descriptor, FetchResult, Installer, InstallPackageExtraApi, Linker, LinkOptions, Locator, LocatorHash, MinimalLinkOptions, Package } from '@yarnpkg/core';
|
|
2
2
|
import { PortablePath } from '@yarnpkg/fslib';
|
|
3
3
|
export declare type PnpmCustomData = {
|
|
4
|
-
pathByLocator: Map<LocatorHash, PortablePath>;
|
|
5
4
|
locatorByPath: Map<PortablePath, string>;
|
|
5
|
+
pathsByLocator: Map<LocatorHash, {
|
|
6
|
+
packageLocation: PortablePath;
|
|
7
|
+
dependenciesLocation: PortablePath | null;
|
|
8
|
+
}>;
|
|
6
9
|
};
|
|
7
10
|
export declare class PnpmLinker implements Linker {
|
|
8
11
|
getCustomDataKey(): string;
|
|
@@ -15,6 +18,7 @@ export declare class PnpmLinker implements Linker {
|
|
|
15
18
|
declare class PnpmInstaller implements Installer {
|
|
16
19
|
private opts;
|
|
17
20
|
private readonly asyncActions;
|
|
21
|
+
private readonly indexFolderPromise;
|
|
18
22
|
constructor(opts: LinkOptions);
|
|
19
23
|
private customData;
|
|
20
24
|
attachCustomData(customData: any): void;
|
package/lib/PnpmLinker.js
CHANGED
|
@@ -9,7 +9,7 @@ class PnpmLinker {
|
|
|
9
9
|
getCustomDataKey() {
|
|
10
10
|
return JSON.stringify({
|
|
11
11
|
name: `PnpmLinker`,
|
|
12
|
-
version:
|
|
12
|
+
version: 3,
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
supportsPackage(pkg, opts) {
|
|
@@ -22,10 +22,10 @@ class PnpmLinker {
|
|
|
22
22
|
const customData = opts.project.linkersCustomData.get(customDataKey);
|
|
23
23
|
if (!customData)
|
|
24
24
|
throw new clipanion_1.UsageError(`The project in ${core_1.formatUtils.pretty(opts.project.configuration, `${opts.project.cwd}/package.json`, core_1.formatUtils.Type.PATH)} doesn't seem to have been installed - running an install there might help`);
|
|
25
|
-
const
|
|
26
|
-
if (typeof
|
|
25
|
+
const packagePaths = customData.pathsByLocator.get(locator.locatorHash);
|
|
26
|
+
if (typeof packagePaths === `undefined`)
|
|
27
27
|
throw new clipanion_1.UsageError(`Couldn't find ${core_1.structUtils.prettyLocator(opts.project.configuration, locator)} in the currently installed pnpm map - running an install might help`);
|
|
28
|
-
return packageLocation;
|
|
28
|
+
return packagePaths.packageLocation;
|
|
29
29
|
}
|
|
30
30
|
async findPackageLocator(location, opts) {
|
|
31
31
|
if (!this.isEnabled(opts))
|
|
@@ -66,10 +66,12 @@ class PnpmInstaller {
|
|
|
66
66
|
this.opts = opts;
|
|
67
67
|
this.asyncActions = new core_1.miscUtils.AsyncActions(10);
|
|
68
68
|
this.customData = {
|
|
69
|
-
|
|
69
|
+
pathsByLocator: new Map(),
|
|
70
70
|
locatorByPath: new Map(),
|
|
71
71
|
};
|
|
72
|
-
|
|
72
|
+
this.indexFolderPromise = (0, fslib_1.setupCopyIndex)(fslib_1.xfs, {
|
|
73
|
+
indexPath: fslib_1.ppath.join(opts.project.configuration.get(`globalFolder`), `index`),
|
|
74
|
+
});
|
|
73
75
|
}
|
|
74
76
|
attachCustomData(customData) {
|
|
75
77
|
// We don't want to attach the data because it's only used in the Linker and we'll recompute it anyways in the Installer,
|
|
@@ -83,25 +85,37 @@ class PnpmInstaller {
|
|
|
83
85
|
throw new Error(`Assertion failed: Unsupported package link type`);
|
|
84
86
|
}
|
|
85
87
|
async installPackageSoft(pkg, fetchResult, api) {
|
|
86
|
-
const
|
|
87
|
-
this.
|
|
88
|
+
const packageLocation = fslib_1.ppath.resolve(fetchResult.packageFs.getRealPath(), fetchResult.prefixPath);
|
|
89
|
+
const dependenciesLocation = this.opts.project.tryWorkspaceByLocator(pkg)
|
|
90
|
+
? fslib_1.ppath.join(packageLocation, fslib_1.Filename.nodeModules)
|
|
91
|
+
: null;
|
|
92
|
+
this.customData.pathsByLocator.set(pkg.locatorHash, {
|
|
93
|
+
packageLocation,
|
|
94
|
+
dependenciesLocation,
|
|
95
|
+
});
|
|
88
96
|
return {
|
|
89
|
-
packageLocation
|
|
97
|
+
packageLocation,
|
|
90
98
|
buildDirective: null,
|
|
91
99
|
};
|
|
92
100
|
}
|
|
93
101
|
async installPackageHard(pkg, fetchResult, api) {
|
|
94
102
|
var _a;
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
this.customData.
|
|
103
|
+
const packagePaths = getPackagePaths(pkg, { project: this.opts.project });
|
|
104
|
+
const packageLocation = packagePaths.packageLocation;
|
|
105
|
+
this.customData.locatorByPath.set(packageLocation, core_1.structUtils.stringifyLocator(pkg));
|
|
106
|
+
this.customData.pathsByLocator.set(pkg.locatorHash, packagePaths);
|
|
98
107
|
api.holdFetchResult(this.asyncActions.set(pkg.locatorHash, async () => {
|
|
99
|
-
await fslib_1.xfs.mkdirPromise(
|
|
108
|
+
await fslib_1.xfs.mkdirPromise(packageLocation, { recursive: true });
|
|
100
109
|
// Copy the package source into the <root>/n_m/.store/<hash> directory, so
|
|
101
110
|
// that we can then create symbolic links to it later.
|
|
102
|
-
await fslib_1.xfs.copyPromise(
|
|
111
|
+
await fslib_1.xfs.copyPromise(packageLocation, fetchResult.prefixPath, {
|
|
103
112
|
baseFs: fetchResult.packageFs,
|
|
104
113
|
overwrite: false,
|
|
114
|
+
linkStrategy: {
|
|
115
|
+
type: `HardlinkFromIndex`,
|
|
116
|
+
indexPath: await this.indexFolderPromise,
|
|
117
|
+
autoRepair: true,
|
|
118
|
+
},
|
|
105
119
|
});
|
|
106
120
|
}));
|
|
107
121
|
const isVirtual = core_1.structUtils.isVirtualLocator(pkg);
|
|
@@ -115,7 +129,7 @@ class PnpmInstaller {
|
|
|
115
129
|
const dependencyMeta = this.opts.project.getDependencyMeta(devirtualizedLocator, pkg.version);
|
|
116
130
|
const buildScripts = plugin_pnp_1.jsInstallUtils.extractBuildScripts(pkg, buildConfig, dependencyMeta, { configuration: this.opts.project.configuration, report: this.opts.report });
|
|
117
131
|
return {
|
|
118
|
-
packageLocation
|
|
132
|
+
packageLocation,
|
|
119
133
|
buildDirective: buildScripts,
|
|
120
134
|
};
|
|
121
135
|
}
|
|
@@ -125,31 +139,33 @@ class PnpmInstaller {
|
|
|
125
139
|
// We don't install those packages at all, because they can't be used anyway
|
|
126
140
|
if (!isPnpmVirtualCompatible(locator, { project: this.opts.project }))
|
|
127
141
|
return;
|
|
142
|
+
const packagePaths = this.customData.pathsByLocator.get(locator.locatorHash);
|
|
143
|
+
if (typeof packagePaths === `undefined`)
|
|
144
|
+
throw new Error(`Assertion failed: Expected the package to have been registered (${core_1.structUtils.stringifyLocator(locator)})`);
|
|
145
|
+
const { dependenciesLocation, } = packagePaths;
|
|
146
|
+
if (!dependenciesLocation)
|
|
147
|
+
return;
|
|
128
148
|
this.asyncActions.reduce(locator.locatorHash, async (action) => {
|
|
129
|
-
|
|
130
|
-
await action;
|
|
131
|
-
const pkgPath = this.customData.pathByLocator.get(locator.locatorHash);
|
|
132
|
-
if (typeof pkgPath === `undefined`)
|
|
133
|
-
throw new Error(`Assertion failed: Expected the package to have been registered (${core_1.structUtils.stringifyLocator(locator)})`);
|
|
134
|
-
const nmPath = fslib_1.ppath.join(pkgPath, fslib_1.Filename.nodeModules);
|
|
135
|
-
const concurrentPromises = [];
|
|
149
|
+
await fslib_1.xfs.mkdirPromise(dependenciesLocation, { recursive: true });
|
|
136
150
|
// Retrieve what's currently inside the package's true nm folder. We
|
|
137
151
|
// will use that to figure out what are the extraneous entries we'll
|
|
138
152
|
// need to remove.
|
|
139
|
-
const
|
|
140
|
-
|
|
153
|
+
const initialEntries = await getNodeModulesListing(dependenciesLocation);
|
|
154
|
+
const extraneous = new Map(initialEntries);
|
|
155
|
+
const concurrentPromises = [action];
|
|
156
|
+
const installDependency = (descriptor, dependency) => {
|
|
141
157
|
// Downgrade virtual workspaces (cf isPnpmVirtualCompatible's documentation)
|
|
142
158
|
let targetDependency = dependency;
|
|
143
159
|
if (!isPnpmVirtualCompatible(dependency, { project: this.opts.project })) {
|
|
144
|
-
this.opts.report.
|
|
160
|
+
this.opts.report.reportWarningOnce(core_1.MessageName.UNNAMED, `The pnpm linker doesn't support providing different versions to workspaces' peer dependencies`);
|
|
145
161
|
targetDependency = core_1.structUtils.devirtualizeLocator(dependency);
|
|
146
162
|
}
|
|
147
|
-
const
|
|
148
|
-
if (typeof
|
|
163
|
+
const depSrcPaths = this.customData.pathsByLocator.get(targetDependency.locatorHash);
|
|
164
|
+
if (typeof depSrcPaths === `undefined`)
|
|
149
165
|
throw new Error(`Assertion failed: Expected the package to have been registered (${core_1.structUtils.stringifyLocator(dependency)})`);
|
|
150
166
|
const name = core_1.structUtils.stringifyIdent(descriptor);
|
|
151
|
-
const depDstPath = fslib_1.ppath.join(
|
|
152
|
-
const depLinkPath = fslib_1.ppath.relative(fslib_1.ppath.dirname(depDstPath),
|
|
167
|
+
const depDstPath = fslib_1.ppath.join(dependenciesLocation, name);
|
|
168
|
+
const depLinkPath = fslib_1.ppath.relative(fslib_1.ppath.dirname(depDstPath), depSrcPaths.packageLocation);
|
|
153
169
|
const existing = extraneous.get(name);
|
|
154
170
|
extraneous.delete(name);
|
|
155
171
|
concurrentPromises.push(Promise.resolve().then(async () => {
|
|
@@ -164,14 +180,22 @@ class PnpmInstaller {
|
|
|
164
180
|
}
|
|
165
181
|
await fslib_1.xfs.mkdirpPromise(fslib_1.ppath.dirname(depDstPath));
|
|
166
182
|
if (process.platform == `win32`) {
|
|
167
|
-
await fslib_1.xfs.symlinkPromise(
|
|
183
|
+
await fslib_1.xfs.symlinkPromise(depSrcPaths.packageLocation, depDstPath, `junction`);
|
|
168
184
|
}
|
|
169
185
|
else {
|
|
170
186
|
await fslib_1.xfs.symlinkPromise(depLinkPath, depDstPath);
|
|
171
187
|
}
|
|
172
188
|
}));
|
|
189
|
+
};
|
|
190
|
+
let hasExplicitSelfDependency = false;
|
|
191
|
+
for (const [descriptor, dependency] of dependencies) {
|
|
192
|
+
if (descriptor.identHash === locator.identHash)
|
|
193
|
+
hasExplicitSelfDependency = true;
|
|
194
|
+
installDependency(descriptor, dependency);
|
|
173
195
|
}
|
|
174
|
-
|
|
196
|
+
if (!hasExplicitSelfDependency && !this.opts.project.tryWorkspaceByLocator(locator))
|
|
197
|
+
installDependency(core_1.structUtils.convertLocatorToDescriptor(locator), locator);
|
|
198
|
+
concurrentPromises.push(cleanNodeModules(dependenciesLocation, extraneous));
|
|
175
199
|
await Promise.all(concurrentPromises);
|
|
176
200
|
});
|
|
177
201
|
}
|
|
@@ -184,46 +208,25 @@ class PnpmInstaller {
|
|
|
184
208
|
await fslib_1.xfs.removePromise(storeLocation);
|
|
185
209
|
}
|
|
186
210
|
else {
|
|
187
|
-
|
|
188
|
-
const expectedEntries = new Set();
|
|
189
|
-
for (const packageLocation of this.customData.pathByLocator.values()) {
|
|
190
|
-
const subpath = fslib_1.ppath.contains(storeLocation, packageLocation);
|
|
191
|
-
if (subpath !== null) {
|
|
192
|
-
const [storeEntry, /* Filename.nodeModules */ , ...identComponents] = subpath.split(fslib_1.ppath.sep);
|
|
193
|
-
expectedEntries.add(storeEntry);
|
|
194
|
-
const storeEntryPath = fslib_1.ppath.join(storeLocation, storeEntry);
|
|
195
|
-
removals.push(fslib_1.xfs.readdirPromise(storeEntryPath)
|
|
196
|
-
.then(entries => {
|
|
197
|
-
return Promise.all(entries.map(async (entry) => {
|
|
198
|
-
const p = fslib_1.ppath.join(storeEntryPath, entry);
|
|
199
|
-
if (entry === fslib_1.Filename.nodeModules) {
|
|
200
|
-
const extraneous = await getNodeModulesListing(p);
|
|
201
|
-
extraneous.delete(identComponents.join(fslib_1.ppath.sep));
|
|
202
|
-
return cleanNodeModules(p, extraneous);
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
return fslib_1.xfs.removePromise(p);
|
|
206
|
-
}
|
|
207
|
-
}));
|
|
208
|
-
})
|
|
209
|
-
.catch(error => {
|
|
210
|
-
if (error.code !== `ENOENT`) {
|
|
211
|
-
throw error;
|
|
212
|
-
}
|
|
213
|
-
}));
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
let storeRecords;
|
|
211
|
+
let extraneous;
|
|
217
212
|
try {
|
|
218
|
-
|
|
213
|
+
extraneous = new Set(await fslib_1.xfs.readdirPromise(storeLocation));
|
|
219
214
|
}
|
|
220
215
|
catch {
|
|
221
|
-
|
|
216
|
+
extraneous = new Set();
|
|
217
|
+
}
|
|
218
|
+
for (const { dependenciesLocation } of this.customData.pathsByLocator.values()) {
|
|
219
|
+
if (!dependenciesLocation)
|
|
220
|
+
continue;
|
|
221
|
+
const subpath = fslib_1.ppath.contains(storeLocation, dependenciesLocation);
|
|
222
|
+
if (subpath === null)
|
|
223
|
+
continue;
|
|
224
|
+
const [storeEntry] = subpath.split(fslib_1.ppath.sep);
|
|
225
|
+
extraneous.delete(storeEntry);
|
|
222
226
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
await Promise.all(removals);
|
|
227
|
+
await Promise.all([...extraneous].map(async (extraneousEntry) => {
|
|
228
|
+
await fslib_1.xfs.removePromise(fslib_1.ppath.join(storeLocation, extraneousEntry));
|
|
229
|
+
}));
|
|
227
230
|
}
|
|
228
231
|
// Wait for the package installs to catch up
|
|
229
232
|
await this.asyncActions.wait();
|
|
@@ -241,11 +244,12 @@ function getNodeModulesLocation(project) {
|
|
|
241
244
|
function getStoreLocation(project) {
|
|
242
245
|
return fslib_1.ppath.join(getNodeModulesLocation(project), `.store`);
|
|
243
246
|
}
|
|
244
|
-
function
|
|
247
|
+
function getPackagePaths(locator, { project }) {
|
|
245
248
|
const pkgKey = core_1.structUtils.slugifyLocator(locator);
|
|
246
|
-
const
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
+
const storeLocation = getStoreLocation(project);
|
|
250
|
+
const packageLocation = fslib_1.ppath.join(storeLocation, pkgKey, `package`);
|
|
251
|
+
const dependenciesLocation = fslib_1.ppath.join(storeLocation, pkgKey, fslib_1.Filename.nodeModules);
|
|
252
|
+
return { packageLocation, dependenciesLocation };
|
|
249
253
|
}
|
|
250
254
|
function isPnpmVirtualCompatible(locator, { project }) {
|
|
251
255
|
// The pnpm install strategy has a limitation: because Node would always
|
package/package.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yarnpkg/plugin-pnpm",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.15",
|
|
4
4
|
"license": "BSD-2-Clause",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@yarnpkg/fslib": "^3.0.0-rc.
|
|
8
|
-
"@yarnpkg/plugin-pnp": "^4.0.0-rc.
|
|
9
|
-
"@yarnpkg/plugin-stage": "^4.0.0-rc.
|
|
7
|
+
"@yarnpkg/fslib": "^3.0.0-rc.15",
|
|
8
|
+
"@yarnpkg/plugin-pnp": "^4.0.0-rc.15",
|
|
9
|
+
"@yarnpkg/plugin-stage": "^4.0.0-rc.15",
|
|
10
10
|
"clipanion": "^3.2.0-rc.10",
|
|
11
11
|
"p-limit": "^2.2.0",
|
|
12
|
-
"tslib": "^
|
|
12
|
+
"tslib": "^2.4.0"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@yarnpkg/cli": "^4.0.0-rc.
|
|
16
|
-
"@yarnpkg/core": "^4.0.0-rc.
|
|
15
|
+
"@yarnpkg/cli": "^4.0.0-rc.15",
|
|
16
|
+
"@yarnpkg/core": "^4.0.0-rc.15"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@yarnpkg/cli": "^4.0.0-rc.
|
|
20
|
-
"@yarnpkg/core": "^4.0.0-rc.
|
|
19
|
+
"@yarnpkg/cli": "^4.0.0-rc.15",
|
|
20
|
+
"@yarnpkg/core": "^4.0.0-rc.15"
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|