8000 Use correct Poetry config when collecting Poetry projects by oranav · Pull Request #447 · actions/setup-python · GitHub
[go: up one dir, main page]

Skip to content

Use correct Poetry config when collecting Poetry projects #447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 3, 2023
Prev Previous commit
Next Next commit
poetry: Run poetry env use only after cache is loaded
The virtualenv cache might contain invalid entries, such as virtualenvs
built in previous, buggy versions of this action.  The `poetry env use`
command will recreate virtualenvs in case they are invalid, but it has
to be run only *after* the cache is loaded.

Refactor `CacheDistributor` a bit such that the validation (and possible
recreation) of virtualenvs happens only after the cache is loaded.
  • Loading branch information
oranav committed Dec 9, 2022
commit 881ca6e47731b87e35fd347eb1a7815ab033bb1c
4 changes: 4 additions & 0 deletions dist/cache-save/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59711,6 +59711,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();
Expand All @@ -59723,6 +59726,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);
});
}
Expand Down
45 changes: 31 additions & 14 deletions dist/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65787,6 +65787,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();
Expand All @@ -65799,6 +65802,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);
});
}
Expand Down Expand Up @@ -66097,42 +66101,31 @@ 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;
return __awaiter(this, void 0, void 0, function* () {
// 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);
paths.add(virtualenvsPath);
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 }; }
Expand All @@ -66156,6 +66149,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 });
Expand Down
3 changes: 3 additions & 0 deletions src/cache-distributions/cache-distributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ abstract class CacheDistributor {
primaryKey: string;
restoreKey: string[] | undefined;
}>;
protected async handleLoadedCache() {}

public async restoreCache() {
const {primaryKey, restoreKey} = await this.computeKeys();
Expand All @@ -41,6 +42,8 @@ abstract class CacheDistributor {
restoreKey
);

await this.handleLoadedCache();

this.handleMatchResult(matchedKey, primaryKey);
}

Expand Down
50 changes: 30 additions & 20 deletions src/cache-distributions/poetry-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> = new Set<string>()
) {
super('poetry', patterns);
}
Expand All @@ -20,16 +21,10 @@ class PoetryCache extends CacheDistributor {
const paths = new Set<string>();
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);

Expand All @@ -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];
Expand All @@ -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',
Expand Down
0