From 7406bf5e76ff06292d3605d9a3884a026ab7fe08 Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Mon, 22 May 2023 10:58:01 +0200 Subject: [PATCH] Changes requests --- dist/cache-save/index.js | 55 ++++++++++++++++++++++++------- dist/setup/index.js | 53 ++++++++++++++++++++++++------ src/cache-save.ts | 3 +- src/cache-utils.ts | 70 ++++++++++++++++++++++++++++------------ 4 files changed, 137 insertions(+), 44 deletions(-) diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js index 6fa2cf89..631e6d47 100644 --- a/dist/cache-save/index.js +++ b/dist/cache-save/index.js @@ -60375,7 +60375,7 @@ const cachePackages = (packageManager) => __awaiter(void 0, void 0, void 0, func core.debug(`Caching for '${packageManager}' is not supported`); return; } - // TODO: core.getInput has a bug - it can return undefined despite its definition + // TODO: core.getInput has a bug - it can return undefined despite its definition (tests only?) // export declare function getInput(name: string, options?: InputOptions): string; const cacheDependencyPath = core.getInput('cache-dependency-path') || ''; const cachePaths = yield cache_utils_1.getCacheDirectoriesPaths(packageManagerInfo, cacheDependencyPath); @@ -60507,6 +60507,10 @@ const getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void } }); exports.getPackageManagerInfo = getPackageManagerInfo; +/** + * glob expanding memoized because it involves potentially very deep + * traversing through the directories tree + */ exports.expandedPatternsMemoized = {}; /** * Wrapper around `glob.create(pattern).glob()` with the memoization @@ -60539,9 +60543,9 @@ const expandCacheDependencyPath = (cacheDependencyPath) => __awaiter(void 0, voi }); exports.expandCacheDependencyPath = expandCacheDependencyPath; /** - * Converts dependency file to the directory it resides in and ensures the directory exists - * @param cacheDependencyPath - file name - * @return either directory containing file or null + * Converts dependency file path to the directory it resides in and ensures the directory exists + * @param cacheDependencyPath - a file name path + * @return either directory containing the file or null */ const cacheDependencyPathToProjectDirectory = (cacheDependencyPath) => { const projectDirectory = path_1.default.dirname(cacheDependencyPath); @@ -60558,7 +60562,8 @@ const cacheDependencyPathToProjectDirectory = (cacheDependencyPath) => { /** * Expands (converts) the string input `cache-dependency-path` to list of directories that * may be project roots - * @param cacheDependencyPath + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` * @return list of directories and possible */ const cacheDependencyPathToProjectsDirectories = (cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { @@ -60566,29 +60571,57 @@ const cacheDependencyPathToProjectsDirectories = (cacheDependencyPath) => __awai const existingDirectories = cacheDependenciesPaths .map(cacheDependencyPath => cacheDependencyPathToProjectDirectory(cacheDependencyPath)) .filter(path => path !== null); + // if user explicitly pointed out some file, but it does not exist it is definitely + // not he wanted, thus we should throw an error not trying to workaround with unexpected + // result to the whole build if (existingDirectories.length === 0) throw Error('No existing directories found containing `cache-dependency-path`="${cacheDependencyPath}"'); - // uniq + // uniq in order to do not traverse the same directories during the further processing return existingDirectories.filter((cachePath, i, result) => cachePath != null && result.indexOf(cachePath) === i); }); +/** + * Utility function to be used from within `map` + * Finds the cache directories configured for the project directory + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param projectDirectory - the string pointing out to a project dir (i.e. directory with its own .yarnrc) + * @return list of directories to be cached according to the project configuration in the directory + */ const projectDirectoryToCacheFolderPath = (packageManagerInfo, projectDirectory) => __awaiter(void 0, void 0, void 0, function* () { const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(projectDirectory); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`); return cacheFolderPath; }); -const projectDirectoriesToCacheFoldersPaths = (packageManagerInfo, projectDirectories) => __awaiter(void 0, void 0, void 0, function* () { - const cacheFoldersPaths = yield Promise.all(projectDirectories.map(projectDirectory => projectDirectoryToCacheFolderPath(packageManagerInfo, projectDirectory))); - return cacheFoldersPaths.filter((cachePath, i, result) => result.indexOf(cachePath) === i); -}); +/** + * Top-entry function to find the cache directories configured for the repo if cache-dependency-path is not empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` + * @return list of files on which the cache depends + */ const cacheDependencyPathToCacheFoldersPaths = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { const projectDirectories = yield cacheDependencyPathToProjectsDirectories(cacheDependencyPath); - return projectDirectoriesToCacheFoldersPaths(packageManagerInfo, projectDirectories); + const cacheFoldersPaths = yield Promise.all(projectDirectories.map(projectDirectory => projectDirectoryToCacheFolderPath(packageManagerInfo, projectDirectory))); + // uniq in order to do not cache the same directories twice + return cacheFoldersPaths.filter((cachePath, i, result) => result.indexOf(cachePath) === i); }); +/** + * Top-entry function to find the cache directories configured for the repo if cache-dependency-path is empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @return list of files on which the cache depends + */ const cacheFoldersPathsForRoot = (packageManagerInfo) => __awaiter(void 0, void 0, void 0, function* () { const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the root directory`); return [cacheFolderPath]; }); +/** + * Main function to find the cache directories configured for the repo + * currently it handles only the case of PM=yarn && cacheDependencyPath is not empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` + * @return list of files on which the cache depends + */ const getCacheDirectoriesPaths = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { // TODO: multiple directories limited to yarn so far return packageManagerInfo === exports.supportedPackageManagers.yarn diff --git a/dist/setup/index.js b/dist/setup/index.js index 57163eb8..23abc160 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -71289,6 +71289,10 @@ const getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void } }); exports.getPackageManagerInfo = getPackageManagerInfo; +/** + * glob expanding memoized because it involves potentially very deep + * traversing through the directories tree + */ exports.expandedPatternsMemoized = {}; /** * Wrapper around `glob.create(pattern).glob()` with the memoization @@ -71321,9 +71325,9 @@ const expandCacheDependencyPath = (cacheDependencyPath) => __awaiter(void 0, voi }); exports.expandCacheDependencyPath = expandCacheDependencyPath; /** - * Converts dependency file to the directory it resides in and ensures the directory exists - * @param cacheDependencyPath - file name - * @return either directory containing file or null + * Converts dependency file path to the directory it resides in and ensures the directory exists + * @param cacheDependencyPath - a file name path + * @return either directory containing the file or null */ const cacheDependencyPathToProjectDirectory = (cacheDependencyPath) => { const projectDirectory = path_1.default.dirname(cacheDependencyPath); @@ -71340,7 +71344,8 @@ const cacheDependencyPathToProjectDirectory = (cacheDependencyPath) => { /** * Expands (converts) the string input `cache-dependency-path` to list of directories that * may be project roots - * @param cacheDependencyPath + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` * @return list of directories and possible */ const cacheDependencyPathToProjectsDirectories = (cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { @@ -71348,29 +71353,57 @@ const cacheDependencyPathToProjectsDirectories = (cacheDependencyPath) => __awai const existingDirectories = cacheDependenciesPaths .map(cacheDependencyPath => cacheDependencyPathToProjectDirectory(cacheDependencyPath)) .filter(path => path !== null); + // if user explicitly pointed out some file, but it does not exist it is definitely + // not he wanted, thus we should throw an error not trying to workaround with unexpected + // result to the whole build if (existingDirectories.length === 0) throw Error('No existing directories found containing `cache-dependency-path`="${cacheDependencyPath}"'); - // uniq + // uniq in order to do not traverse the same directories during the further processing return existingDirectories.filter((cachePath, i, result) => cachePath != null && result.indexOf(cachePath) === i); }); +/** + * Utility function to be used from within `map` + * Finds the cache directories configured for the project directory + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param projectDirectory - the string pointing out to a project dir (i.e. directory with its own .yarnrc) + * @return list of directories to be cached according to the project configuration in the directory + */ const projectDirectoryToCacheFolderPath = (packageManagerInfo, projectDirectory) => __awaiter(void 0, void 0, void 0, function* () { const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(projectDirectory); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`); return cacheFolderPath; }); -const projectDirectoriesToCacheFoldersPaths = (packageManagerInfo, projectDirectories) => __awaiter(void 0, void 0, void 0, function* () { - const cacheFoldersPaths = yield Promise.all(projectDirectories.map(projectDirectory => projectDirectoryToCacheFolderPath(packageManagerInfo, projectDirectory))); - return cacheFoldersPaths.filter((cachePath, i, result) => result.indexOf(cachePath) === i); -}); +/** + * Top-entry function to find the cache directories configured for the repo if cache-dependency-path is not empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` + * @return list of files on which the cache depends + */ const cacheDependencyPathToCacheFoldersPaths = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { const projectDirectories = yield cacheDependencyPathToProjectsDirectories(cacheDependencyPath); - return projectDirectoriesToCacheFoldersPaths(packageManagerInfo, projectDirectories); + const cacheFoldersPaths = yield Promise.all(projectDirectories.map(projectDirectory => projectDirectoryToCacheFolderPath(packageManagerInfo, projectDirectory))); + // uniq in order to do not cache the same directories twice + return cacheFoldersPaths.filter((cachePath, i, result) => result.indexOf(cachePath) === i); }); +/** + * Top-entry function to find the cache directories configured for the repo if cache-dependency-path is empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @return list of files on which the cache depends + */ const cacheFoldersPathsForRoot = (packageManagerInfo) => __awaiter(void 0, void 0, void 0, function* () { const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the root directory`); return [cacheFolderPath]; }); +/** + * Main function to find the cache directories configured for the repo + * currently it handles only the case of PM=yarn && cacheDependencyPath is not empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` + * @return list of files on which the cache depends + */ const getCacheDirectoriesPaths = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { // TODO: multiple directories limited to yarn so far return packageManagerInfo === exports.supportedPackageManagers.yarn diff --git a/src/cache-save.ts b/src/cache-save.ts index 660ec37c..a54a741d 100644 --- a/src/cache-save.ts +++ b/src/cache-save.ts @@ -1,6 +1,5 @@ import * as core from '@actions/core'; import * as cache from '@actions/cache'; -import fs from 'fs'; import {State} from './constants'; import {getCacheDirectoriesPaths, getPackageManagerInfo} from './cache-utils'; @@ -31,7 +30,7 @@ const cachePackages = async (packageManager: string) => { return; } - // TODO: core.getInput has a bug - it can return undefined despite its definition + // TODO: core.getInput has a bug - it can return undefined despite its definition (tests only?) // export declare function getInput(name: string, options?: InputOptions): string; const cacheDependencyPath = core.getInput('cache-dependency-path') || ''; const cachePaths = await getCacheDirectoriesPaths( diff --git a/src/cache-utils.ts b/src/cache-utils.ts index 2c41af60..4fc69717 100644 --- a/src/cache-utils.ts +++ b/src/cache-utils.ts @@ -112,6 +112,11 @@ export const getPackageManagerInfo = async (packageManager: string) => { return null; } }; + +/** + * glob expanding memoized because it involves potentially very deep + * traversing through the directories tree + */ export const expandedPatternsMemoized: Record = {}; /** * Wrapper around `glob.create(pattern).glob()` with the memoization @@ -148,9 +153,9 @@ export const expandCacheDependencyPath = async ( }; /** - * Converts dependency file to the directory it resides in and ensures the directory exists - * @param cacheDependencyPath - file name - * @return either directory containing file or null + * Converts dependency file path to the directory it resides in and ensures the directory exists + * @param cacheDependencyPath - a file name path + * @return either directory containing the file or null */ const cacheDependencyPathToProjectDirectory = ( cacheDependencyPath: string @@ -175,7 +180,8 @@ const cacheDependencyPathToProjectDirectory = ( /** * Expands (converts) the string input `cache-dependency-path` to list of directories that * may be project roots - * @param cacheDependencyPath + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` * @return list of directories and possible */ const cacheDependencyPathToProjectsDirectories = async ( @@ -191,18 +197,28 @@ const cacheDependencyPathToProjectsDirectories = async ( ) .filter(path => path !== null) as string[]; + // if user explicitly pointed out some file, but it does not exist it is definitely + // not he wanted, thus we should throw an error not trying to workaround with unexpected + // result to the whole build if (existingDirectories.length === 0) throw Error( 'No existing directories found containing `cache-dependency-path`="${cacheDependencyPath}"' ); - // uniq + // uniq in order to do not traverse the same directories during the further processing return existingDirectories.filter( (cachePath, i, result) => cachePath != null && result.indexOf(cachePath) === i ); }; +/** + * Utility function to be used from within `map` + * Finds the cache directories configured for the project directory + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param projectDirectory - the string pointing out to a project dir (i.e. directory with its own .yarnrc) + * @return list of directories to be cached according to the project configuration in the directory + */ const projectDirectoryToCacheFolderPath = async ( packageManagerInfo: PackageManagerInfo, projectDirectory: string @@ -216,19 +232,13 @@ const projectDirectoryToCacheFolderPath = async ( return cacheFolderPath; }; -const projectDirectoriesToCacheFoldersPaths = async ( - packageManagerInfo: PackageManagerInfo, - projectDirectories: string[] -): Promise => { - const cacheFoldersPaths = await Promise.all( - projectDirectories.map(projectDirectory => - projectDirectoryToCacheFolderPath(packageManagerInfo, projectDirectory) - ) - ); - return cacheFoldersPaths.filter( - (cachePath, i, result) => result.indexOf(cachePath) === i - ); -}; +/** + * Top-entry function to find the cache directories configured for the repo if cache-dependency-path is not empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` + * @return list of files on which the cache depends + */ const cacheDependencyPathToCacheFoldersPaths = async ( packageManagerInfo: PackageManagerInfo, cacheDependencyPath: string @@ -236,12 +246,22 @@ const cacheDependencyPathToCacheFoldersPaths = async ( const projectDirectories = await cacheDependencyPathToProjectsDirectories( cacheDependencyPath ); - return projectDirectoriesToCacheFoldersPaths( - packageManagerInfo, - projectDirectories + const cacheFoldersPaths = await Promise.all( + projectDirectories.map(projectDirectory => + projectDirectoryToCacheFolderPath(packageManagerInfo, projectDirectory) + ) + ); + // uniq in order to do not cache the same directories twice + return cacheFoldersPaths.filter( + (cachePath, i, result) => result.indexOf(cachePath) === i ); }; +/** + * Top-entry function to find the cache directories configured for the repo if cache-dependency-path is empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @return list of files on which the cache depends + */ const cacheFoldersPathsForRoot = async ( packageManagerInfo: PackageManagerInfo ): Promise => { @@ -252,6 +272,14 @@ const cacheFoldersPathsForRoot = async ( return [cacheFolderPath]; }; +/** + * Main function to find the cache directories configured for the repo + * currently it handles only the case of PM=yarn && cacheDependencyPath is not empty + * @param packageManagerInfo - an object having getCacheFolderPath method specific to given PM + * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns + * expected to be the result of `core.getInput('cache-dependency-path')` + * @return list of files on which the cache depends + */ export const getCacheDirectoriesPaths = async ( packageManagerInfo: PackageManagerInfo, cacheDependencyPath: string