Skip to content
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

fix(manager/pipenv): better artifacts handling of deprecated python #28023

Merged
merged 2 commits into from Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 47 additions & 2 deletions lib/modules/manager/pipenv/artifacts.spec.ts
Expand Up @@ -73,6 +73,7 @@ describe('modules/manager/pipenv/artifacts', () => {
// python
getPkgReleases.mockResolvedValueOnce({
releases: [
{ version: '3.6.5' },
{ version: '3.7.6' },
{ version: '3.8.5' },
{ version: '3.9.1' },
Expand Down Expand Up @@ -263,7 +264,51 @@ describe('modules/manager/pipenv/artifacts', () => {

it('supports install mode', async () => {
GlobalConfig.set({ ...adminConfig, binarySource: 'install' });
pipFileLock._meta!.requires!.python_full_version = '3.7.6';
pipFileLock._meta!.requires!.python_version = '3.6';
fs.ensureCacheDir.mockResolvedValueOnce(pipenvCacheDir);
fs.ensureCacheDir.mockResolvedValueOnce(pipCacheDir);
fs.ensureCacheDir.mockResolvedValueOnce(virtualenvsCacheDir);
fs.readLocalFile.mockResolvedValueOnce(JSON.stringify(pipFileLock));
// pipenv
datasource.getPkgReleases.mockResolvedValueOnce({
releases: [{ version: '2023.1.2' }],
});
const execSnapshots = mockExecAll();
git.getRepoStatus.mockResolvedValue(
partial<StatusResult>({
modified: ['Pipfile.lock'],
}),
);
fs.readLocalFile.mockResolvedValueOnce('new lock');

expect(
await updateArtifacts({
packageFileName: 'Pipfile',
updatedDeps: [],
newPackageFileContent: 'some new content',
config,
}),
).not.toBeNull();

expect(execSnapshots).toMatchObject([
{ cmd: 'install-tool python 3.6.5' },
{ cmd: 'install-tool pipenv 2013.6.12' },
{
cmd: 'pipenv lock',
options: {
cwd: '/tmp/github/some/repo',
env: {
PIPENV_CACHE_DIR: pipenvCacheDir,
PIP_CACHE_DIR: pipCacheDir,
WORKON_HOME: virtualenvsCacheDir,
},
},
},
]);
});

it('defaults to latest if no lock constraints', async () => {
GlobalConfig.set({ ...adminConfig, binarySource: 'install' });
fs.ensureCacheDir.mockResolvedValueOnce(pipenvCacheDir);
fs.ensureCacheDir.mockResolvedValueOnce(pipCacheDir);
fs.ensureCacheDir.mockResolvedValueOnce(virtualenvsCacheDir);
Expand All @@ -290,7 +335,7 @@ describe('modules/manager/pipenv/artifacts', () => {
).not.toBeNull();

expect(execSnapshots).toMatchObject([
{ cmd: 'install-tool python 3.7.6' },
{ cmd: 'install-tool python 3.10.2' },
{ cmd: 'install-tool pipenv 2013.6.12' },
{
cmd: 'pipenv lock',
Expand Down
33 changes: 29 additions & 4 deletions lib/modules/manager/pipenv/artifacts.ts
@@ -1,3 +1,5 @@
import is from '@sindresorhus/is';
import semver from 'semver';
import { TEMPORARY_ERROR } from '../../../constants/error-messages';
import { logger } from '../../../logger';
import type { HostRule } from '../../../types';
Expand Down Expand Up @@ -38,14 +40,16 @@ export function getPythonConstraint(
logger.warn({ error: result.error }, 'Invalid Pipfile.lock');
return undefined;
}
if (result.data._meta?.requires?.python_version) {
const pythonVersion = result.data._meta.requires.python_version;
return `== ${pythonVersion}.*`;
}
// Exact python version has been included since 2022.10.9. It is more specific than the major.minor version
if (result.data._meta?.requires?.python_full_version) {
const pythonFullVersion = result.data._meta.requires.python_full_version;
return `== ${pythonFullVersion}`;
}
// Before 2022.10.9, only the major.minor version was included
if (result.data._meta?.requires?.python_version) {
const pythonVersion = result.data._meta.requires.python_version;
return `== ${pythonVersion}.*`;
}
rarkins marked this conversation as resolved.
Show resolved Hide resolved
} catch (err) {
// Do nothing
}
Expand Down Expand Up @@ -76,6 +80,27 @@ export function getPipenvConstraint(
if (result.data.develop?.pipenv?.version) {
return result.data.develop.pipenv.version;
}
// Exact python version has been included since 2022.10.9
const pythonFullVersion = result.data._meta?.requires?.python_full_version;
if (is.string(pythonFullVersion) && semver.valid(pythonFullVersion)) {
// python_full_version was added after 3.6 was already deprecated, so it should be impossible to have a 3.6 version
if (semver.satisfies(pythonFullVersion, '3.7.*')) {
return '< 2023.10.20';
}
// Future deprecations will go here
}
// Before 2022.10.9, only the major.minor version was included
const pythonVersion = result.data._meta?.requires?.python_version;
if (pythonVersion) {
if (pythonVersion === '3.6') {
// Python 3.6 was deprecated in 2022.4.20
return '< 2022.4.20';
}
if (pythonVersion === '3.7') {
// Python 3.7 was deprecated in 2023.10.20 but we shouldn't reach here unless we are < 2022.10.9
return '< 2022.10.9';
}
}
} catch (err) {
// Do nothing
}
Expand Down