Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: streamline cache exploration #135

Merged
merged 1 commit into from
Jul 8, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions sources/corepackUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {once} from 'events';
import fs from 'fs';
import type {Dir} from 'fs';
import path from 'path';
import semver from 'semver';

Expand Down Expand Up @@ -45,30 +47,35 @@ export async function fetchAvailableVersions(spec: RegistrySpec): Promise<Array<
export async function findInstalledVersion(installTarget: string, descriptor: Descriptor) {
const installFolder = path.join(installTarget, descriptor.name);

let folderContent: Array<string>;
let cacheDirectory: Dir;
try {
folderContent = await fs.promises.readdir(installFolder);
cacheDirectory = await fs.promises.opendir(installFolder);
} catch (error) {
if ((error as nodeUtils.NodeError).code === `ENOENT`) {
folderContent = [];
return null;
} else {
throw error;
}
}

const candidateVersions: Array<string> = [];
for (const entry of folderContent) {
const range = new semver.Range(descriptor.range);
let bestMatch: string | null = null;
let maxSV: semver.SemVer | undefined = undefined;

for await (const {name} of cacheDirectory) {
// Some dot-folders tend to pop inside directories, especially on OSX
if (entry.startsWith(`.`))
if (name.startsWith(`.`))
continue;

candidateVersions.push(entry);
// If the dirname correspond to an in-range version and is not lower than
// the previous best match (or if there is not yet a previous best match),
// it's our new best match.
if (range.test(name) && maxSV?.compare(name) !== 1) {
bestMatch = name;
maxSV = new semver.SemVer(bestMatch);
}
}

const bestMatch = semver.maxSatisfying(candidateVersions, descriptor.range);
if (bestMatch === null)
return null;

return bestMatch;
}

Expand Down Expand Up @@ -106,9 +113,7 @@ export async function installVersion(installTarget: string, locator: Locator, {s

stream.pipe(sendTo);

await new Promise(resolve => {
sendTo.on(`finish`, resolve);
});
await once(sendTo, `finish`);

await fs.promises.mkdir(path.dirname(installFolder), {recursive: true});
try {
Expand Down