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

feat(manager): Support poetry custom repositories. #4524

Merged
merged 11 commits into from
Sep 30, 2019
24 changes: 23 additions & 1 deletion lib/manager/poetry/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export function extractPackageFile(
if (!deps.length) {
return null;
}
return { deps };

return { deps, registryUrls: extractRegistries(pyprojectfile) };
}

function extractFromSection(
Expand Down Expand Up @@ -84,3 +85,24 @@ function extractFromSection(
});
return deps;
}

function extractRegistries(pyprojectfile: PoetryFile): string[] {
const sources =
pyprojectfile.tool &&
pyprojectfile.tool.poetry &&
pyprojectfile.tool.poetry.source;

if (!Array.isArray(sources) || sources.length === 0) {
return null;
}

const registryUrls = new Set<string>();
for (const source of sources) {
if (source.url) {
registryUrls.add(source.url);
}
}
registryUrls.add('https://pypi.org/pypi/');

return Array.from(registryUrls);
}
6 changes: 6 additions & 0 deletions lib/manager/poetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export interface PoetrySection {
dependencies: Record<string, PoetryDependency | string>;
'dev-dependencies': Record<string, PoetryDependency | string>;
extras: Record<string, PoetryDependency | string>;
source?: PoetrySource[];
}

export interface PoetryFile {
Expand All @@ -15,3 +16,8 @@ export interface PoetryDependency {
git?: string;
version?: string;
}

export interface PoetrySource {
name?: string;
url?: string;
}
15 changes: 15 additions & 0 deletions test/manager/poetry/__snapshots__/extract.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`lib/manager/poetry/extract extractPackageFile() dedupes registries 1`] = `
Array [
"https://pypi.org/pypi/",
"https://bar.baz/+simple/",
]
`;

exports[`lib/manager/poetry/extract extractPackageFile() extracts multiple dependencies (with dep = {version = "1.2.3"} case) 1`] = `
Array [
Object {
Expand Down Expand Up @@ -157,6 +164,14 @@ Array [
]
`;

exports[`lib/manager/poetry/extract extractPackageFile() extracts registries 1`] = `
Array [
"https://foo.bar/simple/",
"https://bar.baz/+simple/",
"https://pypi.org/pypi/",
]
`;

exports[`lib/manager/poetry/extract extractPackageFile() handles multiple constraint dependencies 1`] = `
Array [
Object {
Expand Down
16 changes: 16 additions & 0 deletions test/manager/poetry/_fixtures/pyproject.6.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[tool.poetry]
name = "example 6"
version = "0.1.0"
description = ""
authors = ["John Doe <[email protected]>"]

[tool.poetry.dependencies]
dep0 = "0.0.0"

[[tool.poetry.source]]
name = "foo"
url = "https://foo.bar/simple/"

[[tool.poetry.source]]
name = "bar"
url = "https://bar.baz/+simple/"
9 changes: 9 additions & 0 deletions test/manager/poetry/_fixtures/pyproject.7.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[tool.poetry]
name = "example 7"
version = "0.1.0"
description = ""
authors = ["John Doe <[email protected]>"]
source = []

[tool.poetry.dependencies]
dep0 = "0.0.0"
20 changes: 20 additions & 0 deletions test/manager/poetry/_fixtures/pyproject.8.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[tool.poetry]
name = "example 8"
version = "0.1.0"
description = ""
authors = ["John Doe <[email protected]>"]

[tool.poetry.dependencies]
dep0 = "0.0.0"

[[tool.poetry.source]]
name = "foo"
url = "https://pypi.org/pypi/"

[[tool.poetry.source]]
name = "bar"
url = "https://bar.baz/+simple/"

[[tool.poetry.source]]
name = "baz"
url = "https://bar.baz/+simple/"
56 changes: 44 additions & 12 deletions test/manager/poetry/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,41 +26,73 @@ const pyproject5toml = readFileSync(
'utf8'
);

const pyproject6toml = readFileSync(
'test/manager/poetry/_fixtures/pyproject.6.toml',
'utf8'
);

const pyproject7toml = readFileSync(
'test/manager/poetry/_fixtures/pyproject.7.toml',
'utf8'
);

const pyproject8toml = readFileSync(
'test/manager/poetry/_fixtures/pyproject.8.toml',
'utf8'
);

describe('lib/manager/poetry/extract', () => {
describe('extractPackageFile()', () => {
let config;
let filename: string;
beforeEach(() => {
config = {};
filename = '';
});
it('returns null for empty', () => {
expect(extractPackageFile('nothing here', config)).toBeNull();
expect(extractPackageFile('nothing here', filename)).toBeNull();
});
it('returns null for parsed file without poetry section', () => {
expect(extractPackageFile(pyproject5toml, config)).toBeNull();
expect(extractPackageFile(pyproject5toml, filename)).toBeNull();
});
it('extracts multiple dependencies', () => {
const res = extractPackageFile(pyproject1toml, config);
const res = extractPackageFile(pyproject1toml, filename);
expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(9);
});
it('extracts multiple dependencies (with dep = {version = "1.2.3"} case)', () => {
const res = extractPackageFile(pyproject2toml, config);
const res = extractPackageFile(pyproject2toml, filename);
expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(7);
});
it('handles case with no dependencies', () => {
const res = extractPackageFile(pyproject3toml, config);
const res = extractPackageFile(pyproject3toml, filename);
expect(res).toBeNull();
});
it('handles multiple constraint dependencies', () => {
const res = extractPackageFile(pyproject4toml, config);
const res = extractPackageFile(pyproject4toml, filename);
expect(res.deps).toMatchSnapshot();
expect(res.deps).toHaveLength(1);
});
it('extracts registries', () => {
const res = extractPackageFile(pyproject6toml, filename);
expect(res.registryUrls).toMatchSnapshot();
expect(res.registryUrls).toHaveLength(3);
});
it('can parse empty registries', () => {
const res = extractPackageFile(pyproject7toml, filename);
expect(res.registryUrls).toBeNull();
});
it('can parse missing registries', () => {
const res = extractPackageFile(pyproject1toml, filename);
expect(res.registryUrls).toBeNull();
});
it('dedupes registries', () => {
const res = extractPackageFile(pyproject8toml, filename);
expect(res.registryUrls).toMatchSnapshot();
});
it('skips git dependencies', () => {
const content =
'[tool.poetry.dependencies]\r\nflask = {git = "https://github.com/pallets/flask.git"}\r\nwerkzeug = ">=0.14"';
const res = extractPackageFile(content, config).deps;
const res = extractPackageFile(content, filename).deps;
expect(res[0].depName).toBe('flask');
expect(res[0].currentValue).toBe('');
expect(res[0].skipReason).toBe('git-dependency');
Expand All @@ -69,7 +101,7 @@ describe('lib/manager/poetry/extract', () => {
it('skips git dependencies', () => {
const content =
'[tool.poetry.dependencies]\r\nflask = {git = "https://github.com/pallets/flask.git", version="1.2.3"}\r\nwerkzeug = ">=0.14"';
const res = extractPackageFile(content, config).deps;
const res = extractPackageFile(content, filename).deps;
expect(res[0].depName).toBe('flask');
expect(res[0].currentValue).toBe('1.2.3');
expect(res[0].skipReason).toBe('git-dependency');
Expand All @@ -78,7 +110,7 @@ describe('lib/manager/poetry/extract', () => {
it('skips path dependencies', () => {
const content =
'[tool.poetry.dependencies]\r\nflask = {path = "/some/path/"}\r\nwerkzeug = ">=0.14"';
const res = extractPackageFile(content, config).deps;
const res = extractPackageFile(content, filename).deps;
expect(res[0].depName).toBe('flask');
expect(res[0].currentValue).toBe('');
expect(res[0].skipReason).toBe('path-dependency');
Expand All @@ -87,7 +119,7 @@ describe('lib/manager/poetry/extract', () => {
it('skips path dependencies', () => {
const content =
'[tool.poetry.dependencies]\r\nflask = {path = "/some/path/", version = "1.2.3"}\r\nwerkzeug = ">=0.14"';
const res = extractPackageFile(content, config).deps;
const res = extractPackageFile(content, filename).deps;
expect(res[0].depName).toBe('flask');
expect(res[0].currentValue).toBe('1.2.3');
expect(res[0].skipReason).toBe('path-dependency');
Expand Down