Skip to content

Commit

Permalink
Merge pull request #376 from ackama:poetry/support-groups
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 719216987
  • Loading branch information
copybara-github committed Jan 24, 2025
2 parents 85f39de + f91ddcd commit 147bdb5
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 9 deletions.
35 changes: 26 additions & 9 deletions extractor/filesystem/language/python/poetrylock/poetrylock.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type poetryLockPackage struct {
Name string `toml:"name"`
Version string `toml:"version"`
Optional bool `toml:"optional"`
Groups []string `toml:"groups"`
Source poetryLockPackageSource `toml:"source"`
}

Expand Down Expand Up @@ -65,6 +66,28 @@ func (e Extractor) FileRequired(api filesystem.FileAPI) bool {
return filepath.Base(api.Path()) == "poetry.lock"
}

func resolveGroups(pkg poetryLockPackage) []string {
// by definition an optional package cannot be in any other group,
// otherwise that would make it a required package
if pkg.Optional {
return []string{"optional"}
}

if pkg.Groups == nil {
return []string{}
}

for _, group := range pkg.Groups {
// the "main" group is the default group used for "production" dependencies,
// which we represent by an empty slice aka no groups
if group == "main" {
return []string{}
}
}

return pkg.Groups
}

// Extract extracts packages from poetry.lock files passed through the scan input.
func (e Extractor) Extract(ctx context.Context, input *filesystem.ScanInput) ([]*extractor.Inventory, error) {
var parsedLockfile *poetryLockFile
Expand All @@ -82,21 +105,15 @@ func (e Extractor) Extract(ctx context.Context, input *filesystem.ScanInput) ([]
Name: lockPackage.Name,
Version: lockPackage.Version,
Locations: []string{input.Path},
Metadata: osv.DepGroupMetadata{
DepGroupVals: resolveGroups(lockPackage),
},
}
if lockPackage.Source.Commit != "" {
pkgDetails.SourceCode = &extractor.SourceCodeIdentifier{
Commit: lockPackage.Source.Commit,
}
}
if lockPackage.Optional {
pkgDetails.Metadata = osv.DepGroupMetadata{
DepGroupVals: []string{"optional"},
}
} else {
pkgDetails.Metadata = osv.DepGroupMetadata{
DepGroupVals: []string{},
}
}
packages = append(packages, pkgDetails)
}

Expand Down
96 changes: 96 additions & 0 deletions extractor/filesystem/language/python/poetrylock/poetrylock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,102 @@ func TestExtractor_Extract(t *testing.T) {
},
},
},
{
Name: "multiple packages with a v2 lockfile",
InputConfig: extracttest.ScanInputMockConfig{
Path: "testdata/multiple-packages.v2.lock",
},
WantInventory: []*extractor.Inventory{
{
Name: "async-timeout",
Version: "5.0.1",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{"optional"},
},
},
{
Name: "factory-boy",
Version: "3.3.1",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{"dev"},
},
},
{
Name: "faker",
Version: "33.3.0",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{"dev", "test"},
},
},
{
Name: "proto-plus",
Version: "1.22.0",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{},
},
},
{
Name: "proto-plus",
Version: "1.23.0",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{},
},
},
{
Name: "protobuf",
Version: "4.25.5",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{},
},
},
{
Name: "python-dateutil",
Version: "2.9.0.post0",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{"dev", "test"},
},
},
{
Name: "six",
Version: "1.17.0",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{},
},
},
{
Name: "typing-extensions",
Version: "4.12.2",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{"dev", "test"},
},
},
{
Name: "urllib3",
Version: "2.3.0",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{"dev"},
},
},
{
Name: "redis",
Version: "5.2.1",
Locations: []string{"testdata/multiple-packages.v2.lock"},
Metadata: osv.DepGroupMetadata{
DepGroupVals: []string{"optional"},
},
},
},
},
}

for _, tt := range tests {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand.

[[package]]
name = "async-timeout"
version = "5.0.1"
description = "Timeout context manager for asyncio programs"
optional = true
python-versions = ">=3.8"
groups = ["main"]
markers = "extra == \"caching\" and python_full_version < \"3.11.3\""
files = [
{file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"},
{file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"},
]

[[package]]
name = "factory-boy"
version = "3.3.1"
description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby."
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "factory_boy-3.3.1-py2.py3-none-any.whl", hash = "sha256:7b1113c49736e1e9995bc2a18f4dbf2c52cf0f841103517010b1d825712ce3ca"},
{file = "factory_boy-3.3.1.tar.gz", hash = "sha256:8317aa5289cdfc45f9cae570feb07a6177316c82e34d14df3c2e1f22f26abef0"},
]

[package.dependencies]
Faker = ">=0.7.0"

[package.extras]
dev = ["Django", "Pillow", "SQLAlchemy", "coverage", "flake8", "isort", "mongoengine", "mongomock", "mypy", "tox", "wheel (>=0.32.0)", "zest.releaser[recommended]"]
doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"]

[[package]]
name = "faker"
version = "33.3.0"
description = "Faker is a Python package that generates fake data for you."
optional = false
python-versions = ">=3.8"
groups = ["dev", "test"]
files = [
{file = "Faker-33.3.0-py3-none-any.whl", hash = "sha256:ae074d9c7ef65817a93b448141a5531a16b2ea2e563dc5774578197c7c84060c"},
{file = "faker-33.3.0.tar.gz", hash = "sha256:2abb551a05b75d268780b6095100a48afc43c53e97422002efbfc1272ebf5f26"},
]

[package.dependencies]
python-dateutil = ">=2.4"
typing-extensions = "*"

[[package]]
name = "proto-plus"
version = "1.22.0"
description = "Beautiful, Pythonic protocol buffers."
optional = false
python-versions = ">=3.6"
groups = ["main"]
markers = "python_version < \"3.10\""
files = [
{file = "proto-plus-1.22.0.tar.gz", hash = "sha256:c2e6693fdf68c405a6428226915a8625d21d0513793598ae3287a1210478d8ec"},
{file = "proto_plus-1.22.0-py3-none-any.whl", hash = "sha256:a27192d8cdc54e044f137b4c9053c9108cf5c065b46d067f1bcd389a911faf5b"},
]

[package.dependencies]
protobuf = ">=3.19.0,<5.0.0dev"

[package.extras]
testing = ["google-api-core[grpc] (>=1.31.5)"]

[[package]]
name = "proto-plus"
version = "1.23.0"
description = "Beautiful, Pythonic protocol buffers."
optional = false
python-versions = ">=3.6"
groups = ["main"]
markers = "python_version >= \"3.10\""
files = [
{file = "proto-plus-1.23.0.tar.gz", hash = "sha256:89075171ef11988b3fa157f5dbd8b9cf09d65fffee97e29ce403cd8defba19d2"},
{file = "proto_plus-1.23.0-py3-none-any.whl", hash = "sha256:a829c79e619e1cf632de091013a4173deed13a55f326ef84f05af6f50ff4c82c"},
]

[package.dependencies]
protobuf = ">=3.19.0,<5.0.0dev"

[package.extras]
testing = ["google-api-core[grpc] (>=1.31.5)"]

[[package]]
name = "protobuf"
version = "4.25.5"
description = ""
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "protobuf-4.25.5-cp310-abi3-win32.whl", hash = "sha256:5e61fd921603f58d2f5acb2806a929b4675f8874ff5f330b7d6f7e2e784bbcd8"},
{file = "protobuf-4.25.5-cp310-abi3-win_amd64.whl", hash = "sha256:4be0571adcbe712b282a330c6e89eae24281344429ae95c6d85e79e84780f5ea"},
{file = "protobuf-4.25.5-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:b2fde3d805354df675ea4c7c6338c1aecd254dfc9925e88c6d31a2bcb97eb173"},
{file = "protobuf-4.25.5-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:919ad92d9b0310070f8356c24b855c98df2b8bd207ebc1c0c6fcc9ab1e007f3d"},
{file = "protobuf-4.25.5-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fe14e16c22be926d3abfcb500e60cab068baf10b542b8c858fa27e098123e331"},
{file = "protobuf-4.25.5-cp38-cp38-win32.whl", hash = "sha256:98d8d8aa50de6a2747efd9cceba361c9034050ecce3e09136f90de37ddba66e1"},
{file = "protobuf-4.25.5-cp38-cp38-win_amd64.whl", hash = "sha256:b0234dd5a03049e4ddd94b93400b67803c823cfc405689688f59b34e0742381a"},
{file = "protobuf-4.25.5-cp39-cp39-win32.whl", hash = "sha256:abe32aad8561aa7cc94fc7ba4fdef646e576983edb94a73381b03c53728a626f"},
{file = "protobuf-4.25.5-cp39-cp39-win_amd64.whl", hash = "sha256:7a183f592dc80aa7c8da7ad9e55091c4ffc9497b3054452d629bb85fa27c2a45"},
{file = "protobuf-4.25.5-py3-none-any.whl", hash = "sha256:0aebecb809cae990f8129ada5ca273d9d670b76d9bfc9b1809f0a9c02b7dbf41"},
{file = "protobuf-4.25.5.tar.gz", hash = "sha256:7f8249476b4a9473645db7f8ab42b02fe1488cbe5fb72fddd445e0665afd8584"},
]

[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
description = "Extensions to the standard Python datetime module"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
groups = ["dev", "test"]
files = [
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
]

[package.dependencies]
six = ">=1.5"

[[package]]
name = "redis"
version = "5.2.1"
description = "Python client for Redis database and key-value store"
optional = true
python-versions = ">=3.8"
groups = ["main"]
markers = "extra == \"caching\""
files = [
{file = "redis-5.2.1-py3-none-any.whl", hash = "sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4"},
{file = "redis-5.2.1.tar.gz", hash = "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f"},
]

[package.dependencies]
async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""}

[package.extras]
hiredis = ["hiredis (>=3.0.0)"]
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==23.2.1)", "requests (>=2.31.0)"]

[[package]]
name = "six"
version = "1.17.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
groups = ["main", "dev", "test"]
files = [
{file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
{file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
]

[[package]]
name = "typing-extensions"
version = "4.12.2"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
groups = ["dev", "test"]
files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
]

[[package]]
name = "urllib3"
version = "2.3.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"},
{file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"},
]

[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]

[extras]
caching = ["redis"]

[metadata]
lock-version = "2.1"
python-versions = ">=3.9"
content-hash = "ab8a643d59b9404536d1a035b0f7324ca1e2b906b5a69cf6ae8321a65efc3870"

0 comments on commit 147bdb5

Please sign in to comment.