|
| 1 | +import {once} from 'events'; |
1 | 2 | import fs from 'fs';
|
| 3 | +import type {Dir} from 'fs'; |
2 | 4 | import path from 'path';
|
3 | 5 | import semver from 'semver';
|
4 | 6 |
|
@@ -45,30 +47,35 @@ export async function fetchAvailableVersions(spec: RegistrySpec): Promise<Array<
|
45 | 47 | export async function findInstalledVersion(installTarget: string, descriptor: Descriptor) {
|
46 | 48 | const installFolder = path.join(installTarget, descriptor.name);
|
47 | 49 |
|
48 |
| - let folderContent: Array<string>; |
| 50 | + let cacheDirectory: Dir; |
49 | 51 | try {
|
50 |
| - folderContent = await fs.promises.readdir(installFolder); |
| 52 | + cacheDirectory = await fs.promises.opendir(installFolder); |
51 | 53 | } catch (error) {
|
52 | 54 | if ((error as nodeUtils.NodeError).code === `ENOENT`) {
|
53 |
| - folderContent = []; |
| 55 | + return null; |
54 | 56 | } else {
|
55 | 57 | throw error;
|
56 | 58 | }
|
57 | 59 | }
|
58 | 60 |
|
59 |
| - const candidateVersions: Array<string> = []; |
60 |
| - for (const entry of folderContent) { |
| 61 | + const range = new semver.Range(descriptor.range); |
| 62 | + let bestMatch: string | null = null; |
| 63 | + let maxSV: semver.SemVer | undefined = undefined; |
| 64 | + |
| 65 | + for await (const {name} of cacheDirectory) { |
61 | 66 | // Some dot-folders tend to pop inside directories, especially on OSX
|
62 |
| - if (entry.startsWith(`.`)) |
| 67 | + if (name.startsWith(`.`)) |
63 | 68 | continue;
|
64 | 69 |
|
65 |
| - candidateVersions.push(entry); |
| 70 | + // If the dirname correspond to an in-range version and is not lower than |
| 71 | + // the previous best match (or if there is not yet a previous best match), |
| 72 | + // it's our new best match. |
| 73 | + if (range.test(name) && maxSV?.compare(name) !== 1) { |
| 74 | + bestMatch = name; |
| 75 | + maxSV = new semver.SemVer(bestMatch); |
| 76 | + } |
66 | 77 | }
|
67 | 78 |
|
68 |
| - const bestMatch = semver.maxSatisfying(candidateVersions, descriptor.range); |
69 |
| - if (bestMatch === null) |
70 |
| - return null; |
71 |
| - |
72 | 79 | return bestMatch;
|
73 | 80 | }
|
74 | 81 |
|
@@ -106,9 +113,7 @@ export async function installVersion(installTarget: string, locator: Locator, {s
|
106 | 113 |
|
107 | 114 | stream.pipe(sendTo);
|
108 | 115 |
|
109 |
| - await new Promise(resolve => { |
110 |
| - sendTo.on(`finish`, resolve); |
111 |
| - }); |
| 116 | + await once(sendTo, `finish`); |
112 | 117 |
|
113 | 118 | await fs.promises.mkdir(path.dirname(installFolder), {recursive: true});
|
114 | 119 | try {
|
|
0 commit comments