Skip to content

Commit

Permalink
feat: support parsing pdm.lock files (#245)
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Feb 1, 2024
1 parent 8f29dc8 commit 363515b
Show file tree
Hide file tree
Showing 14 changed files with 374 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ The detector supports parsing the following lockfiles:
| `mix.lock` | `Hex` | `mix` |
| `poetry.lock` | `PyPI` | `poetry` |
| `Pipfile.lock` | `PyPI` | `pipenv` |
| `pdm.lock` | `PyPI` | `pdm` |
| `pubspec.lock` | `Pub` | `pub` |
| `pom.xml`\* | `Maven` | `maven` |
| `requirements.txt`\* | `PyPI` | `pip` |
Expand Down
1 change: 1 addition & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func TestRun(t *testing.T) {
mix.lock
package-lock.json
packages.lock.json
pdm.lock
Pipfile.lock
pnpm-lock.yaml
poetry.lock
Expand Down
4 changes: 2 additions & 2 deletions pkg/lockfile/ecosystems_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ func TestKnownEcosystems(t *testing.T) {
expectedCount := numberOfLockfileParsers(t)

// - npm, yarn, and pnpm,
// - pip, poetry, and pipenv,
// - pip, poetry, pdm and pipenv,
// - maven and gradle,
// all use the same ecosystem so "ignore" those parsers in the count
expectedCount -= 5
expectedCount -= 6

ecosystems := lockfile.KnownEcosystems()

Expand Down
42 changes: 42 additions & 0 deletions pkg/lockfile/fixtures/pdm/dev-dependency.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This file is @generated by PDM.
# It is not intended for manual editing.

[metadata]
groups = ["default", "dev"]
strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1"
content_hash = "sha256:5a543e4cbf50fa2fae6c9180c8c4b4031bbaf7e95c26484384109782ebdfd647"

[[package]]
name = "pyroute2"
version = "0.7.11"
summary = "Python Netlink library"
groups = ["dev"]
dependencies = [
"win-inet-pton; platform_system == \"Windows\"",
]
files = [
{file = "pyroute2-0.7.11-py3-none-any.whl", hash = "sha256:95852e702149b3d6abc8484d3291c38c45660168e8db76e5566a60ef0e133d5b"},
]

[[package]]
name = "toml"
version = "0.10.2"
requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python Library for Tom's Obvious, Minimal Language"
groups = ["default"]
files = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]

[[package]]
name = "win-inet-pton"
version = "1.1.0"
summary = "Native inet_pton and inet_ntop implementation for Python on Windows (with ctypes)."
groups = ["dev"]
marker = "platform_system == \"Windows\""
files = [
{file = "win_inet_pton-1.1.0-py2.py3-none-any.whl", hash = "sha256:eaf0193cbe7152ac313598a0da7313fb479f769343c0c16c5308f64887dc885b"},
{file = "win_inet_pton-1.1.0.tar.gz", hash = "sha256:dd03d942c0d3e2b1cf8bab511844546dfa5f74cb61b241699fa379ad707dea4f"},
]
8 changes: 8 additions & 0 deletions pkg/lockfile/fixtures/pdm/empty.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file is @generated by PDM.
# It is not intended for manual editing.

[metadata]
groups = ["default"]
strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1"
content_hash = "sha256:ebb844511b46d2da311c9adf39499a26883e110605ef99ca9c6762905dcb3e56"
17 changes: 17 additions & 0 deletions pkg/lockfile/fixtures/pdm/git-dependency.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# This file is @generated by PDM.
# It is not intended for manual editing.

[metadata]
groups = ["default"]
strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1"
content_hash = "sha256:93fc3209615f0fa4a29b2bd263bb5e72c2343ebc334df8c56c5d9f2cacfc0241"

[[package]]
name = "toml"
version = "0.10.2"
requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
git = "https://github.com/uiri/toml.git"
revision = "65bab7582ce14c55cdeec2244c65ea23039c9e6f"
summary = "Python Library for Tom's Obvious, Minimal Language"
groups = ["default"]
1 change: 1 addition & 0 deletions pkg/lockfile/fixtures/pdm/not-toml.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this is not valid toml! (I think)
42 changes: 42 additions & 0 deletions pkg/lockfile/fixtures/pdm/optional-dependency.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This file is @generated by PDM.
# It is not intended for manual editing.

[metadata]
groups = ["default", "tmp"]
strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1"
content_hash = "sha256:dfa3dd060fb1217f183be92d3a42fc9b77ca2ca340a7ac15c6786de5bbced943"

[[package]]
name = "pyroute2"
version = "0.7.11"
summary = "Python Netlink library"
groups = ["tmp"]
dependencies = [
"win-inet-pton; platform_system == \"Windows\"",
]
files = [
{file = "pyroute2-0.7.11-py3-none-any.whl", hash = "sha256:95852e702149b3d6abc8484d3291c38c45660168e8db76e5566a60ef0e133d5b"},
]

[[package]]
name = "toml"
version = "0.10.2"
requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python Library for Tom's Obvious, Minimal Language"
groups = ["default"]
files = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]

[[package]]
name = "win-inet-pton"
version = "1.1.0"
summary = "Native inet_pton and inet_ntop implementation for Python on Windows (with ctypes)."
groups = ["tmp"]
marker = "platform_system == \"Windows\""
files = [
{file = "win_inet_pton-1.1.0-py2.py3-none-any.whl", hash = "sha256:eaf0193cbe7152ac313598a0da7313fb479f769343c0c16c5308f64887dc885b"},
{file = "win_inet_pton-1.1.0.tar.gz", hash = "sha256:dd03d942c0d3e2b1cf8bab511844546dfa5f74cb61b241699fa379ad707dea4f"},
]
19 changes: 19 additions & 0 deletions pkg/lockfile/fixtures/pdm/single-package.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This file is @generated by PDM.
# It is not intended for manual editing.

[metadata]
groups = ["default"]
strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1"
content_hash = "sha256:0cee617a22cf58c87c4b154a4a31e08351b4e38f471f6c82edbb1ee185bda2cf"

[[package]]
name = "toml"
version = "0.10.2"
requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python Library for Tom's Obvious, Minimal Language"
groups = ["default"]
files = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
30 changes: 30 additions & 0 deletions pkg/lockfile/fixtures/pdm/two-packages.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file is @generated by PDM.
# It is not intended for manual editing.

[metadata]
groups = ["default"]
strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1"
content_hash = "sha256:0acb7cdc3e805d9bec1f3347b79b69d92ba257d2cd82b5ef4355010930d46deb"

[[package]]
name = "six"
version = "1.16.0"
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python 2 and 3 compatibility utilities"
groups = ["default"]
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]

[[package]]
name = "toml"
version = "0.10.2"
requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python Library for Tom's Obvious, Minimal Language"
groups = ["default"]
files = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
57 changes: 57 additions & 0 deletions pkg/lockfile/parse-pdm-lock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package lockfile

import (
"fmt"
"os"

"github.com/BurntSushi/toml"
)

type PdmLockPackage struct {
Name string `toml:"name"`
Version string `toml:"version"`
Groups []string `toml:"groups"`
Revision string `toml:"revision"`
}

type PdmLockFile struct {
Version string `toml:"lock-version"`
Packages []PdmLockPackage `toml:"package"`
}

const PdmEcosystem = PipEcosystem

func ParsePdmLock(pathToLockfile string) ([]PackageDetails, error) {
var parsedLockfile *PdmLockFile

lockfileContents, err := os.ReadFile(pathToLockfile)

if err != nil {
return []PackageDetails{}, fmt.Errorf("could not read %s: %w", pathToLockfile, err)
}

err = toml.Unmarshal(lockfileContents, &parsedLockfile)

if err != nil {
return []PackageDetails{}, fmt.Errorf("could not parse %s: %w", pathToLockfile, err)
}

packages := make([]PackageDetails, 0, len(parsedLockfile.Packages))

for _, pkg := range parsedLockfile.Packages {
details := PackageDetails{
Name: pkg.Name,
Version: pkg.Version,
Ecosystem: PdmEcosystem,
CompareAs: PdmEcosystem,
}

if pkg.Revision != "" {
details.Commit = pkg.Revision
}

packages = append(packages, details)
}

return packages, nil
}

0 comments on commit 363515b

Please sign in to comment.