Skip to content

Commit

Permalink
refactor(pip_requirements): Move flags extraction to common.ts (#29360)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbudnek committed Jun 1, 2024
1 parent 5b18be5 commit 6797e01
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 66 deletions.
59 changes: 59 additions & 0 deletions lib/modules/manager/pip_requirements/common.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { extractPackageFileFlags } from './common';

describe('modules/manager/pip_requirements/common', () => {
describe('extractPackageFileFlags()', () => {
it('extracts --index-url flag', () => {
const res = extractPackageFileFlags(
'--index-url https://example.com/pypi',
);
expect(res).toMatchObject({
deps: [],
registryUrls: ['https://example.com/pypi'],
});
});

it('extracts --index-url short code', () => {
const requirements = `-i http://example.com/private-pypi/
some-package==0.3.1`;

const res = extractPackageFileFlags(requirements);

expect(res).toMatchObject({
deps: [],
registryUrls: ['http://example.com/private-pypi/'],
});
});

it('extracts --extra-index-url flag', () => {
const res = extractPackageFileFlags(
'--extra-index-url https://example.com/pypi',
);
expect(res).toMatchObject({
deps: [],
additionalRegistryUrls: ['https://example.com/pypi'],
});
});

it('extracts --requirement short code option', () => {
const requirements = `-r base.txt
some-package==0.3.1`;

const res = extractPackageFileFlags(requirements);

expect(res).toHaveProperty('managerData', {
requirementsFiles: ['base.txt'],
});
});

it('extracts --constraints short code option', () => {
const requirements = `-c constrain.txt
some-package==0.3.1`;

const res = extractPackageFileFlags(requirements);

expect(res).toHaveProperty('managerData', {
constraintsFiles: ['constrain.txt'],
});
});
});
});
70 changes: 70 additions & 0 deletions lib/modules/manager/pip_requirements/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { GlobalConfig } from '../../../config/global';
import { newlineRegex, regEx } from '../../../util/regex';
import type { PackageFileContent } from '../types';
import type { PipRequirementsManagerData } from './types';

function cleanRegistryUrls(registryUrls: string[]): string[] {
return registryUrls.map((url) => {
// handle the optional quotes in eg. `--extra-index-url "https://foo.bar"`
const cleaned = url.replace(regEx(/^"/), '').replace(regEx(/"$/), '');
if (!GlobalConfig.get('exposeAllEnv')) {
return cleaned;
}
// interpolate any environment variables
return cleaned.replace(
regEx(/(\$[A-Za-z\d_]+)|(\${[A-Za-z\d_]+})/g),
(match) => {
const envvar = match
.substring(1)
.replace(regEx(/^{/), '')
.replace(regEx(/}$/), '');
const sub = process.env[envvar];
return sub ?? match;
},
);
});
}

export function extractPackageFileFlags(
content: string,
): PackageFileContent<PipRequirementsManagerData> {
let registryUrls: string[] = [];
const additionalRegistryUrls: string[] = [];
const additionalRequirementsFiles: string[] = [];
const additionalConstraintsFiles: string[] = [];
content.split(newlineRegex).forEach((line) => {
if (line.startsWith('-i ') || line.startsWith('--index-url ')) {
registryUrls = [line.split(' ')[1]];
} else if (line.startsWith('--extra-index-url ')) {
const extraUrl = line
.substring('--extra-index-url '.length)
.split(' ')[0];
additionalRegistryUrls.push(extraUrl);
} else if (line.startsWith('-r ')) {
additionalRequirementsFiles.push(line.split(' ')[1]);
} else if (line.startsWith('-c ')) {
additionalConstraintsFiles.push(line.split(' ')[1]);
}
});

const res: PackageFileContent<PipRequirementsManagerData> = { deps: [] };
if (registryUrls.length > 0) {
res.registryUrls = cleanRegistryUrls(registryUrls);
}
if (additionalRegistryUrls.length) {
res.additionalRegistryUrls = cleanRegistryUrls(additionalRegistryUrls);
}
if (additionalRequirementsFiles.length) {
if (!res.managerData) {
res.managerData = {};
}
res.managerData.requirementsFiles = additionalRequirementsFiles;
}
if (additionalConstraintsFiles.length) {
if (!res.managerData) {
res.managerData = {};
}
res.managerData.constraintsFiles = additionalConstraintsFiles;
}
return res;
}
76 changes: 10 additions & 66 deletions lib/modules/manager/pip_requirements/extract.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// based on https://www.python.org/dev/peps/pep-0508/#names
import { RANGE_PATTERN } from '@renovatebot/pep440';
import is from '@sindresorhus/is';
import { GlobalConfig } from '../../../config/global';
import { logger } from '../../../logger';
import { isSkipComment } from '../../../util/ignore';
import { newlineRegex, regEx } from '../../../util/regex';
import { GitTagsDatasource } from '../../datasource/git-tags';
import { PypiDatasource } from '../../datasource/pypi';
import type { PackageDependency, PackageFileContent } from '../types';
import { extractPackageFileFlags } from './common';
import type { PipRequirementsManagerData } from './types';

export const packagePattern =
Expand All @@ -25,52 +25,11 @@ const specifierPartPattern = `\\s*${rangePattern.replace(
const specifierPattern = `${specifierPartPattern}(?:\\s*,${specifierPartPattern})*`;
export const dependencyPattern = `(${packagePattern})(${extrasPattern})(${specifierPattern})`;

export function cleanRegistryUrls(registryUrls: string[]): string[] {
return registryUrls.map((url) => {
// handle the optional quotes in eg. `--extra-index-url "https://foo.bar"`
const cleaned = url.replace(regEx(/^"/), '').replace(regEx(/"$/), '');
if (!GlobalConfig.get('exposeAllEnv')) {
return cleaned;
}
// interpolate any environment variables
return cleaned.replace(
regEx(/(\$[A-Za-z\d_]+)|(\${[A-Za-z\d_]+})/g),
(match) => {
const envvar = match
.substring(1)
.replace(regEx(/^{/), '')
.replace(regEx(/}$/), '');
const sub = process.env[envvar];
return sub ?? match;
},
);
});
}

export function extractPackageFile(
content: string,
): PackageFileContent<PipRequirementsManagerData> | null {
logger.trace('pip_requirements.extractPackageFile()');

let registryUrls: string[] = [];
const additionalRegistryUrls: string[] = [];
const additionalRequirementsFiles: string[] = [];
const additionalConstraintsFiles: string[] = [];
content.split(newlineRegex).forEach((line) => {
if (line.startsWith('-i ') || line.startsWith('--index-url ')) {
registryUrls = [line.split(' ')[1]];
} else if (line.startsWith('--extra-index-url ')) {
const extraUrl = line
.substring('--extra-index-url '.length)
.split(' ')[0];
additionalRegistryUrls.push(extraUrl);
} else if (line.startsWith('-r ')) {
additionalRequirementsFiles.push(line.split(' ')[1]);
} else if (line.startsWith('-c ')) {
additionalConstraintsFiles.push(line.split(' ')[1]);
}
});

const pkgRegex = regEx(`^(${packagePattern})$`);
const pkgValRegex = regEx(`^${dependencyPattern}$`);
const deps = content
Expand Down Expand Up @@ -131,33 +90,18 @@ export function extractPackageFile(
return dep;
})
.filter(is.truthy);

const res = extractPackageFileFlags(content);
res.deps = deps;

if (
!deps.length &&
!registryUrls.length &&
!additionalRegistryUrls.length &&
!additionalRequirementsFiles.length &&
!additionalConstraintsFiles.length
!res.deps.length &&
!res.registryUrls?.length &&
!res.additionalRegistryUrls?.length &&
!res.managerData?.requirementsFiles?.length &&
!res.managerData?.constraintsFiles?.length
) {
return null;
}
const res: PackageFileContent = { deps };
if (registryUrls.length > 0) {
res.registryUrls = cleanRegistryUrls(registryUrls);
}
if (additionalRegistryUrls.length) {
res.additionalRegistryUrls = cleanRegistryUrls(additionalRegistryUrls);
}
if (additionalRequirementsFiles.length) {
if (!res.managerData) {
res.managerData = {};
}
res.managerData.requirementsFiles = additionalRequirementsFiles;
}
if (additionalConstraintsFiles.length) {
if (!res.managerData) {
res.managerData = {};
}
res.managerData.constraintsFiles = additionalConstraintsFiles;
}
return res;
}

0 comments on commit 6797e01

Please sign in to comment.