Compose Metadata Analyzer: Refactor to support V2 and V1 repositories#4470
Conversation
72be736 to
22b55f7
Compare
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferencesCodacy stopped sending the deprecated coverage status on June 5th, 2024. Learn more |
|
The current code only works with repositories that use the default url pattern for package metadata: More extensive changes are needed to support repositories that use a different url pattern, or provide the package metadata inline. Those changes should go into a different PR so we can keep this PR here simple. Hopefully that helpts to get this PR merged/released before Composer V1 stops providing new metadata (February 1st 2025) |
So this really could (should!) go out in the 4.12.3 bugfix release then. Even if we get 4.13 out before Feb, not everyone will upgrade non-bugfix releases immediately. So better play it safe and get it out sooner. |
ab8a30d to
eb80260
Compare
|
Even better. Didn't know if you'd want it in a bugfix release, but it's not too big of a change. |
|
Looks like some third party repositories still expose their (meta)data in V1 format. Example https://packages.shopware.com. |
|
After a good nights sleep I realized we should just look at https://github.com/composer/composer/blob/main/src/Composer/Repository/ComposerRepository.php and mimic what is done there. The approach in #4435 may work for the short term, but it will result in lots of failing (404) requests for V2 meatada to repositories that are still V1. |
|
Turns out that do it right, we need to retrieve the Some talking points:
Valentijn |
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferencesCodacy stopped sending the deprecated coverage status on June 5th, 2024. Learn more |
Signed-off-by: Valentijn Scholten <valentijnscholten@gmail.com>
c43f64e to
b73448d
Compare
Signed-off-by: Valentijn Scholten <valentijnscholten@gmail.com>
src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java
Show resolved
Hide resolved
src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java
Outdated
Show resolved
Hide resolved
src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java
Outdated
Show resolved
Hide resolved
src/main/java/org/dependencytrack/tasks/repositories/ComposerMetaAnalyzer.java
Outdated
Show resolved
Hide resolved
I don't see a problem in providing more info, like the repository type and identifier. Don't think we should pass the entire
Added a comment about that, it should be possible to avoid this conflict in tests by instructing WireMock to use a dynamic port.
That would be great. |
I suggest we replace the existing |
Signed-off-by: Valentijn Scholten <valentijnscholten@gmail.com>
037f62c to
2e2a8bd
Compare
Trimmed them down. |
Signed-off-by: Valentijn Scholten <valentijnscholten@gmail.com>
|
|
||
| if (StringUtils.trimToNull(model.getLatestVersion()) != null) { | ||
| // Resolution from repository was successful. Update meta model | ||
| //FIXME What happens if multiple repositories return a metamodel result with different lastPublishedTimestamps? |
There was a problem hiding this comment.
The repository loop is broken out of upon encounter of the first matching repository, via the break in line 243.
There was a problem hiding this comment.
Yeah, that's what made me wonder. I noticed some components are published in multiple repositories. For example phpunit. I came across a third part repo that published an older version of phpunit. If DT ends up using that release as latest, it might draw the wrong conclusion. Might be safer to analyze all repositories and take the global latest release. But that could be wrong as well if some repo publish a release with some changes/fixes with a higher version number. Not sure how DT handles the suffixes like p1, p2, redhat1, etc.
There was a problem hiding this comment.
There is no bullet-proof way to determine what the "correct" repository or version is, at least none I am aware of. Hence the current strategy that will work most of the time, is to pick the first match. The strategy assumes that authoritative repositories (i.e. Maven Central for Maven) are checked first, which ATM is ensured via the resolution order.
Not sure how DT handles the suffixes like p1, p2, redhat1, etc.
It's not possible to handle such things generically. #2826 might help, but only as long as whoever adds these suffixes abides to the ecosystem's de-facto standard notation.
src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java
Outdated
Show resolved
Hide resolved
src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Valentijn Scholten <valentijnscholten@gmail.com>
Signed-off-by: Valentijn Scholten <valentijnscholten@gmail.com>
Description
Use Composer Repository V2 url for metadata as v1 is deprecated. The https://repo.packagist.org and its private counterparts at packagist.com are becoming read only to clients that request V1 metdata.
This PR adds support for V2 for all repositories. It also keeps and improves V1 support as lots of third party repositories are still in V1 mode. The V1 support in DT was very minimal and this PR ads more constructs such as packages included in the main
packages.jsonfile and the user ofavailable-packagesandavailable-package-patternsto only query for applicable packages.I analyzed a number of real world projects and looked at all the composer repositories and how those were handled by Composer. The implementation is based on the docs found in https://github.com/composer/composer. The docs are a bit ambiguous / unclear sometimes, so I also looked at the source code. I confirmed the behaviour by looking at real worl requests/responses sent by the Composer CLI.
Test cases are added.
Addressed Issue
Fixes #2337
Additional Details
The metadata being returned for V2 has the same format as V1, except that the releases for a package are returned as an Array instead of a JSONObject (minified is what Composer calls this).
One thing that changed is how non-existing (or no longer existing) packages are being handled:
Checklist