Skip to content

Commit b2328f1

Browse files
committed
refactor, introduce cacheDependencyPathToProjectsDirectories
it is necessary for the next PR related yarn optimization
1 parent b779602 commit b2328f1

File tree

5 files changed

+293
-81
lines changed

5 files changed

+293
-81
lines changed

__tests__/cache-save.test.ts

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,14 @@ describe('run', () => {
118118
expect(getStateSpy).toHaveBeenCalledTimes(2);
119119
expect(getCommandOutputSpy).toHaveBeenCalledTimes(2);
120120
expect(debugSpy).toHaveBeenCalledWith(
121-
'yarn path is /some/random/path/yarn1 (derived from cache-dependency-path: "")'
121+
'Project directory "." derived from cache-dependency-path: ""'
122+
);
123+
expect(debugSpy).toHaveBeenCalledWith(
124+
'Consumed yarn version is 1.2.3 (working dir: ".")'
125+
);
126+
expect(debugSpy).toHaveBeenCalledWith(
127+
'yarn\'s cache folder "/some/random/path/yarn1" configured for the directory "."'
122128
);
123-
expect(debugSpy).toHaveBeenCalledWith('Consumed yarn version is 1.2.3');
124129
expect(infoSpy).toHaveBeenCalledWith(
125130
`Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.`
126131
);
@@ -140,9 +145,14 @@ describe('run', () => {
140145
expect(getStateSpy).toHaveBeenCalledTimes(2);
141146
expect(getCommandOutputSpy).toHaveBeenCalledTimes(2);
142147
expect(debugSpy).toHaveBeenCalledWith(
143-
'yarn path is /some/random/path/yarn2 (derived from cache-dependency-path: "")'
148+
'Project directory "." derived from cache-dependency-path: ""'
149+
);
150+
expect(debugSpy).toHaveBeenCalledWith(
151+
'Consumed yarn version is 2.2.3 (working dir: ".")'
152+
);
153+
expect(debugSpy).toHaveBeenCalledWith(
154+
'yarn\'s cache folder "/some/random/path/yarn2" configured for the directory "."'
144155
);
145-
expect(debugSpy).toHaveBeenCalledWith('Consumed yarn version is 2.2.3');
146156
expect(infoSpy).toHaveBeenCalledWith(
147157
`Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.`
148158
);
@@ -159,7 +169,9 @@ describe('run', () => {
159169
expect(getInputSpy).toHaveBeenCalled();
160170
expect(getStateSpy).toHaveBeenCalledTimes(2);
161171
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
162-
expect(debugSpy).toHaveBeenCalledWith(`npm path is ${commonPath}/npm`);
172+
expect(debugSpy).toHaveBeenCalledWith(
173+
`npm's cache folder "${commonPath}/npm" configured for the root directory`
174+
);
163175
expect(infoSpy).toHaveBeenCalledWith(
164176
`Cache hit occurred on the primary key ${npmFileHash}, not saving cache.`
165177
);
@@ -176,7 +188,9 @@ describe('run', () => {
176188
expect(getInputSpy).toHaveBeenCalled();
177189
expect(getStateSpy).toHaveBeenCalledTimes(2);
178190
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
179-
expect(debugSpy).toHaveBeenCalledWith(`pnpm path is ${commonPath}/pnpm`);
191+
expect(debugSpy).toHaveBeenCalledWith(
192+
`pnpm's cache folder "${commonPath}/pnpm" configured for the root directory`
193+
);
180194
expect(infoSpy).toHaveBeenCalledWith(
181195
`Cache hit occurred on the primary key ${pnpmFileHash}, not saving cache.`
182196
);
@@ -204,9 +218,14 @@ describe('run', () => {
204218
expect(getStateSpy).toHaveBeenCalledTimes(2);
205219
expect(getCommandOutputSpy).toHaveBeenCalledTimes(2);
206220
expect(debugSpy).toHaveBeenCalledWith(
207-
'yarn path is /some/random/path/yarn1 (derived from cache-dependency-path: "")'
221+
'Project directory "." derived from cache-dependency-path: ""'
222+
);
223+
expect(debugSpy).toHaveBeenCalledWith(
224+
'Consumed yarn version is 1.2.3 (working dir: ".")'
225+
);
226+
expect(debugSpy).toHaveBeenCalledWith(
227+
'yarn\'s cache folder "/some/random/path/yarn1" configured for the directory "."'
208228
);
209-
expect(debugSpy).toHaveBeenCalledWith('Consumed yarn version is 1.2.3');
210229
expect(infoSpy).not.toHaveBeenCalledWith(
211230
`Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.`
212231
);
@@ -236,9 +255,14 @@ describe('run', () => {
236255
expect(getStateSpy).toHaveBeenCalledTimes(2);
237256
expect(getCommandOutputSpy).toHaveBeenCalledTimes(2);
238257
expect(debugSpy).toHaveBeenCalledWith(
239-
'yarn path is /some/random/path/yarn2 (derived from cache-dependency-path: "")'
258+
'Project directory "." derived from cache-dependency-path: ""'
259+
);
260+
expect(debugSpy).toHaveBeenCalledWith(
261+
'Consumed yarn version is 2.2.3 (working dir: ".")'
262+
);
263+
expect(debugSpy).toHaveBeenCalledWith(
264+
'yarn\'s cache folder "/some/random/path/yarn2" configured for the directory "."'
240265
);
241-
expect(debugSpy).toHaveBeenCalledWith('Consumed yarn version is 2.2.3');
242266
expect(infoSpy).not.toHaveBeenCalledWith(
243267
`Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.`
244268
);
@@ -265,7 +289,9 @@ describe('run', () => {
265289
expect(getInputSpy).toHaveBeenCalled();
266290
expect(getStateSpy).toHaveBeenCalledTimes(2);
267291
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
268-
expect(debugSpy).toHaveBeenCalledWith(`npm path is ${commonPath}/npm`);
292+
expect(debugSpy).toHaveBeenCalledWith(
293+
`npm's cache folder "${commonPath}/npm" configured for the root directory`
294+
);
269295
expect(infoSpy).not.toHaveBeenCalledWith(
270296
`Cache hit occurred on the primary key ${npmFileHash}, not saving cache.`
271297
);
@@ -292,7 +318,9 @@ describe('run', () => {
292318
expect(getInputSpy).toHaveBeenCalled();
293319
expect(getStateSpy).toHaveBeenCalledTimes(2);
294320
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
295-
expect(debugSpy).toHaveBeenCalledWith(`pnpm path is ${commonPath}/pnpm`);
321+
expect(debugSpy).toHaveBeenCalledWith(
322+
`pnpm's cache folder "${commonPath}/pnpm" configured for the root directory`
323+
);
296324
expect(infoSpy).not.toHaveBeenCalledWith(
297325
`Cache hit occurred on the primary key ${pnpmFileHash}, not saving cache.`
298326
);
@@ -322,7 +350,9 @@ describe('run', () => {
322350
expect(getInputSpy).toHaveBeenCalled();
323351
expect(getStateSpy).toHaveBeenCalledTimes(2);
324352
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
325-
expect(debugSpy).toHaveBeenCalledWith(`npm path is ${commonPath}/npm`);
353+
expect(debugSpy).toHaveBeenCalledWith(
354+
`npm's cache folder "${commonPath}/npm" configured for the root directory`
355+
);
326356
expect(infoSpy).not.toHaveBeenCalledWith(
327357
`Cache hit occurred on the primary key ${npmFileHash}, not saving cache.`
328358
);
@@ -352,7 +382,9 @@ describe('run', () => {
352382
expect(getInputSpy).toHaveBeenCalled();
353383
expect(getStateSpy).toHaveBeenCalledTimes(2);
354384
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
355-
expect(debugSpy).toHaveBeenCalledWith(`npm path is ${commonPath}/npm`);
385+
expect(debugSpy).toHaveBeenCalledWith(
386+
`npm's cache folder "${commonPath}/npm" configured for the root directory`
387+
);
356388
expect(infoSpy).not.toHaveBeenCalledWith(
357389
`Cache hit occurred on the primary key ${npmFileHash}, not saving cache.`
358390
);

__tests__/cache-utils.test.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
isCacheFeatureAvailable,
88
supportedPackageManagers,
99
getCommandOutput,
10-
expandCacheDependencyPath
10+
expandCacheDependencyPath,
11+
expandedPatternsMemoized
1112
} from '../src/cache-utils';
1213
import fs from 'fs';
1314
import * as cacheUtils from '../src/cache-utils';
@@ -104,6 +105,10 @@ describe('cache-utils', () => {
104105
(pattern: string): Promise<Globber> =>
105106
MockGlobber.create(['/foo', '/bar'])
106107
);
108+
109+
Object.keys(expandedPatternsMemoized).forEach(
110+
key => delete expandedPatternsMemoized[key]
111+
);
107112
});
108113

109114
afterEach(() => {
@@ -194,13 +199,36 @@ two
194199
[supportedPackageManagers.yarn, '/dir/file.lock'],
195200
[supportedPackageManagers.yarn, '/**/file.lock']
196201
])(
197-
'getCacheDirectoriesPaths should return empty array of folder in case of error',
202+
'getCacheDirectoriesPaths should throw for getCommandOutput returning empty',
198203
async (packageManagerInfo, cacheDependency) => {
199204
getCommandOutputSpy.mockImplementation((command: string) =>
200205
// return empty string to indicate getCacheFolderPath failed
201206
// --version still works
202207
command.includes('version') ? '1.' : ''
203208
);
209+
210+
await expect(
211+
cacheUtils.getCacheDirectoriesPaths(
212+
packageManagerInfo,
213+
cacheDependency
214+
)
215+
).rejects.toThrow(); //'Could not get cache folder path for /dir');
216+
}
217+
);
218+
219+
it.each([
220+
[supportedPackageManagers.npm, ''],
221+
[supportedPackageManagers.npm, '/dir/file.lock'],
222+
[supportedPackageManagers.npm, '/**/file.lock'],
223+
[supportedPackageManagers.pnpm, ''],
224+
[supportedPackageManagers.pnpm, '/dir/file.lock'],
225+
[supportedPackageManagers.pnpm, '/**/file.lock'],
226+
[supportedPackageManagers.yarn, ''],
227+
[supportedPackageManagers.yarn, '/dir/file.lock'],
228+
[supportedPackageManagers.yarn, '/**/file.lock']
229+
])(
230+
'getCacheDirectoriesPaths should throw in case of having not directories',
231+
async (packageManagerInfo, cacheDependency) => {
204232
lstatSpy.mockImplementation(arg => ({
205233
isDirectory: () => false
206234
}));
@@ -248,9 +276,8 @@ two
248276
}
249277
);
250278

251-
// TODO: by design - glob is not expected to return duplicates so 3 patterns do not collapse to 2
252279
it.each(['1.1.1', '2.2.2'])(
253-
'getCacheDirectoriesPaths yarn v%s should return 3 dirs with globbed cacheDependency expanding to duplicates',
280+
'getCacheDirectoriesPaths yarn v%s should return 2 dirs with globbed cacheDependency expanding to duplicates',
254281
async version => {
255282
let dirNo = 1;
256283
getCommandOutputSpy.mockImplementation((command: string) =>
@@ -269,11 +296,7 @@ two
269296
supportedPackageManagers.yarn,
270297
'/tmp/**/file'
271298
);
272-
expect(dirs).toEqual([
273-
`file_${version}_1`,
274-
`file_${version}_2`,
275-
`file_${version}_3`
276-
]);
299+
expect(dirs).toEqual([`file_${version}_1`, `file_${version}_2`]);
277300
}
278301
);
279302

dist/cache-save/index.js

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60434,7 +60434,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6043460434
return (mod && mod.__esModule) ? mod : { "default": mod };
6043560435
};
6043660436
Object.defineProperty(exports, "__esModule", ({ value: true }));
60437-
exports.isCacheFeatureAvailable = exports.isGhes = exports.getCacheDirectoriesPaths = exports.expandCacheDependencyPath = exports.getPackageManagerInfo = exports.getCommandOutputGuarded = exports.getCommandOutput = exports.supportedPackageManagers = exports.yarn2GetCacheFolderCommand = exports.yarn1GetCacheFolderCommand = exports.pnpmGetCacheFolderCommand = exports.npmGetCacheFolderCommand = void 0;
60437+
exports.isCacheFeatureAvailable = exports.isGhes = exports.getCacheDirectoriesPaths = exports.expandCacheDependencyPath = exports.expandedPatternsMemoized = exports.getPackageManagerInfo = exports.getCommandOutputGuarded = exports.getCommandOutput = exports.supportedPackageManagers = exports.yarn2GetCacheFolderCommand = exports.yarn1GetCacheFolderCommand = exports.pnpmGetCacheFolderCommand = exports.npmGetCacheFolderCommand = void 0;
6043860438
const core = __importStar(__nccwpck_require__(2186));
6043960439
const exec = __importStar(__nccwpck_require__(1514));
6044060440
const cache = __importStar(__nccwpck_require__(7799));
@@ -60462,7 +60462,7 @@ exports.supportedPackageManagers = {
6046260462
lockFilePatterns: ['yarn.lock'],
6046360463
getCacheFolderPath: (projectDir) => __awaiter(void 0, void 0, void 0, function* () {
6046460464
const yarnVersion = yield exports.getCommandOutputGuarded(`yarn --version`, 'Could not retrieve version of yarn', projectDir);
60465-
core.debug(`Consumed yarn version is ${yarnVersion}`);
60465+
core.debug(`Consumed yarn version is ${yarnVersion} (working dir: "${projectDir}")`);
6046660466
const stdOut = yarnVersion.startsWith('1.')
6046760467
? yield exports.getCommandOutput(exports.yarn1GetCacheFolderCommand, projectDir)
6046860468
: yield exports.getCommandOutput(exports.yarn2GetCacheFolderCommand, projectDir);
@@ -60507,10 +60507,27 @@ const getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void
6050760507
}
6050860508
});
6050960509
exports.getPackageManagerInfo = getPackageManagerInfo;
60510+
exports.expandedPatternsMemoized = {};
60511+
/**
60512+
* Wrapper around `glob.create(pattern).glob()` with the memoization
60513+
* @param pattern is expected to be a globed path
60514+
* @return list of files or directories expanded from glob
60515+
*/
6051060516
const globPatternToArray = (pattern) => __awaiter(void 0, void 0, void 0, function* () {
60517+
const memoized = exports.expandedPatternsMemoized[pattern];
60518+
if (memoized)
60519+
return Promise.resolve(memoized);
6051160520
const globber = yield glob.create(pattern);
60512-
return globber.glob();
60521+
const expanded = yield globber.glob();
60522+
exports.expandedPatternsMemoized[pattern] = expanded;
60523+
return expanded;
6051360524
});
60525+
/**
60526+
* Expands (converts) the string input `cache-dependency-path` to list of files' paths
60527+
* First it breaks the input by new lines and then expand glob patterns if any
60528+
* @param cacheDependencyPath - either a single string or multiline string with possible glob patterns
60529+
* @return list of files on which the cache depends
60530+
*/
6051460531
const expandCacheDependencyPath = (cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
6051560532
const multilinePaths = cacheDependencyPath
6051660533
.split(/\r?\n/)
@@ -60521,26 +60538,55 @@ const expandCacheDependencyPath = (cacheDependencyPath) => __awaiter(void 0, voi
6052160538
return expandedPaths.length === 0 ? [''] : expandedPaths.flat();
6052260539
});
6052360540
exports.expandCacheDependencyPath = expandCacheDependencyPath;
60524-
const cacheDependencyPathToCacheFolderPath = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
60525-
const cacheDependencyPathDirectory = path_1.default.dirname(cacheDependencyPath);
60526-
const cacheFolderPath = fs_1.default.existsSync(cacheDependencyPathDirectory) &&
60527-
fs_1.default.lstatSync(cacheDependencyPathDirectory).isDirectory()
60528-
? yield packageManagerInfo.getCacheFolderPath(cacheDependencyPathDirectory)
60529-
: yield packageManagerInfo.getCacheFolderPath();
60530-
core.debug(`${packageManagerInfo.name} path is ${cacheFolderPath} (derived from cache-dependency-path: "${cacheDependencyPath}")`);
60541+
/**
60542+
* Converts dependency file to the directory it resides in and ensures the directory exists
60543+
* @param cacheDependencyPath - file name
60544+
* @return either directory containing file or null
60545+
*/
60546+
const cacheDependencyPathToProjectDirectory = (cacheDependencyPath) => {
60547+
const projectDirectory = path_1.default.dirname(cacheDependencyPath);
60548+
if (fs_1.default.existsSync(projectDirectory) &&
60549+
fs_1.default.lstatSync(projectDirectory).isDirectory()) {
60550+
core.debug(`Project directory "${projectDirectory}" derived from cache-dependency-path: "${cacheDependencyPath}"`);
60551+
return projectDirectory;
60552+
}
60553+
else {
60554+
core.debug(`No project directory found cache-dependency-path: "${cacheDependencyPath}", root dir assumed`);
60555+
return null;
60556+
}
60557+
};
60558+
/**
60559+
* Expands (converts) the string input `cache-dependency-path` to list of directories that
60560+
* may be project roots
60561+
* @param cacheDependencyPath
60562+
* @return list of directories and possible
60563+
*/
60564+
const cacheDependencyPathToProjectsDirectories = (cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
60565+
const cacheDependenciesPaths = yield exports.expandCacheDependencyPath(cacheDependencyPath);
60566+
const existingDirectories = cacheDependenciesPaths
60567+
.map(cacheDependencyPath => cacheDependencyPathToProjectDirectory(cacheDependencyPath))
60568+
.filter(path => path !== null);
60569+
if (existingDirectories.length === 0)
60570+
throw Error('No existing directories found containing `cache-dependency-path`="${cacheDependencyPath}"');
60571+
// uniq
60572+
return existingDirectories.filter((cachePath, i, result) => cachePath != null && result.indexOf(cachePath) === i);
60573+
});
60574+
const projectDirectoryToCacheFolderPath = (packageManagerInfo, projectDirectory) => __awaiter(void 0, void 0, void 0, function* () {
60575+
const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(projectDirectory);
60576+
core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`);
6053160577
return cacheFolderPath;
6053260578
});
60533-
const cacheDependenciesPathsToCacheFoldersPaths = (packageManagerInfo, cacheDependenciesPaths) => __awaiter(void 0, void 0, void 0, function* () {
60534-
const cacheFoldersPaths = yield Promise.all(cacheDependenciesPaths.map(cacheDependencyPath => cacheDependencyPathToCacheFolderPath(packageManagerInfo, cacheDependencyPath)));
60579+
const projectDirectoriesToCacheFoldersPaths = (packageManagerInfo, projectDirectories) => __awaiter(void 0, void 0, void 0, function* () {
60580+
const cacheFoldersPaths = yield Promise.all(projectDirectories.map(projectDirectory => projectDirectoryToCacheFolderPath(packageManagerInfo, projectDirectory)));
6053560581
return cacheFoldersPaths.filter((cachePath, i, result) => result.indexOf(cachePath) === i);
6053660582
});
6053760583
const cacheDependencyPathToCacheFoldersPaths = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
60538-
const cacheDependenciesPaths = yield exports.expandCacheDependencyPath(cacheDependencyPath);
60539-
return cacheDependenciesPathsToCacheFoldersPaths(packageManagerInfo, cacheDependenciesPaths);
60584+
const projectDirectories = yield cacheDependencyPathToProjectsDirectories(cacheDependencyPath);
60585+
return projectDirectoriesToCacheFoldersPaths(packageManagerInfo, projectDirectories);
6054060586
});
6054160587
const cacheFoldersPathsForRoot = (packageManagerInfo) => __awaiter(void 0, void 0, void 0, function* () {
6054260588
const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath();
60543-
core.debug(`${packageManagerInfo.name} path is ${cacheFolderPath}`);
60589+
core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the root directory`);
6054460590
return [cacheFolderPath];
6054560591
});
6054660592
const getCacheDirectoriesPaths = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy