Skip to content

Commit

Permalink
feat!: move getCustomDataKey to Linker (#4505)
Browse files Browse the repository at this point in the history
* feat: move getCustomDataKey to Linker

* fix: bump install state version
  • Loading branch information
jdanil authored Jun 2, 2022
1 parent 4883b3a commit e729e46
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 56 deletions.
34 changes: 34 additions & 0 deletions .yarn/versions/fd50b4cb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
releases:
"@yarnpkg/core": major
"@yarnpkg/plugin-nm": patch
"@yarnpkg/plugin-pnp": patch
"@yarnpkg/plugin-pnpm": patch

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-exec"
- "@yarnpkg/plugin-file"
- "@yarnpkg/plugin-git"
- "@yarnpkg/plugin-github"
- "@yarnpkg/plugin-http"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-link"
- "@yarnpkg/plugin-npm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/cli"
- "@yarnpkg/doctor"
- "@yarnpkg/extensions"
- "@yarnpkg/nm"
- "@yarnpkg/pnpify"
- "@yarnpkg/sdks"
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ The following changes only affect people writing Yarn plugins:

- The `generateLoader` function in `@yarnpkg/pnp` no longer generates the `$$SETUP_STATE` function, it now needs to be present in the `loader` passed to the function.

- The `getCustomDataKey` function in `Installer` from `@yarnpkg/core` has been moved to `Linker`.

### Compatibility

- The patched filesystem now supports `ftruncate`.
Expand Down
14 changes: 7 additions & 7 deletions packages/plugin-nm/sources/NodeModulesLinker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ export enum NodeModulesMode {
export class NodeModulesLinker implements Linker {
private installStateCache: Map<string, Promise<InstallState | null>> = new Map();

getCustomDataKey() {
return JSON.stringify({
name: `NodeModulesLinker`,
version: 2,
});
}

supportsPackage(pkg: Package, opts: MinimalLinkOptions) {
return this.isEnabled(opts);
}
Expand Down Expand Up @@ -119,13 +126,6 @@ class NodeModulesInstaller implements Installer {
// Nothing to do
}

getCustomDataKey() {
return JSON.stringify({
name: `NodeModulesInstaller`,
version: 2,
});
}

private customData: {
store: Map<LocatorHash, CustomPackageData>;
} = {
Expand Down
14 changes: 7 additions & 7 deletions packages/plugin-pnp/sources/PnpLinker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ export class PnpLinker implements Linker {

private pnpCache: Map<string, PnpApi> = new Map();

getCustomDataKey() {
return JSON.stringify({
name: `PnpLinker`,
version: 2,
});
}

supportsPackage(pkg: Package, opts: MinimalLinkOptions) {
return this.isEnabled(opts);
}
Expand Down Expand Up @@ -101,13 +108,6 @@ export class PnpInstaller implements Installer {
this.opts = opts;
}

getCustomDataKey() {
return JSON.stringify({
name: `PnpInstaller`,
version: 2,
});
}

private customData: {
store: Map<LocatorHash, CustomPackageData>;
} = {
Expand Down
26 changes: 11 additions & 15 deletions packages/plugin-pnpm/sources/PnpmLinker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ export type PnpmCustomData = {
};

export class PnpmLinker implements Linker {
getCustomDataKey() {
return JSON.stringify({
name: `PnpmLinker`,
version: 2,
});
}

supportsPackage(pkg: Package, opts: MinimalLinkOptions) {
return this.isEnabled(opts);
}
Expand All @@ -17,8 +24,8 @@ export class PnpmLinker implements Linker {
if (!this.isEnabled(opts))
throw new Error(`Assertion failed: Expected the pnpm linker to be enabled`);

const customDataKey = getCustomDataKey();
const customData = opts.project.installersCustomData.get(customDataKey) as PnpmCustomData | undefined;
const customDataKey = this.getCustomDataKey();
const customData = opts.project.linkersCustomData.get(customDataKey) as PnpmCustomData | undefined;
if (!customData)
throw new UsageError(`The project in ${formatUtils.pretty(opts.project.configuration, `${opts.project.cwd}/package.json`, formatUtils.Type.PATH)} doesn't seem to have been installed - running an install there might help`);

Expand All @@ -33,8 +40,8 @@ export class PnpmLinker implements Linker {
if (!this.isEnabled(opts))
return null;

const customDataKey = getCustomDataKey();
const customData = opts.project.installersCustomData.get(customDataKey) as any;
const customDataKey = this.getCustomDataKey();
const customData = opts.project.linkersCustomData.get(customDataKey) as any;
if (!customData)
throw new UsageError(`The project in ${formatUtils.pretty(opts.project.configuration, `${opts.project.cwd}/package.json`, formatUtils.Type.PATH)} doesn't seem to have been installed - running an install there might help`);

Expand Down Expand Up @@ -77,10 +84,6 @@ class PnpmInstaller implements Installer {
// Nothing to do
}

getCustomDataKey() {
return getCustomDataKey();
}

private customData: PnpmCustomData = {
pathByLocator: new Map(),
locatorByPath: new Map(),
Expand Down Expand Up @@ -286,13 +289,6 @@ class PnpmInstaller implements Installer {
}
}

function getCustomDataKey() {
return JSON.stringify({
name: `PnpmInstaller`,
version: 2,
});
}

function getNodeModulesLocation(project: Project) {
return ppath.join(project.cwd, Filename.nodeModules);
}
Expand Down
12 changes: 0 additions & 12 deletions packages/yarnpkg-core/sources/Installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,6 @@ export type InstallPackageExtraApi = {
};

export interface Installer {
/**
* Return an arbitrary key.
*
* This key will be used to save and restore the installer's custom data. You
* typically will want to return the installer's name, but you can be fancy
* and send a stringified JSON payload that include the cache version, etc.
*
* TODO (Yarn 4): Move this method into `Linker` so that linkers can use it
* to save some state useful to findPackageLocator (cf PnpmLinker).
*/
getCustomDataKey(): string;

/**
* Only called if the installer has a custom data key matching one currently
* stored. Will be called with whatever `finalizeInstall` returned in its
Expand Down
9 changes: 9 additions & 0 deletions packages/yarnpkg-core/sources/Linker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ export interface Linker {
*/
findPackageLocator(location: PortablePath, opts: LinkOptions): Promise<Locator | null>;

/**
* Return an arbitrary key.
*
* This key will be used to save and restore the installer's custom data. You
* typically will want to return the installer's name, but you can be fancy
* and send a stringified JSON payload that include the cache version, etc.
*/
getCustomDataKey(): string;

/**
* This function must instantiate an Installer object that describes how to
* install the packages on the disk. Check the Installer file for more
Expand Down
30 changes: 15 additions & 15 deletions packages/yarnpkg-core/sources/Project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const LOCKFILE_VERSION = 7;
// Same thing but must be bumped when the members of the Project class changes (we
// don't recommend our users to check-in this file, so it's fine to bump it even
// between patch or minor releases).
const INSTALL_STATE_VERSION = 1;
const INSTALL_STATE_VERSION = 2;

const MULTIPLE_KEYS_REGEXP = / *, */g;
const TRAILING_SLASH_REGEXP = /\/$/;
Expand Down Expand Up @@ -138,8 +138,8 @@ export type InstallOptions = {
};

const INSTALL_STATE_FIELDS = {
restoreInstallersCustomData: [
`installersCustomData`,
restoreLinkersCustomData: [
`linkersCustomData`,
] as const,

restoreResolutions: [
Expand Down Expand Up @@ -223,10 +223,10 @@ export class Project {
public peerRequirements: Map<string, PeerRequirement> = new Map();

/**
* Contains whatever data the installers (cf `Linker.ts`) want to persist
* Contains whatever data the linkers (cf `Linker.ts`) want to persist
* from an install to another.
*/
public installersCustomData: Map<string, unknown> = new Map();
public linkersCustomData: Map<string, unknown> = new Map();

/**
* Those checksums are used to detect whether the relevant files actually
Expand Down Expand Up @@ -1048,8 +1048,8 @@ export class Project {
const installers = new Map(linkers.map(linker => {
const installer = linker.makeInstaller(linkerOptions);

const customDataKey = installer.getCustomDataKey();
const customData = this.installersCustomData.get(customDataKey);
const customDataKey = linker.getCustomDataKey();
const customData = this.linkersCustomData.get(customDataKey);
if (typeof customData !== `undefined`)
installer.attachCustomData(customData);

Expand Down Expand Up @@ -1246,9 +1246,9 @@ export class Project {

// Step 3: Inform our linkers that they should have all the info needed

const installersCustomData = new Map();
const linkersCustomData = new Map();

for (const installer of installers.values()) {
for (const [linker, installer] of installers) {
const finalizeInstallData = await installer.finalizeInstall();

for (const installStatus of finalizeInstallData?.records ?? []) {
Expand All @@ -1259,11 +1259,11 @@ export class Project {
}

if (typeof finalizeInstallData?.customData !== `undefined`) {
installersCustomData.set(installer.getCustomDataKey(), finalizeInstallData.customData);
linkersCustomData.set(linker.getCustomDataKey(), finalizeInstallData.customData);
}
}

this.installersCustomData = installersCustomData;
this.linkersCustomData = linkersCustomData;

await miscUtils.allSettledSafe(pendingPromises);

Expand Down Expand Up @@ -1789,7 +1789,7 @@ export class Project {
this.installStateChecksum = newInstallStateChecksum;
}

async restoreInstallState({restoreInstallersCustomData = true, restoreResolutions = true, restoreBuildState = true}: RestoreInstallStateOpts = {}) {
async restoreInstallState({restoreLinkersCustomData = true, restoreResolutions = true, restoreBuildState = true}: RestoreInstallStateOpts = {}) {
const installStatePath = this.configuration.get(`installStatePath`);

let installState: InstallState;
Expand All @@ -1805,9 +1805,9 @@ export class Project {
return;
}

if (restoreInstallersCustomData)
if (typeof installState.installersCustomData !== `undefined`)
this.installersCustomData = installState.installersCustomData;
if (restoreLinkersCustomData)
if (typeof installState.linkersCustomData !== `undefined`)
this.linkersCustomData = installState.linkersCustomData;

if (restoreBuildState)
Object.assign(this, pick(installState, INSTALL_STATE_FIELDS.restoreBuildState));
Expand Down

0 comments on commit e729e46

Please sign in to comment.