diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js index da8fdef70..4357671db 100644 --- a/dist/cache-save/index.js +++ b/dist/cache-save/index.js @@ -45304,10 +45304,10 @@ function populateMaps (extensions, types) { module.exports = minimatch minimatch.Minimatch = Minimatch -var path = (function () { try { return __nccwpck_require__(1017) } catch (e) {}}()) || { - sep: '/' -} -minimatch.sep = path.sep +var path = { sep: '/' } +try { + path = __nccwpck_require__(1017) +} catch (er) {} var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} var expand = __nccwpck_require__(3717) @@ -45359,64 +45359,43 @@ function filter (pattern, options) { } function ext (a, b) { + a = a || {} b = b || {} var t = {} - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) Object.keys(b).forEach(function (k) { t[k] = b[k] }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) return t } minimatch.defaults = function (def) { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return minimatch - } + if (!def || !Object.keys(def).length) return minimatch var orig = minimatch var m = function minimatch (p, pattern, options) { - return orig(p, pattern, ext(def, options)) + return orig.minimatch(p, pattern, ext(def, options)) } m.Minimatch = function Minimatch (pattern, options) { return new orig.Minimatch(pattern, ext(def, options)) } - m.Minimatch.defaults = function defaults (options) { - return orig.defaults(ext(def, options)).Minimatch - } - - m.filter = function filter (pattern, options) { - return orig.filter(pattern, ext(def, options)) - } - - m.defaults = function defaults (options) { - return orig.defaults(ext(def, options)) - } - - m.makeRe = function makeRe (pattern, options) { - return orig.makeRe(pattern, ext(def, options)) - } - - m.braceExpand = function braceExpand (pattern, options) { - return orig.braceExpand(pattern, ext(def, options)) - } - - m.match = function (list, pattern, options) { - return orig.match(list, pattern, ext(def, options)) - } return m } Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch return minimatch.defaults(def).Minimatch } function minimatch (p, pattern, options) { - assertValidPattern(pattern) + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } if (!options) options = {} @@ -45425,6 +45404,9 @@ function minimatch (p, pattern, options) { return false } + // "" only matches "" + if (pattern.trim() === '') return p === '' + return new Minimatch(pattern, options).match(p) } @@ -45433,14 +45415,15 @@ function Minimatch (pattern, options) { return new Minimatch(pattern, options) } - assertValidPattern(pattern) + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } if (!options) options = {} - pattern = pattern.trim() // windows support: need to use /, not \ - if (!options.allowWindowsEscape && path.sep !== '/') { + if (path.sep !== '/') { pattern = pattern.split(path.sep).join('/') } @@ -45451,7 +45434,6 @@ function Minimatch (pattern, options) { this.negate = false this.comment = false this.empty = false - this.partial = !!options.partial // make the set of regexps etc. this.make() @@ -45461,6 +45443,9 @@ Minimatch.prototype.debug = function () {} Minimatch.prototype.make = make function make () { + // don't do it more than once. + if (this._made) return + var pattern = this.pattern var options = this.options @@ -45480,7 +45465,7 @@ function make () { // step 2: expand braces var set = this.globSet = this.braceExpand() - if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } + if (options.debug) this.debug = console.error this.debug(this.pattern, set) @@ -45560,11 +45545,12 @@ function braceExpand (pattern, options) { pattern = typeof pattern === 'undefined' ? this.pattern : pattern - assertValidPattern(pattern) + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } - // Thanks to Yeting Li for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { + if (options.nobrace || + !pattern.match(/\{.*\}/)) { // shortcut. no need to expand. return [pattern] } @@ -45572,17 +45558,6 @@ function braceExpand (pattern, options) { return expand(pattern) } -var MAX_PATTERN_LENGTH = 1024 * 64 -var assertValidPattern = function (pattern) { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern') - } - - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long') - } -} - // parse a component of the expanded set. // At this point, no pattern may contain "/" in it // so we're going to return a 2d array, where each entry is the full @@ -45597,17 +45572,14 @@ var assertValidPattern = function (pattern) { Minimatch.prototype.parse = parse var SUBPARSE = {} function parse (pattern, isSub) { - assertValidPattern(pattern) + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } var options = this.options // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return GLOBSTAR - else - pattern = '*' - } + if (!options.noglobstar && pattern === '**') return GLOBSTAR if (pattern === '') return '' var re = '' @@ -45663,12 +45635,10 @@ function parse (pattern, isSub) { } switch (c) { - /* istanbul ignore next */ - case '/': { + case '/': // completely not allowed, even escaped. // Should already be path-split by now. return false - } case '\\': clearStateChar() @@ -45787,23 +45757,25 @@ function parse (pattern, isSub) { // handle the case where we left a class open. // "[z-a]" is valid, equivalent to "\[z-a\]" - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } } // finish up the class. @@ -45887,7 +45859,9 @@ function parse (pattern, isSub) { // something that could conceivably capture a dot var addPatternStart = false switch (re.charAt(0)) { - case '[': case '.': case '(': addPatternStart = true + case '.': + case '[': + case '(': addPatternStart = true } // Hack to work around lack of negative lookbehind in JS @@ -45949,7 +45923,7 @@ function parse (pattern, isSub) { var flags = options.nocase ? 'i' : '' try { var regExp = new RegExp('^' + re + '$', flags) - } catch (er) /* istanbul ignore next - should be impossible */ { + } catch (er) { // If it was an invalid regular expression, then it can't match // anything. This trick looks for a character after the end of // the string, which is of course impossible, except in multi-line @@ -46007,7 +45981,7 @@ function makeRe () { try { this.regexp = new RegExp(re, flags) - } catch (ex) /* istanbul ignore next - should be impossible */ { + } catch (ex) { this.regexp = false } return this.regexp @@ -46025,8 +45999,8 @@ minimatch.match = function (list, pattern, options) { return list } -Minimatch.prototype.match = function match (f, partial) { - if (typeof partial === 'undefined') partial = this.partial +Minimatch.prototype.match = match +function match (f, partial) { this.debug('match', f, this.pattern) // short-circuit in the case of busted things. // comments, etc. @@ -46108,7 +46082,6 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // should be impossible. // some invalid regexp stuff in the set. - /* istanbul ignore if */ if (p === false) return false if (p === GLOBSTAR) { @@ -46182,7 +46155,6 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // no match was found. // However, in partial mode, we can't say this is necessarily over. // If there's more *pattern* left, then - /* istanbul ignore if */ if (partial) { // ran out of file this.debug('\n>>> no match, partial?', file, fr, pattern, pr) @@ -46196,7 +46168,11 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // patterns with magic have been turned into regexps. var hit if (typeof p === 'string') { - hit = f === p + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } this.debug('string match', p, f, hit) } else { hit = f.match(p) @@ -46227,16 +46203,16 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // this is ok if we're doing the match as part of // a glob fs traversal. return partial - } else /* istanbul ignore else */ if (pi === pl) { + } else if (pi === pl) { // ran out of pattern, still have file left. // this is only acceptable if we're on the very last // empty segment of a file with a trailing slash. // a/* should match a/b/ - return (fi === fl - 1) && (file[fi] === '') + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd } // should be unreachable. - /* istanbul ignore next */ throw new Error('wtf?') } @@ -59711,6 +59687,9 @@ class CacheDistributor { this.cacheDependencyPath = cacheDependencyPath; this.CACHE_KEY_PREFIX = 'setup-python'; } + handleLoadedCache() { + return __awaiter(this, void 0, void 0, function* () { }); + } restoreCache() { return __awaiter(this, void 0, void 0, function* () { const { primaryKey, restoreKey } = yield this.computeKeys(); @@ -59723,6 +59702,7 @@ class CacheDistributor { core.saveState(State.CACHE_PATHS, cachePath); core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey); const matchedKey = yield cache.restoreCache(cachePath, primaryKey, restoreKey); + yield this.handleLoadedCache(); this.handleMatchResult(matchedKey, primaryKey); }); } diff --git a/dist/setup/index.js b/dist/setup/index.js index 28e3cee72..bf5d90d6c 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -49469,10 +49469,10 @@ function populateMaps (extensions, types) { module.exports = minimatch minimatch.Minimatch = Minimatch -var path = (function () { try { return __nccwpck_require__(1017) } catch (e) {}}()) || { - sep: '/' -} -minimatch.sep = path.sep +var path = { sep: '/' } +try { + path = __nccwpck_require__(1017) +} catch (er) {} var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} var expand = __nccwpck_require__(3717) @@ -49524,64 +49524,43 @@ function filter (pattern, options) { } function ext (a, b) { + a = a || {} b = b || {} var t = {} - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) Object.keys(b).forEach(function (k) { t[k] = b[k] }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) return t } minimatch.defaults = function (def) { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return minimatch - } + if (!def || !Object.keys(def).length) return minimatch var orig = minimatch var m = function minimatch (p, pattern, options) { - return orig(p, pattern, ext(def, options)) + return orig.minimatch(p, pattern, ext(def, options)) } m.Minimatch = function Minimatch (pattern, options) { return new orig.Minimatch(pattern, ext(def, options)) } - m.Minimatch.defaults = function defaults (options) { - return orig.defaults(ext(def, options)).Minimatch - } - - m.filter = function filter (pattern, options) { - return orig.filter(pattern, ext(def, options)) - } - - m.defaults = function defaults (options) { - return orig.defaults(ext(def, options)) - } - - m.makeRe = function makeRe (pattern, options) { - return orig.makeRe(pattern, ext(def, options)) - } - - m.braceExpand = function braceExpand (pattern, options) { - return orig.braceExpand(pattern, ext(def, options)) - } - - m.match = function (list, pattern, options) { - return orig.match(list, pattern, ext(def, options)) - } return m } Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch return minimatch.defaults(def).Minimatch } function minimatch (p, pattern, options) { - assertValidPattern(pattern) + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } if (!options) options = {} @@ -49590,6 +49569,9 @@ function minimatch (p, pattern, options) { return false } + // "" only matches "" + if (pattern.trim() === '') return p === '' + return new Minimatch(pattern, options).match(p) } @@ -49598,14 +49580,15 @@ function Minimatch (pattern, options) { return new Minimatch(pattern, options) } - assertValidPattern(pattern) + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } if (!options) options = {} - pattern = pattern.trim() // windows support: need to use /, not \ - if (!options.allowWindowsEscape && path.sep !== '/') { + if (path.sep !== '/') { pattern = pattern.split(path.sep).join('/') } @@ -49616,7 +49599,6 @@ function Minimatch (pattern, options) { this.negate = false this.comment = false this.empty = false - this.partial = !!options.partial // make the set of regexps etc. this.make() @@ -49626,6 +49608,9 @@ Minimatch.prototype.debug = function () {} Minimatch.prototype.make = make function make () { + // don't do it more than once. + if (this._made) return + var pattern = this.pattern var options = this.options @@ -49645,7 +49630,7 @@ function make () { // step 2: expand braces var set = this.globSet = this.braceExpand() - if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } + if (options.debug) this.debug = console.error this.debug(this.pattern, set) @@ -49725,11 +49710,12 @@ function braceExpand (pattern, options) { pattern = typeof pattern === 'undefined' ? this.pattern : pattern - assertValidPattern(pattern) + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } - // Thanks to Yeting Li for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { + if (options.nobrace || + !pattern.match(/\{.*\}/)) { // shortcut. no need to expand. return [pattern] } @@ -49737,17 +49723,6 @@ function braceExpand (pattern, options) { return expand(pattern) } -var MAX_PATTERN_LENGTH = 1024 * 64 -var assertValidPattern = function (pattern) { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern') - } - - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long') - } -} - // parse a component of the expanded set. // At this point, no pattern may contain "/" in it // so we're going to return a 2d array, where each entry is the full @@ -49762,17 +49737,14 @@ var assertValidPattern = function (pattern) { Minimatch.prototype.parse = parse var SUBPARSE = {} function parse (pattern, isSub) { - assertValidPattern(pattern) + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } var options = this.options // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return GLOBSTAR - else - pattern = '*' - } + if (!options.noglobstar && pattern === '**') return GLOBSTAR if (pattern === '') return '' var re = '' @@ -49828,12 +49800,10 @@ function parse (pattern, isSub) { } switch (c) { - /* istanbul ignore next */ - case '/': { + case '/': // completely not allowed, even escaped. // Should already be path-split by now. return false - } case '\\': clearStateChar() @@ -49952,23 +49922,25 @@ function parse (pattern, isSub) { // handle the case where we left a class open. // "[z-a]" is valid, equivalent to "\[z-a\]" - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } } // finish up the class. @@ -50052,7 +50024,9 @@ function parse (pattern, isSub) { // something that could conceivably capture a dot var addPatternStart = false switch (re.charAt(0)) { - case '[': case '.': case '(': addPatternStart = true + case '.': + case '[': + case '(': addPatternStart = true } // Hack to work around lack of negative lookbehind in JS @@ -50114,7 +50088,7 @@ function parse (pattern, isSub) { var flags = options.nocase ? 'i' : '' try { var regExp = new RegExp('^' + re + '$', flags) - } catch (er) /* istanbul ignore next - should be impossible */ { + } catch (er) { // If it was an invalid regular expression, then it can't match // anything. This trick looks for a character after the end of // the string, which is of course impossible, except in multi-line @@ -50172,7 +50146,7 @@ function makeRe () { try { this.regexp = new RegExp(re, flags) - } catch (ex) /* istanbul ignore next - should be impossible */ { + } catch (ex) { this.regexp = false } return this.regexp @@ -50190,8 +50164,8 @@ minimatch.match = function (list, pattern, options) { return list } -Minimatch.prototype.match = function match (f, partial) { - if (typeof partial === 'undefined') partial = this.partial +Minimatch.prototype.match = match +function match (f, partial) { this.debug('match', f, this.pattern) // short-circuit in the case of busted things. // comments, etc. @@ -50273,7 +50247,6 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // should be impossible. // some invalid regexp stuff in the set. - /* istanbul ignore if */ if (p === false) return false if (p === GLOBSTAR) { @@ -50347,7 +50320,6 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // no match was found. // However, in partial mode, we can't say this is necessarily over. // If there's more *pattern* left, then - /* istanbul ignore if */ if (partial) { // ran out of file this.debug('\n>>> no match, partial?', file, fr, pattern, pr) @@ -50361,7 +50333,11 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // patterns with magic have been turned into regexps. var hit if (typeof p === 'string') { - hit = f === p + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } this.debug('string match', p, f, hit) } else { hit = f.match(p) @@ -50392,16 +50368,16 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) { // this is ok if we're doing the match as part of // a glob fs traversal. return partial - } else /* istanbul ignore else */ if (pi === pl) { + } else if (pi === pl) { // ran out of pattern, still have file left. // this is only acceptable if we're on the very last // empty segment of a file with a trailing slash. // a/* should match a/b/ - return (fi === fl - 1) && (file[fi] === '') + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd } // should be unreachable. - /* istanbul ignore next */ throw new Error('wtf?') } @@ -65787,6 +65763,9 @@ class CacheDistributor { this.cacheDependencyPath = cacheDependencyPath; this.CACHE_KEY_PREFIX = 'setup-python'; } + handleLoadedCache() { + return __awaiter(this, void 0, void 0, function* () { }); + } restoreCache() { return __awaiter(this, void 0, void 0, function* () { const { primaryKey, restoreKey } = yield this.computeKeys(); @@ -65799,6 +65778,7 @@ class CacheDistributor { core.saveState(State.CACHE_PATHS, cachePath); core.saveState(State.STATE_CACHE_PRIMARY_KEY, primaryKey); const matchedKey = yield cache.restoreCache(cachePath, primaryKey, restoreKey); + yield this.handleLoadedCache(); this.handleMatchResult(matchedKey, primaryKey); }); } @@ -66097,10 +66077,11 @@ const core = __importStar(__nccwpck_require__(2186)); const cache_distributor_1 = __importDefault(__nccwpck_require__(8953)); const utils_1 = __nccwpck_require__(1314); class PoetryCache extends cache_distributor_1.default { - constructor(pythonVersion, patterns = '**/poetry.lock') { + constructor(pythonVersion, patterns = '**/poetry.lock', poetryProjects = new Set()) { super('poetry', patterns); this.pythonVersion = pythonVersion; this.patterns = patterns; + this.poetryProjects = poetryProjects; } getCacheGlobalDirectories() { var e_1, _a; @@ -66108,18 +66089,12 @@ class PoetryCache extends cache_distributor_1.default { // Same virtualenvs path may appear for different projects, hence we use a Set const paths = new Set(); const globber = yield glob.create(this.patterns); - const pythonLocation = yield io.which('python'); - if (pythonLocation) { - core.debug(`pythonLocation is ${pythonLocation}`); - } - else { - utils_1.logWarning('python binaries were not found in PATH'); - } try { for (var _b = __asyncValues(globber.globGenerator()), _c; _c = yield _b.next(), !_c.done;) { const file = _c.value; const basedir = path.dirname(file); core.debug(`Processing Poetry project at ${basedir}`); + this.poetryProjects.add(basedir); const poetryConfig = yield this.getPoetryConfiguration(basedir); const cacheDir = poetryConfig['cache-dir']; const virtualenvsPath = poetryConfig['virtualenvs.path'].replace('{cache-dir}', cacheDir); @@ -66127,12 +66102,6 @@ class PoetryCache extends cache_distributor_1.default { if (poetryConfig['virtualenvs.in-project']) { paths.add(path.join(basedir, '.venv')); } - if (pythonLocation) { - const { exitCode, stderr } = yield exec.getExecOutput('poetry', ['env', 'use', pythonLocation], { ignoreReturnCode: true, cwd: basedir }); - if (exitCode) { - utils_1.logWarning(stderr); - } - } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } @@ -66156,6 +66125,30 @@ class PoetryCache extends cache_distributor_1.default { }; }); } + handleLoadedCache() { + const _super = Object.create(null, { + handleLoadedCache: { get: () => super.handleLoadedCache } + }); + return __awaiter(this, void 0, void 0, function* () { + yield _super.handleLoadedCache.call(this); + // After the cache is loaded -- make sure virtualenvs use the correct Python version (the one that we have just installed). + // This will handle invalid caches, recreating virtualenvs if necessary. + const pythonLocation = yield io.which('python'); + if (pythonLocation) { + core.debug(`pythonLocation is ${pythonLocation}`); + } + else { + utils_1.logWarning('python binaries were not found in PATH'); + return; + } + for (const poetryProject of this.poetryProjects) { + const { exitCode, stderr } = yield exec.getExecOutput('poetry', ['env', 'use', pythonLocation], { ignoreReturnCode: true, cwd: poetryProject }); + if (exitCode) { + utils_1.logWarning(stderr); + } + } + }); + } getPoetryConfiguration(basedir) { return __awaiter(this, void 0, void 0, function* () { const { stdout, stderr, exitCode } = yield exec.getExecOutput('poetry', ['config', '--list'], { cwd: basedir }); diff --git a/src/cache-distributions/cache-distributor.ts b/src/cache-distributions/cache-distributor.ts index f24c78dab..2e46c961d 100644 --- a/src/cache-distributions/cache-distributor.ts +++ b/src/cache-distributions/cache-distributor.ts @@ -19,6 +19,7 @@ abstract class CacheDistributor { primaryKey: string; restoreKey: string[] | undefined; }>; + protected async handleLoadedCache() {} public async restoreCache() { const {primaryKey, restoreKey} = await this.computeKeys(); @@ -41,6 +42,8 @@ abstract class CacheDistributor { restoreKey ); + await this.handleLoadedCache(); + this.handleMatchResult(matchedKey, primaryKey); } diff --git a/src/cache-distributions/poetry-cache.ts b/src/cache-distributions/poetry-cache.ts index 24a96b13b..ebbffbacf 100644 --- a/src/cache-distributions/poetry-cache.ts +++ b/src/cache-distributions/poetry-cache.ts @@ -10,7 +10,8 @@ import {logWarning} from '../utils'; class PoetryCache extends CacheDistributor { constructor( private pythonVersion: string, - protected patterns: string = '**/poetry.lock' + protected patterns: string = '**/poetry.lock', + protected poetryProjects: Set = new Set() ) { super('poetry', patterns); } @@ -20,16 +21,10 @@ class PoetryCache extends CacheDistributor { const paths = new Set(); const globber = await glob.create(this.patterns); - const pythonLocation = await io.which('python'); - if (pythonLocation) { - core.debug(`pythonLocation is ${pythonLocation}`); - } else { - logWarning('python binaries were not found in PATH'); - } - for await (const file of globber.globGenerator()) { const basedir = path.dirname(file); core.debug(`Processing Poetry project at ${basedir}`); + this.poetryProjects.add(basedir); const poetryConfig = await this.getPoetryConfiguration(basedir); @@ -44,18 +39,6 @@ class PoetryCache extends CacheDistributor { if (poetryConfig['virtualenvs.in-project']) { paths.add(path.join(basedir, '.venv')); } - - if (pythonLocation) { - const {exitCode, stderr} = await exec.getExecOutput( - 'poetry', - ['env', 'use', pythonLocation], - {ignoreReturnCode: true, cwd: basedir} - ); - - if (exitCode) { - logWarning(stderr); - } - } } return [...paths]; @@ -71,6 +54,33 @@ class PoetryCache extends CacheDistributor { }; } + protected async handleLoadedCache() { + await super.handleLoadedCache(); + + // After the cache is loaded -- make sure virtualenvs use the correct Python version (the one that we have just installed). + // This will handle invalid caches, recreating virtualenvs if necessary. + + const pythonLocation = await io.which('python'); + if (pythonLocation) { + core.debug(`pythonLocation is ${pythonLocation}`); + } else { + logWarning('python binaries were not found in PATH'); + return; + } + + for (const poetryProject of this.poetryProjects) { + const {exitCode, stderr} = await exec.getExecOutput( + 'poetry', + ['env', 'use', pythonLocation], + {ignoreReturnCode: true, cwd: poetryProject} + ); + + if (exitCode) { + logWarning(stderr); + } + } + } + private async getPoetryConfiguration(basedir: string) { const {stdout, stderr, exitCode} = await exec.getExecOutput( 'poetry',