From b68f05c8bb0161029ff4d1280eadfee490ab7155 Mon Sep 17 00:00:00 2001 From: Dmitry Shibanov Date: Fri, 17 Sep 2021 10:17:17 +0300 Subject: [PATCH] rebuild all code --- action.yml | 2 + dist/cache-save/index.js | 205 ++++++++++------ dist/setup/index.js | 183 +++++++++++---- src/cache-distributions/cache-distributor.ts | 56 ++--- src/cache-distributions/cache-factory.ts | 42 +++- src/cache-distributions/pip-cache.ts | 48 +++- src/cache-distributions/pipenv-cache.ts | 15 +- src/cache-save.ts | 4 +- src/cache.ts | 234 ++++++++++++------- src/setup-python.ts | 15 +- src/utils.ts | 13 ++ 11 files changed, 550 insertions(+), 267 deletions(-) diff --git a/action.yml b/action.yml index 6ac4bfff..7b8bd9f5 100644 --- a/action.yml +++ b/action.yml @@ -14,6 +14,8 @@ inputs: token: description: Used to pull python distributions from actions/python-versions. Since there's a default, this is typically not supplied by the user. default: ${{ github.token }} + cache-dependency-path: + description: 'Used to specify the path to a dependency files. Supports wildcards or a list of file names for caching multiple dependencies.' outputs: python-version: description: "The installed python version. Useful when given a version range as input." diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js index 517d1e16..d5dfaa1b 100644 --- a/dist/cache-save/index.js +++ b/dist/cache-save/index.js @@ -1748,7 +1748,7 @@ class HttpClient { if (useProxy) { // If using proxy, need tunnel if (!tunnel) { - tunnel = __webpack_require__(413); + tunnel = __webpack_require__(856); } const agentOptions = { maxSockets: maxSockets, @@ -4602,7 +4602,7 @@ function isSpanContext(spanContext) { /* 152 */ /***/ (function(module, __unusedexports, __webpack_require__) { -var Stream = __webpack_require__(794).Stream; +var Stream = __webpack_require__(413).Stream; var util = __webpack_require__(669); module.exports = DelayedStream; @@ -5383,22 +5383,27 @@ Object.defineProperty(exports, "__esModule", { value: true }); const glob = __importStar(__webpack_require__(281)); const cache_distributor_1 = __importDefault(__webpack_require__(435)); class PipenvCache extends cache_distributor_1.default { - constructor(pythonVersion) { + constructor(cacheManager) { super({ patterns: ['Pipfile.lock'], toolName: 'pipenv' }); - this.pythonVersion = pythonVersion; + this.cacheManager = cacheManager; } - getCacheGlobalDirectory() { + getCacheGlobalDirectories() { return __awaiter(this, void 0, void 0, function* () { return ['~/.local/share/virtualenvs']; }); } - computePrimaryKey() { + computeKeys() { return __awaiter(this, void 0, void 0, function* () { const hash = yield glob.hashFiles('Pipfile.lock'); - return `setup-python-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-pipenv-${hash}`; + const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.cacheManager.pythonVersion}-${this.packageManager.toolName}-${hash}`; + const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.cacheManager.pythonVersion}-${this.packageManager.toolName}`; + return { + primaryKey, + restoreKey + }; }); } } @@ -5634,7 +5639,7 @@ const http_client_1 = __webpack_require__(22); const storage_blob_1 = __webpack_require__(373); const buffer = __importStar(__webpack_require__(293)); const fs = __importStar(__webpack_require__(747)); -const stream = __importStar(__webpack_require__(794)); +const stream = __importStar(__webpack_require__(413)); const util = __importStar(__webpack_require__(669)); const utils = __importStar(__webpack_require__(15)); const constants_1 = __webpack_require__(931); @@ -8614,7 +8619,7 @@ var logger$1 = __webpack_require__(928); var abortController = __webpack_require__(106); var os = __webpack_require__(87); var crypto = __webpack_require__(417); -var stream = __webpack_require__(794); +var stream = __webpack_require__(413); __webpack_require__(510); var coreLro = __webpack_require__(889); var events = __webpack_require__(614); @@ -34091,17 +34096,62 @@ exports.PrefixSecurityEnum = PrefixSecurityEnum; "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); +const glob = __importStar(__webpack_require__(281)); +const core = __importStar(__webpack_require__(470)); +const exec = __importStar(__webpack_require__(986)); +const path = __importStar(__webpack_require__(622)); +const os = __importStar(__webpack_require__(87)); const cache_distributor_1 = __importDefault(__webpack_require__(435)); class PipCache extends cache_distributor_1.default { - constructor() { + constructor(info) { super({ - command: 'pip cache dir', - patterns: ['**/requirements.txt'], - toolName: 'pip' + patterns: info.patterns.length == 0 ? ['**/requirements.txt'] : info.patterns, + toolName: info.toolName + }); + } + getCacheGlobalDirectories() { + return __awaiter(this, void 0, void 0, function* () { + const { stdout, stderr, exitCode } = yield exec.getExecOutput('pip cache dir'); + if (stderr) { + throw new Error(`failed to procceed with caching with error: ${exitCode}`); + } + let resolvedPath = stdout.trim(); + if (resolvedPath.includes('~')) { + resolvedPath = path.join(os.homedir(), resolvedPath.slice(1)); + } + core.info(`global cache directory path is ${resolvedPath}`); + return [resolvedPath]; + }); + } + computeKeys() { + return __awaiter(this, void 0, void 0, function* () { + const hash = yield glob.hashFiles(this.packageManager.patterns.join('\n')); + const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-${hash}`; + const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-`; + return { + primaryKey, + restoreKey + }; }); } } @@ -34188,10 +34238,9 @@ exports.ProxyTracer = ProxyTracer; /* 411 */, /* 412 */, /* 413 */ -/***/ (function(module, __unusedexports, __webpack_require__) { - -module.exports = __webpack_require__(141); +/***/ (function(module) { +module.exports = require("stream"); /***/ }), /* 414 */, @@ -35031,13 +35080,9 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -const exec = __importStar(__webpack_require__(986)); const cache = __importStar(__webpack_require__(692)); -const glob = __importStar(__webpack_require__(281)); const core = __importStar(__webpack_require__(470)); const fs = __importStar(__webpack_require__(747)); -const path = __importStar(__webpack_require__(622)); -const os = __importStar(__webpack_require__(87)); class CacheDistributor { constructor(packageManager) { this.packageManager = packageManager; @@ -35045,27 +35090,6 @@ class CacheDistributor { this.STATE_CACHE_PRIMARY_KEY = 'cache-primary-key'; this.CACHE_MATCHED_KEY = 'cache-matched-key'; } - getCacheGlobalDirectory() { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const { stdout, stderr, exitCode } = yield exec.getExecOutput((_a = this.packageManager.command) !== null && _a !== void 0 ? _a : ''); - if (stderr) { - throw new Error(`failed to procceed with caching with error: ${exitCode}`); - } - let resolvedPath = stdout.trim(); - if (resolvedPath.includes('~')) { - resolvedPath = path.join(os.homedir(), resolvedPath.slice(1)); - } - core.info(`global cache directory path is ${resolvedPath}`); - return [resolvedPath]; - }); - } - computePrimaryKey() { - return __awaiter(this, void 0, void 0, function* () { - const hash = yield glob.hashFiles(this.packageManager.patterns.join('\n')); - return `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-${hash}`; - }); - } isCacheDirectoryExists(cacheDirectory) { const result = cacheDirectory.reduce((previousValue, currentValue) => { return previousValue || fs.existsSync(currentValue); @@ -35074,7 +35098,7 @@ class CacheDistributor { } saveCache() { return __awaiter(this, void 0, void 0, function* () { - const cachePath = yield this.getCacheGlobalDirectory(); + const cachePath = yield this.getCacheGlobalDirectories(); if (!this.isCacheDirectoryExists(cachePath)) { throw new Error('No one cache directory exists'); } @@ -35106,15 +35130,15 @@ class CacheDistributor { } restoreCache() { return __awaiter(this, void 0, void 0, function* () { - const primaryKey = yield this.computePrimaryKey(); - const cachePath = yield this.getCacheGlobalDirectory(); + const { primaryKey, restoreKey } = yield this.computeKeys(); + const cachePath = yield this.getCacheGlobalDirectories(); core.saveState(this.STATE_CACHE_PRIMARY_KEY, primaryKey); if (primaryKey.endsWith('-')) { throw new Error(`No file in ${process.cwd()} matched to [${this.packageManager.patterns}], make sure you have checked out the target repository`); } const matchedKey = yield cache.restoreCache(cachePath, primaryKey, [ - `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}` - ]); + restoreKey + ]); // `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}` if (matchedKey) { core.saveState(this.CACHE_MATCHED_KEY, matchedKey); core.info(`Cache restored from key: ${matchedKey}`); @@ -35402,7 +35426,7 @@ Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var Stream = _interopDefault(__webpack_require__(794)); +var Stream = _interopDefault(__webpack_require__(413)); var http = _interopDefault(__webpack_require__(605)); var Url = _interopDefault(__webpack_require__(835)); var https = _interopDefault(__webpack_require__(211)); @@ -38501,7 +38525,7 @@ var DiagLogLevel; /***/ (function(module, __unusedexports, __webpack_require__) { var util = __webpack_require__(669); -var Stream = __webpack_require__(794).Stream; +var Stream = __webpack_require__(413).Stream; var DelayedStream = __webpack_require__(152); module.exports = CombinedStream; @@ -40392,6 +40416,15 @@ module.exports = require("net"); "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -40403,15 +40436,46 @@ var Caches; Caches["Pip"] = "pip"; Caches["Pipenv"] = "pipenv"; })(Caches = exports.Caches || (exports.Caches = {})); -function getCache(cacheType, pythonVersion) { - switch (cacheType) { - case Caches.Pip: - return new pip_cache_1.default(); - case Caches.Pipenv: - return new pipenv_cache_1.default(pythonVersion); - default: - throw new Error('No cache distributor'); +exports.supportedPackageManagers = { + pip: { + patterns: ['**/requirements.txt'], + toolName: 'pip' + }, + pipenv: { + patterns: ['pnpm-lock.yaml'], + toolName: 'pipenv' } +}; +exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void 0, function* () { + if (packageManager === 'pip') { + return exports.supportedPackageManagers.pip; + } + else if (packageManager === 'pipenv') { + return exports.supportedPackageManagers.pipenv; + } + else { + throw new Error('package manager is not supported'); + } +}); +function getCache(cacheManager) { + return __awaiter(this, void 0, void 0, function* () { + const info = yield exports.getPackageManagerInfo(cacheManager.toolName); + if (!info) { + throw new Error('No cache distributor'); + } + info.pythonVersion = cacheManager.pythonVersion; + if (cacheManager.patterns.length) { + info.patterns = cacheManager.patterns; + } + switch (cacheManager.toolName) { + case Caches.Pip: + return new pip_cache_1.default(info); + case Caches.Pipenv: + return new pipenv_cache_1.default(info); + default: + throw new Error('No cache distributor'); + } + }); } exports.getCache = getCache; @@ -40988,7 +41052,7 @@ var __createBinding; var Stream try { - Stream = __webpack_require__(794).Stream + Stream = __webpack_require__(413).Stream } catch (ex) { Stream = function () {} } @@ -44406,7 +44470,7 @@ exports.hashFiles = void 0; const crypto = __importStar(__webpack_require__(417)); const core = __importStar(__webpack_require__(470)); const fs = __importStar(__webpack_require__(747)); -const stream = __importStar(__webpack_require__(794)); +const stream = __importStar(__webpack_require__(413)); const util = __importStar(__webpack_require__(669)); const path = __importStar(__webpack_require__(622)); function hashFiles(globber) { @@ -45956,7 +46020,7 @@ var http = __webpack_require__(605); var https = __webpack_require__(211); var parseUrl = __webpack_require__(835).parse; var fs = __webpack_require__(747); -var Stream = __webpack_require__(794).Stream; +var Stream = __webpack_require__(413).Stream; var mime = __webpack_require__(779); var asynckit = __webpack_require__(334); var populate = __webpack_require__(766); @@ -46533,12 +46597,7 @@ FormData.prototype.toString = function () { /***/ }), /* 792 */, /* 793 */, -/* 794 */ -/***/ (function(module) { - -module.exports = require("stream"); - -/***/ }), +/* 794 */, /* 795 */, /* 796 */ /***/ (function(__unusedmodule, exports, __webpack_require__) { @@ -46569,8 +46628,8 @@ function cacheSave() { try { const cache = core.getInput('cache'); if (cache) { - const cacheManager = cache_factory_1.getCache(cache, ''); - cacheManager.saveCache(); + const cacheManager = yield cache_factory_1.getCache({ toolName: cache, patterns: [] }); + yield cacheManager.saveCache(); } } catch (error) { @@ -46856,7 +46915,13 @@ var _default = stringify; exports.default = _default; /***/ }), -/* 856 */, +/* 856 */ +/***/ (function(module, __unusedexports, __webpack_require__) { + +module.exports = __webpack_require__(141); + + +/***/ }), /* 857 */ /***/ (function(__unusedmodule, exports, __webpack_require__) { @@ -52560,9 +52625,9 @@ var abortController = __webpack_require__(106); var FormData = _interopDefault(__webpack_require__(790)); var util = __webpack_require__(669); var url = __webpack_require__(835); -var stream = __webpack_require__(794); +var stream = __webpack_require__(413); var logger$1 = __webpack_require__(928); -var tunnel = __webpack_require__(413); +var tunnel = __webpack_require__(856); var tslib = __webpack_require__(865); var coreAuth = __webpack_require__(229); var xml2js = __webpack_require__(992); diff --git a/dist/setup/index.js b/dist/setup/index.js index b25535d0..2a2c6a90 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -6007,9 +6007,6 @@ exports.NoopTracerProvider = NoopTracerProvider; "use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; @@ -6017,7 +6014,11 @@ var __importStar = (this && this.__importStar) || function (mod) { result["default"] = mod; return result; }; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(__webpack_require__(470)); const fs_1 = __importDefault(__webpack_require__(747)); const path = __importStar(__webpack_require__(622)); const semver = __importStar(__webpack_require__(876)); @@ -6086,6 +6087,14 @@ function validatePythonVersionFormatForPyPy(version) { return re.test(version); } exports.validatePythonVersionFormatForPyPy = validatePythonVersionFormatForPyPy; +function getInputAsArray(name, options) { + return core + .getInput(name, options) + .split('\n') + .map(s => s.trim()) + .filter(x => x !== ''); +} +exports.getInputAsArray = getInputAsArray; /***/ }), @@ -6454,6 +6463,7 @@ const finderPyPy = __importStar(__webpack_require__(50)); const path = __importStar(__webpack_require__(622)); const os = __importStar(__webpack_require__(87)); const cache_factory_1 = __webpack_require__(633); +const utils_1 = __webpack_require__(163); function isPyPyVersion(versionSpec) { return versionSpec.startsWith('pypy-'); } @@ -6475,8 +6485,14 @@ function run() { core.info(`Successfully setup ${installed.impl} (${installed.version})`); } const cache = core.getInput('cache'); + const patterns = utils_1.getInputAsArray('cache-dependency-path'); if (cache) { - const cacheDistributor = cache_factory_1.getCache(cache, pythonVersion); + const packageManager = cache_factory_1.getPackageManagerInfo(cache); + const cacheDistributor = yield cache_factory_1.getCache({ + toolName: cache, + patterns: patterns, + pythonVersion: pythonVersion + }); cacheDistributor.restoreCache(); } } @@ -6935,22 +6951,27 @@ Object.defineProperty(exports, "__esModule", { value: true }); const glob = __importStar(__webpack_require__(281)); const cache_distributor_1 = __importDefault(__webpack_require__(435)); class PipenvCache extends cache_distributor_1.default { - constructor(pythonVersion) { + constructor(cacheManager) { super({ patterns: ['Pipfile.lock'], toolName: 'pipenv' }); - this.pythonVersion = pythonVersion; + this.cacheManager = cacheManager; } - getCacheGlobalDirectory() { + getCacheGlobalDirectories() { return __awaiter(this, void 0, void 0, function* () { return ['~/.local/share/virtualenvs']; }); } - computePrimaryKey() { + computeKeys() { return __awaiter(this, void 0, void 0, function* () { const hash = yield glob.hashFiles('Pipfile.lock'); - return `setup-python-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-pipenv-${hash}`; + const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.cacheManager.pythonVersion}-${this.packageManager.toolName}-${hash}`; + const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.cacheManager.pythonVersion}-${this.packageManager.toolName}`; + return { + primaryKey, + restoreKey + }; }); } } @@ -35860,17 +35881,62 @@ exports.PrefixSecurityEnum = PrefixSecurityEnum; "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); +const glob = __importStar(__webpack_require__(281)); +const core = __importStar(__webpack_require__(470)); +const exec = __importStar(__webpack_require__(986)); +const path = __importStar(__webpack_require__(622)); +const os = __importStar(__webpack_require__(87)); const cache_distributor_1 = __importDefault(__webpack_require__(435)); class PipCache extends cache_distributor_1.default { - constructor() { + constructor(info) { super({ - command: 'pip cache dir', - patterns: ['**/requirements.txt'], - toolName: 'pip' + patterns: info.patterns.length == 0 ? ['**/requirements.txt'] : info.patterns, + toolName: info.toolName + }); + } + getCacheGlobalDirectories() { + return __awaiter(this, void 0, void 0, function* () { + const { stdout, stderr, exitCode } = yield exec.getExecOutput('pip cache dir'); + if (stderr) { + throw new Error(`failed to procceed with caching with error: ${exitCode}`); + } + let resolvedPath = stdout.trim(); + if (resolvedPath.includes('~')) { + resolvedPath = path.join(os.homedir(), resolvedPath.slice(1)); + } + core.info(`global cache directory path is ${resolvedPath}`); + return [resolvedPath]; + }); + } + computeKeys() { + return __awaiter(this, void 0, void 0, function* () { + const hash = yield glob.hashFiles(this.packageManager.patterns.join('\n')); + const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-${hash}`; + const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-`; + return { + primaryKey, + restoreKey + }; }); } } @@ -36800,13 +36866,9 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -const exec = __importStar(__webpack_require__(986)); const cache = __importStar(__webpack_require__(692)); -const glob = __importStar(__webpack_require__(281)); const core = __importStar(__webpack_require__(470)); const fs = __importStar(__webpack_require__(747)); -const path = __importStar(__webpack_require__(622)); -const os = __importStar(__webpack_require__(87)); class CacheDistributor { constructor(packageManager) { this.packageManager = packageManager; @@ -36814,27 +36876,6 @@ class CacheDistributor { this.STATE_CACHE_PRIMARY_KEY = 'cache-primary-key'; this.CACHE_MATCHED_KEY = 'cache-matched-key'; } - getCacheGlobalDirectory() { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const { stdout, stderr, exitCode } = yield exec.getExecOutput((_a = this.packageManager.command) !== null && _a !== void 0 ? _a : ''); - if (stderr) { - throw new Error(`failed to procceed with caching with error: ${exitCode}`); - } - let resolvedPath = stdout.trim(); - if (resolvedPath.includes('~')) { - resolvedPath = path.join(os.homedir(), resolvedPath.slice(1)); - } - core.info(`global cache directory path is ${resolvedPath}`); - return [resolvedPath]; - }); - } - computePrimaryKey() { - return __awaiter(this, void 0, void 0, function* () { - const hash = yield glob.hashFiles(this.packageManager.patterns.join('\n')); - return `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-${hash}`; - }); - } isCacheDirectoryExists(cacheDirectory) { const result = cacheDirectory.reduce((previousValue, currentValue) => { return previousValue || fs.existsSync(currentValue); @@ -36843,7 +36884,7 @@ class CacheDistributor { } saveCache() { return __awaiter(this, void 0, void 0, function* () { - const cachePath = yield this.getCacheGlobalDirectory(); + const cachePath = yield this.getCacheGlobalDirectories(); if (!this.isCacheDirectoryExists(cachePath)) { throw new Error('No one cache directory exists'); } @@ -36875,15 +36916,15 @@ class CacheDistributor { } restoreCache() { return __awaiter(this, void 0, void 0, function* () { - const primaryKey = yield this.computePrimaryKey(); - const cachePath = yield this.getCacheGlobalDirectory(); + const { primaryKey, restoreKey } = yield this.computeKeys(); + const cachePath = yield this.getCacheGlobalDirectories(); core.saveState(this.STATE_CACHE_PRIMARY_KEY, primaryKey); if (primaryKey.endsWith('-')) { throw new Error(`No file in ${process.cwd()} matched to [${this.packageManager.patterns}], make sure you have checked out the target repository`); } const matchedKey = yield cache.restoreCache(cachePath, primaryKey, [ - `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}` - ]); + restoreKey + ]); // `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}` if (matchedKey) { core.saveState(this.CACHE_MATCHED_KEY, matchedKey); core.info(`Cache restored from key: ${matchedKey}`); @@ -45268,6 +45309,15 @@ module.exports = require("net"); "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -45279,15 +45329,46 @@ var Caches; Caches["Pip"] = "pip"; Caches["Pipenv"] = "pipenv"; })(Caches = exports.Caches || (exports.Caches = {})); -function getCache(cacheType, pythonVersion) { - switch (cacheType) { - case Caches.Pip: - return new pip_cache_1.default(); - case Caches.Pipenv: - return new pipenv_cache_1.default(pythonVersion); - default: - throw new Error('No cache distributor'); +exports.supportedPackageManagers = { + pip: { + patterns: ['**/requirements.txt'], + toolName: 'pip' + }, + pipenv: { + patterns: ['pnpm-lock.yaml'], + toolName: 'pipenv' } +}; +exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void 0, function* () { + if (packageManager === 'pip') { + return exports.supportedPackageManagers.pip; + } + else if (packageManager === 'pipenv') { + return exports.supportedPackageManagers.pipenv; + } + else { + throw new Error('package manager is not supported'); + } +}); +function getCache(cacheManager) { + return __awaiter(this, void 0, void 0, function* () { + const info = yield exports.getPackageManagerInfo(cacheManager.toolName); + if (!info) { + throw new Error('No cache distributor'); + } + info.pythonVersion = cacheManager.pythonVersion; + if (cacheManager.patterns.length) { + info.patterns = cacheManager.patterns; + } + switch (cacheManager.toolName) { + case Caches.Pip: + return new pip_cache_1.default(info); + case Caches.Pipenv: + return new pipenv_cache_1.default(info); + default: + throw new Error('No cache distributor'); + } + }); } exports.getCache = getCache; diff --git a/src/cache-distributions/cache-distributor.ts b/src/cache-distributions/cache-distributor.ts index eb70f278..46c2b146 100644 --- a/src/cache-distributions/cache-distributor.ts +++ b/src/cache-distributions/cache-distributor.ts @@ -1,49 +1,29 @@ -import * as exec from '@actions/exec'; import * as cache from '@actions/cache'; -import * as glob from '@actions/glob'; import * as core from '@actions/core'; import * as fs from 'fs'; -import * as path from 'path'; -import * as os from 'os'; -interface PackageManager { - command?: string; +export interface IPackageManager { patterns: string[]; toolName: string; + pythonVersion?: string; + key_prefix?: string; + cacheFolder?: string[]; + command?: string; + isPythonVersionAdded?: boolean; } abstract class CacheDistributor { - private CACHE_KEY_PREFIX = 'setup-python'; + protected CACHE_KEY_PREFIX = 'setup-python'; private STATE_CACHE_PRIMARY_KEY = 'cache-primary-key'; private CACHE_MATCHED_KEY = 'cache-matched-key'; - constructor(private packageManager: PackageManager) {} + constructor(protected packageManager: IPackageManager) {} - protected async getCacheGlobalDirectory() { - const {stdout, stderr, exitCode} = await exec.getExecOutput( - this.packageManager.command ?? '' - ); - if (stderr) { - throw new Error( - `failed to procceed with caching with error: ${exitCode}` - ); - } - - let resolvedPath = stdout.trim(); - - if (resolvedPath.includes('~')) { - resolvedPath = path.join(os.homedir(), resolvedPath.slice(1)); - } - - core.info(`global cache directory path is ${resolvedPath}`); - - return [resolvedPath]; - } - - protected async computePrimaryKey() { - const hash = await glob.hashFiles(this.packageManager.patterns.join('\n')); - return `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-${hash}`; - } + protected abstract getCacheGlobalDirectories(): Promise; + protected abstract computeKeys(): Promise<{ + primaryKey: string; + restoreKey: string; + }>; protected isCacheDirectoryExists(cacheDirectory: string[]) { const result = cacheDirectory.reduce((previousValue, currentValue) => { @@ -54,7 +34,7 @@ abstract class CacheDistributor { } public async saveCache() { - const cachePath = await this.getCacheGlobalDirectory(); + const cachePath = await this.getCacheGlobalDirectories(); if (!this.isCacheDirectoryExists(cachePath)) { throw new Error('No one cache directory exists'); } @@ -85,8 +65,8 @@ abstract class CacheDistributor { } public async restoreCache() { - const primaryKey = await this.computePrimaryKey(); - const cachePath = await this.getCacheGlobalDirectory(); + const {primaryKey, restoreKey} = await this.computeKeys(); + const cachePath = await this.getCacheGlobalDirectories(); core.saveState(this.STATE_CACHE_PRIMARY_KEY, primaryKey); if (primaryKey.endsWith('-')) { throw new Error( @@ -97,8 +77,8 @@ abstract class CacheDistributor { } const matchedKey = await cache.restoreCache(cachePath, primaryKey, [ - `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}` - ]); + restoreKey + ]); // `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}` if (matchedKey) { core.saveState(this.CACHE_MATCHED_KEY, matchedKey); core.info(`Cache restored from key: ${matchedKey}`); diff --git a/src/cache-distributions/cache-factory.ts b/src/cache-distributions/cache-factory.ts index 1bb84a4e..3301528f 100644 --- a/src/cache-distributions/cache-factory.ts +++ b/src/cache-distributions/cache-factory.ts @@ -1,3 +1,4 @@ +import {IPackageManager} from './cache-distributor'; import PipCache from './pip-cache'; import PipenvCache from './pipenv-cache'; @@ -6,12 +7,45 @@ export enum Caches { Pipenv = 'pipenv' } -export function getCache(cacheType: string, pythonVersion: string) { - switch (cacheType) { +type SupportedPackageManagers = { + [prop: string]: IPackageManager; +}; + +export const supportedPackageManagers: SupportedPackageManagers = { + pip: { + patterns: ['**/requirements.txt'], + toolName: 'pip' + }, + pipenv: { + patterns: ['pnpm-lock.yaml'], + toolName: 'pipenv' + } +}; + +export const getPackageManagerInfo = async (packageManager: string) => { + if (packageManager === 'pip') { + return supportedPackageManagers.pip; + } else if (packageManager === 'pipenv') { + return supportedPackageManagers.pipenv; + } else { + throw new Error('package manager is not supported'); + } +}; + +export async function getCache(cacheManager: IPackageManager) { + const info = await getPackageManagerInfo(cacheManager.toolName); + if (!info) { + throw new Error('No cache distributor'); + } + info.pythonVersion = cacheManager.pythonVersion; + if (cacheManager.patterns.length) { + info.patterns = cacheManager.patterns; + } + switch (cacheManager.toolName) { case Caches.Pip: - return new PipCache(); + return new PipCache(info); case Caches.Pipenv: - return new PipenvCache(pythonVersion); + return new PipenvCache(info); default: throw new Error('No cache distributor'); } diff --git a/src/cache-distributions/pip-cache.ts b/src/cache-distributions/pip-cache.ts index 255b8060..d411348d 100644 --- a/src/cache-distributions/pip-cache.ts +++ b/src/cache-distributions/pip-cache.ts @@ -1,13 +1,51 @@ -import CacheDistributor from './cache-distributor'; +import * as glob from '@actions/glob'; +import * as core from '@actions/core'; +import * as exec from '@actions/exec'; + +import * as path from 'path'; +import * as os from 'os'; + +import CacheDistributor, {IPackageManager} from './cache-distributor'; class PipCache extends CacheDistributor { - constructor() { + constructor(info: IPackageManager) { super({ - command: 'pip cache dir', - patterns: ['**/requirements.txt'], - toolName: 'pip' + patterns: + info.patterns.length == 0 ? ['**/requirements.txt'] : info.patterns, + toolName: info.toolName }); } + + protected async getCacheGlobalDirectories() { + const {stdout, stderr, exitCode} = await exec.getExecOutput( + 'pip cache dir' + ); + if (stderr) { + throw new Error( + `failed to procceed with caching with error: ${exitCode}` + ); + } + + let resolvedPath = stdout.trim(); + + if (resolvedPath.includes('~')) { + resolvedPath = path.join(os.homedir(), resolvedPath.slice(1)); + } + + core.info(`global cache directory path is ${resolvedPath}`); + + return [resolvedPath]; + } + + protected async computeKeys() { + const hash = await glob.hashFiles(this.packageManager.patterns.join('\n')); + const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-${hash}`; + const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}-`; + return { + primaryKey, + restoreKey + }; + } } export default PipCache; diff --git a/src/cache-distributions/pipenv-cache.ts b/src/cache-distributions/pipenv-cache.ts index cb8aa1a9..ebf55a8c 100644 --- a/src/cache-distributions/pipenv-cache.ts +++ b/src/cache-distributions/pipenv-cache.ts @@ -1,22 +1,27 @@ import * as glob from '@actions/glob'; -import CacheDistributor from './cache-distributor'; +import CacheDistributor, {IPackageManager} from './cache-distributor'; class PipenvCache extends CacheDistributor { - constructor(private pythonVersion: string) { + constructor(private cacheManager: IPackageManager) { super({ patterns: ['Pipfile.lock'], toolName: 'pipenv' }); } - protected async getCacheGlobalDirectory() { + protected async getCacheGlobalDirectories() { return ['~/.local/share/virtualenvs']; } - protected async computePrimaryKey() { + protected async computeKeys() { const hash = await glob.hashFiles('Pipfile.lock'); - return `setup-python-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-pipenv-${hash}`; + const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.cacheManager.pythonVersion}-${this.packageManager.toolName}-${hash}`; + const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.cacheManager.pythonVersion}-${this.packageManager.toolName}`; + return { + primaryKey, + restoreKey + }; } } diff --git a/src/cache-save.ts b/src/cache-save.ts index f6ceef88..eed05947 100644 --- a/src/cache-save.ts +++ b/src/cache-save.ts @@ -5,8 +5,8 @@ export async function cacheSave() { try { const cache = core.getInput('cache'); if (cache) { - const cacheManager = getCache(cache, ''); - cacheManager.saveCache(); + const cacheManager = await getCache({toolName: cache, patterns: []}); + await cacheManager.saveCache(); } } catch (error) { const err = error as Error; diff --git a/src/cache.ts b/src/cache.ts index c9480d96..dd683a7e 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -1,99 +1,153 @@ -// import * as core from '@actions/core'; -// import * as cache from '@actions/cache'; -// import * as exec from '@actions/exec'; -// import * as glob from '@actions/glob'; +import * as core from '@actions/core'; +import * as glob from '@actions/glob'; +import * as cache from '@actions/cache'; +import * as exec from '@actions/exec'; -// const CACHE_KEY_PREFIX = 'setup-python'; -// const STATE_CACHE_PRIMARY_KEY = 'cache-primary-key'; -// const CACHE_MATCHED_KEY = 'cache-matched-key'; +import * as path from 'path'; +import * as fs from 'fs'; +import * as os from 'os'; +import {IPackageManager} from './cache-distributions/cache-distributor'; -// interface ICacheManagers { -// path?: string[]; -// command?: string; -// toolName: string; -// keyPrefix: string; -// patterns: string[]; -// dependencyFiles: string[]; -// cacheKeyPrefix?: string; -// } +const CACHE_KEY_PREFIX = 'setup-python'; +const STATE_CACHE_PRIMARY_KEY = 'cache-primary-key'; +const CACHE_MATCHED_KEY = 'cache-matched-key'; -// async function getCacheGlobalDirectory(packageManager: ICacheManagers) { -// if (!packageManager.command || !packageManager.path) { -// throw new Error( -// 'You should specify command to get global cache or if it does not exists set path manual' -// ); -// } -// if (!packageManager.command) { -// return packageManager.path; -// } -// const {stdout, stderr, exitCode} = await exec.getExecOutput( -// packageManager.command ?? '' -// ); -// if (stderr) { -// throw new Error(`failed to procceed with caching with error: ${exitCode}`); -// } +type SupportedPackageManagers = { + [prop: string]: IPackageManager; +}; -// return [stdout]; -// } +const supportedPackageManagers: SupportedPackageManagers = { + pip: { + patterns: ['**/requirements.txt'], + toolName: 'pip', + command: 'pip cache dir', + key_prefix: `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-` + }, + pipenv: { + patterns: ['pnpm-lock.yaml'], + toolName: 'pipenv', + cacheFolder: ['~/.local/share/virtualenvs'], + key_prefix: `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-` + } +}; -// export async function saveCache(packageManager: ICacheManagers) { -// const cachePath = await getCacheGlobalDirectory(packageManager); -// const primaryKey = core.getState(STATE_CACHE_PRIMARY_KEY); -// const matchedKey = core.getState(CACHE_MATCHED_KEY); +export const getPackageManagerInfo = async (packageManager: string) => { + if (packageManager === 'pip') { + return supportedPackageManagers.pip; + } else if (packageManager === 'pipenv') { + return supportedPackageManagers.pipenv; + } else { + return null; + } +}; -// if (!primaryKey) { -// core.warning('Error retrieving key from state.'); -// return; -// } else if (matchedKey === primaryKey) { -// // no change in target directories -// core.info( -// `Cache hit occurred on the primary key ${primaryKey}, not saving cache.` -// ); -// return; -// } -// try { -// await cache.saveCache(cachePath, primaryKey); -// core.info(`Cache saved with the key: ${primaryKey}`); -// } catch (error) { -// const err = error as Error; -// if (err.name === cache.ReserveCacheError.name) { -// core.info(err.message); -// } else { -// throw error; -// } -// } -// } +async function getCacheGlobalDirectories(packageManager: IPackageManager) { + if (!packageManager.cacheFolder || !packageManager.command) { + throw new Error('please provide command or cachefilder path'); + } -// export async function restoreCache(packageManager: ICacheManagers) { -// const primaryKey = await computePrimaryKey( -// packageManager, -// packageManager.keyPrefix -// ); -// const cachePath = await getCacheGlobalDirectory(packageManager); -// core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); -// if (primaryKey.endsWith('-')) { -// throw new Error( -// `No file in ${process.cwd()} matched to [${ -// packageManager.patterns -// }], make sure you have checked out the target repository` -// ); -// } + if (!packageManager.command) { + return packageManager.cacheFolder!; + } + const {stdout, stderr, exitCode} = await exec.getExecOutput( + packageManager.command + ); + if (stderr) { + throw new Error(`failed to procceed with caching with error: ${exitCode}`); + } -// const matchedKey = await cache.restoreCache(cachePath, primaryKey, [ -// `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${packageManager.toolName}` -// ]); -// if (matchedKey) { -// core.saveState(CACHE_MATCHED_KEY, matchedKey); -// core.info(`Cache restored from key: ${matchedKey}`); -// } else { -// core.info(`${packageManager.toolName} cache is not found`); -// } -// } + let resolvedPath = stdout.trim(); -// async function computePrimaryKey( -// packageManager: ICacheManagers, -// cacheKeyPrefix = `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}` -// ) { -// const hash = await glob.hashFiles(packageManager.patterns.join('\n')); -// return `${cacheKeyPrefix}-${packageManager.toolName}-${hash}`; -// } + if (resolvedPath.includes('~')) { + resolvedPath = path.join(os.homedir(), resolvedPath.slice(1)); + } + + core.info(`global cache directory path is ${resolvedPath}`); + + return [resolvedPath]; +} + +async function computeKeys( + packageManager: IPackageManager, + pythonVersion?: string +) { + const hash = await glob.hashFiles(packageManager.patterns.join('\n')); + let version = ''; + if (!pythonVersion) { + version = `${pythonVersion}-`; + } + const primaryKey = `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${version}${packageManager.toolName}-${hash}`; + const restoreKey = `${CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${version}${packageManager.toolName}-`; + return { + primaryKey, + restoreKey + }; +} + +function isCacheDirectoryExists(cacheDirectory: string[]) { + const result = cacheDirectory.reduce((previousValue, currentValue) => { + return previousValue || fs.existsSync(currentValue); + }, false); + + return result; +} + +export async function saveCache(packageManager: IPackageManager) { + const cachePath = await getCacheGlobalDirectories(packageManager); + if (!isCacheDirectoryExists(cachePath)) { + throw new Error('No one cache directory exists'); + } + const primaryKey = core.getState(STATE_CACHE_PRIMARY_KEY); + const matchedKey = core.getState(CACHE_MATCHED_KEY); + + if (!primaryKey) { + core.warning('Error retrieving key from state.'); + return; + } else if (matchedKey === primaryKey) { + // no change in target directories + core.info( + `Cache hit occurred on the primary key ${primaryKey}, not saving cache.` + ); + return; + } + try { + await cache.saveCache(cachePath, primaryKey); + core.info(`Cache saved with the key: ${primaryKey}`); + } catch (error) { + const err = error as Error; + if (err.name === cache.ReserveCacheError.name) { + core.info(err.message); + } else { + throw error; + } + } +} + +export async function restoreCache( + packageManager: IPackageManager, + pythonVersion?: string +) { + const {primaryKey, restoreKey} = await computeKeys( + packageManager, + pythonVersion + ); + const cachePath = await getCacheGlobalDirectories(packageManager); + core.saveState(STATE_CACHE_PRIMARY_KEY, primaryKey); + if (primaryKey.endsWith('-')) { + throw new Error( + `No file in ${process.cwd()} matched to [${ + packageManager.patterns + }], make sure you have checked out the target repository` + ); + } + + const matchedKey = await cache.restoreCache(cachePath, primaryKey, [ + restoreKey + ]); // `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager.toolName}` + if (matchedKey) { + core.saveState(CACHE_MATCHED_KEY, matchedKey); + core.info(`Cache restored from key: ${matchedKey}`); + } else { + core.info(`${packageManager.toolName} cache is not found`); + } +} diff --git a/src/setup-python.ts b/src/setup-python.ts index 26320f85..02fb8c81 100644 --- a/src/setup-python.ts +++ b/src/setup-python.ts @@ -3,7 +3,11 @@ import * as finder from './find-python'; import * as finderPyPy from './find-pypy'; import * as path from 'path'; import * as os from 'os'; -import {getCache} from './cache-distributions/cache-factory'; +import { + getCache, + getPackageManagerInfo +} from './cache-distributions/cache-factory'; +import {getInputAsArray} from './utils'; function isPyPyVersion(versionSpec: string) { return versionSpec.startsWith('pypy-'); @@ -30,8 +34,15 @@ async function run() { } const cache = core.getInput('cache'); + const patterns = getInputAsArray('cache-dependency-path'); if (cache) { - const cacheDistributor = getCache(cache, pythonVersion); + const packageManager = getPackageManagerInfo(cache); + + const cacheDistributor = await getCache({ + toolName: cache, + patterns: patterns, + pythonVersion: pythonVersion + }); cacheDistributor.restoreCache(); } } diff --git a/src/utils.ts b/src/utils.ts index c15fe3d0..75f689c3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,5 @@ +import * as core from '@actions/core'; + import fs from 'fs'; import * as path from 'path'; import * as semver from 'semver'; @@ -92,3 +94,14 @@ export function validatePythonVersionFormatForPyPy(version: string) { const re = /^\d+\.\d+$/; return re.test(version); } + +export function getInputAsArray( + name: string, + options?: core.InputOptions +): string[] { + return core + .getInput(name, options) + .split('\n') + .map(s => s.trim()) + .filter(x => x !== ''); +}