Skip to content

Commit 10cd98c

Browse files
fix(python): add poetry v2 support (#8323)
Co-authored-by: Nikita Pivkin <[email protected]>
1 parent 9b74384 commit 10cd98c

File tree

13 files changed

+1065
-2199
lines changed

13 files changed

+1065
-2199
lines changed

pkg/dependency/parser/python/poetry/parse.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package poetry
22

33
import (
4+
"slices"
45
"sort"
56

67
"github.com/BurntSushi/toml"
@@ -17,6 +18,7 @@ import (
1718
type Lockfile struct {
1819
Packages []struct {
1920
Category string `toml:"category"`
21+
Groups []string `toml:"groups"`
2022
Description string `toml:"description"`
2123
Marker string `toml:"marker,omitempty"`
2224
Name string `toml:"name"`
@@ -50,15 +52,16 @@ func (p *Parser) Parse(r xio.ReadSeekerAt) ([]ftypes.Package, []ftypes.Dependenc
5052
var pkgs []ftypes.Package
5153
var deps []ftypes.Dependency
5254
for _, pkg := range lockfile.Packages {
53-
if pkg.Category == "dev" {
54-
continue
55-
}
56-
5755
pkgID := packageID(pkg.Name, pkg.Version)
5856
pkgs = append(pkgs, ftypes.Package{
5957
ID: pkgID,
6058
Name: pkg.Name,
6159
Version: pkg.Version,
60+
// TODO upgrade logic for working with groups
61+
// Mark only:
62+
// - `category = "dev"`
63+
// - groups without `main`. e.g. `groups = ["dev"]`
64+
Dev: pkg.Category == "dev" || (len(pkg.Groups) > 0 && !slices.Contains(pkg.Groups, "main")),
6265
})
6366

6467
dependsOn := p.parseDependencies(pkg.Dependencies, pkgVersions)

pkg/dependency/parser/python/poetry/parse_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ func TestParser_Parse(t *testing.T) {
2525
wantPkgs: poetryNormal,
2626
wantErr: assert.NoError,
2727
},
28-
{
29-
name: "many",
30-
file: "testdata/poetry_many.lock",
31-
wantPkgs: poetryMany,
32-
wantDeps: poetryManyDeps,
33-
wantErr: assert.NoError,
34-
},
3528
{
3629
name: "flask",
3730
file: "testdata/poetry_flask.lock",
3831
wantPkgs: poetryFlask,
3932
wantDeps: poetryFlaskDeps,
4033
wantErr: assert.NoError,
4134
},
35+
{
36+
name: "flask + poetry v2",
37+
file: "testdata/poetry_v2_flask.lock",
38+
wantPkgs: poetryFlask,
39+
wantDeps: poetryV2FlaskDeps,
40+
wantErr: assert.NoError,
41+
},
4242
}
4343
for _, tt := range tests {
4444
t.Run(tt.name, func(t *testing.T) {

pkg/dependency/parser/python/poetry/parse_testcase.go

+36-103
Original file line numberDiff line numberDiff line change
@@ -14,122 +14,55 @@ var (
1414
{ID: "[email protected]", Name: "pypi", Version: "2.1"},
1515
}
1616

17-
// docker run --name poetry --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
18-
// apk add curl
19-
// curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.1.7 python3 -
20-
// export PATH=/root/.local/bin:$PATH
21-
// poetry new many && cd many
22-
// curl -o poetry.lock https://raw.githubusercontent.com/python-poetry/poetry/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock
23-
// curl -o pyproject.toml https://raw.githubusercontent.com/python-poetry/poetry/c8945eb110aeda611cc6721565d7ad0c657d453a/pyproject.toml
24-
// poetry show -a | awk '{gsub(/\(!\)/, ""); printf("{ID: \""$1"@"$2"\", Name: \""$1"\", Version: \""$2"\"},\n") }'
25-
// `--no-dev` flag uncorrected returns deps. Then need to remove `dev` deps manually
26-
// list of dev deps - cat poetry.lock | grep 'category = "dev"' -B 3
27-
poetryMany = []ftypes.Package{
28-
{ID: "[email protected]", Name: "attrs", Version: "22.2.0"},
29-
{ID: "[email protected]", Name: "backports-cached-property", Version: "1.0.2"},
30-
{ID: "[email protected]", Name: "build", Version: "0.10.0"},
31-
{ID: "[email protected]", Name: "cachecontrol", Version: "0.12.11"},
32-
{ID: "[email protected]", Name: "certifi", Version: "2022.12.7"},
33-
{ID: "[email protected]", Name: "cffi", Version: "1.15.1"},
34-
{ID: "[email protected]", Name: "charset-normalizer", Version: "3.0.1"},
35-
{ID: "[email protected]", Name: "cleo", Version: "2.0.1"},
36-
{ID: "[email protected]", Name: "colorama", Version: "0.4.6"},
37-
{ID: "[email protected]", Name: "crashtest", Version: "0.4.1"},
38-
{ID: "[email protected]", Name: "cryptography", Version: "39.0.0"},
39-
{ID: "[email protected]", Name: "distlib", Version: "0.3.6"},
40-
{ID: "[email protected]", Name: "dulwich", Version: "0.21.2"},
41-
{ID: "[email protected]", Name: "filelock", Version: "3.9.0"},
42-
{ID: "[email protected]", Name: "html5lib", Version: "1.1"},
43-
{ID: "[email protected]", Name: "idna", Version: "3.4"},
44-
{ID: "[email protected]", Name: "importlib-metadata", Version: "6.0.0"},
45-
{ID: "[email protected]", Name: "importlib-resources", Version: "5.10.2"},
46-
{ID: "[email protected]", Name: "installer", Version: "0.6.0"},
47-
{ID: "[email protected]", Name: "jaraco-classes", Version: "3.2.3"},
48-
{ID: "[email protected]", Name: "jeepney", Version: "0.8.0"},
49-
{ID: "[email protected]", Name: "jsonschema", Version: "4.17.3"},
50-
{ID: "[email protected]", Name: "keyring", Version: "23.13.1"},
51-
{ID: "[email protected]", Name: "lockfile", Version: "0.12.2"},
52-
{ID: "[email protected]", Name: "more-itertools", Version: "9.0.0"},
53-
{ID: "[email protected]", Name: "msgpack", Version: "1.0.4"},
54-
{ID: "[email protected]", Name: "packaging", Version: "23.0"},
55-
{ID: "[email protected]", Name: "pexpect", Version: "4.8.0"},
56-
{ID: "[email protected]", Name: "pkginfo", Version: "1.9.6"},
57-
{ID: "[email protected]", Name: "pkgutil-resolve-name", Version: "1.3.10"},
58-
{ID: "[email protected]", Name: "platformdirs", Version: "2.6.2"},
59-
{ID: "[email protected]", Name: "poetry-core", Version: "1.5.0"},
60-
{ID: "[email protected]", Name: "poetry-plugin-export", Version: "1.3.0"},
61-
{ID: "[email protected]", Name: "ptyprocess", Version: "0.7.0"},
62-
{ID: "[email protected]", Name: "pycparser", Version: "2.21"},
63-
{ID: "[email protected]", Name: "pyproject-hooks", Version: "1.0.0"},
64-
{ID: "[email protected]", Name: "pyrsistent", Version: "0.19.3"},
65-
{ID: "[email protected]", Name: "pywin32-ctypes", Version: "0.2.0"},
66-
{ID: "[email protected]", Name: "rapidfuzz", Version: "2.13.7"},
67-
{ID: "[email protected]", Name: "requests", Version: "2.28.2"},
68-
{ID: "[email protected]", Name: "requests-toolbelt", Version: "0.10.1"},
69-
{ID: "[email protected]", Name: "secretstorage", Version: "3.3.3"},
70-
{ID: "[email protected]", Name: "shellingham", Version: "1.5.0.post1"},
71-
{ID: "[email protected]", Name: "six", Version: "1.16.0"},
72-
{ID: "[email protected]", Name: "tomli", Version: "2.0.1"},
73-
{ID: "[email protected]", Name: "tomlkit", Version: "0.11.6"},
74-
{ID: "[email protected]", Name: "trove-classifiers", Version: "2023.1.20"},
75-
{ID: "[email protected]", Name: "typing-extensions", Version: "4.4.0"},
76-
{ID: "[email protected]", Name: "urllib3", Version: "1.26.14"},
77-
{ID: "[email protected]", Name: "virtualenv", Version: "20.16.5"},
78-
{ID: "[email protected]", Name: "virtualenv", Version: "20.17.1"},
79-
{ID: "[email protected]", Name: "webencodings", Version: "0.5.1"},
80-
{ID: "[email protected]", Name: "xattr", Version: "0.10.1"},
81-
{ID: "[email protected]", Name: "zipp", Version: "3.12.0"},
82-
}
83-
84-
// cat poetry.lock | grep "\[package.dependencies\]" -B 3 -A 8 - it might help to complete this slice
85-
poetryManyDeps = []ftypes.Dependency{
86-
87-
88-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
89-
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}},
90-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
91-
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}},
92-
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}},
93-
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}},
94-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
95-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
96-
97-
98-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
99-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
100-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
101-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
102-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
103-
104-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
105-
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}},
106-
107-
108-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
109-
}
110-
11117
// docker run --name poetry --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
11218
// apk add curl
11319
// curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.1.7 python3 -
11420
// export PATH=/root/.local/bin:$PATH
11521
// poetry new web && cd web
22+
// poetry add [email protected] -E pre-commit,tox
11623
// poetry add [email protected]
24+
// poetry add [email protected] --dev
11725
// poetry show -a | awk '{gsub(/\(!\)/, ""); printf("{ID: \""$1"@"$2"\", Name: \""$1"\", Version: \""$2"\"},\n") }'
26+
// mark dev deps
11827
poetryFlask = []ftypes.Package{
119-
{ID: "[email protected]", Name: "click", Version: "8.1.3"},
28+
{ID: "[email protected]", Name: "atomicwrites", Version: "1.4.1", Dev: true},
29+
{ID: "[email protected]", Name: "attrs", Version: "25.1.0", Dev: true},
30+
{ID: "[email protected]", Name: "click", Version: "8.1.8"},
12031
{ID: "[email protected]", Name: "colorama", Version: "0.4.6"},
12132
{ID: "[email protected]", Name: "flask", Version: "1.0.3"},
122-
{ID: "[email protected]", Name: "itsdangerous", Version: "2.1.2"},
123-
{ID: "[email protected]", Name: "jinja2", Version: "3.1.2"},
124-
{ID: "[email protected]", Name: "markupsafe", Version: "2.1.2"},
125-
{ID: "[email protected]", Name: "werkzeug", Version: "2.2.3"},
33+
{ID: "[email protected]", Name: "itsdangerous", Version: "2.2.0"},
34+
{ID: "[email protected]", Name: "jinja2", Version: "3.1.5"},
35+
{ID: "[email protected]", Name: "markupsafe", Version: "3.0.2"},
36+
{ID: "[email protected]", Name: "more-itertools", Version: "10.6.0", Dev: true},
37+
{ID: "[email protected]", Name: "packaging", Version: "24.2", Dev: true},
38+
{ID: "[email protected]", Name: "pluggy", Version: "0.13.1", Dev: false},
39+
{ID: "[email protected]", Name: "py", Version: "1.11.0", Dev: true},
40+
{ID: "[email protected]", Name: "pytest", Version: "5.4.3", Dev: true},
41+
{ID: "[email protected]", Name: "wcwidth", Version: "0.2.13", Dev: true},
42+
{ID: "[email protected]", Name: "werkzeug", Version: "3.1.3"},
12643
}
12744

12845
// cat poetry.lock | grep "\[package.dependencies\]" -B 3 -A 8 - it might help to complete this slice
12946
poetryFlaskDeps = []ftypes.Dependency{
130-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
131-
132-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
133-
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
47+
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
48+
49+
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
50+
{ID: "[email protected]", DependsOn: []string{"[email protected]", "[email protected]"}},
51+
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
52+
}
53+
54+
// use instruction above with `POETRY_VERSION=2.0.1`
55+
56+
poetryV2FlaskDeps = []ftypes.Dependency{
57+
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
58+
59+
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
60+
{
61+
ID: "[email protected]", DependsOn: []string{
62+
63+
64+
},
65+
},
66+
{ID: "[email protected]", DependsOn: []string{"[email protected]"}},
13467
}
13568
)

0 commit comments

Comments
 (0)