8000 SNAPSHOT version downloaded from remote is always the first published · Issue #3416 · coursier/coursier · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
SNAPSHOT version downloaded from remote is always the first published #3416
Open
@Iilun

Description

@Iilun

Hello everyone, first of all thank you for your work on this project !

I have recently switched workflow to use snapshot versions built on remote, and ran into the following issue (I think it might be due to the fact that I use the github maven package registry).

The maven-metadata.xml for the snapshot version looks like this:

<metadata modelVersion="">
    <groupId>com.example</groupId>
    <artifactId>artifact</artifactId>
    <version>2.5.x-SNAPSHOT</version>
    <versioning>
        <snapshot>
            <timestamp>20250522.153927</timestamp>
            <buildNumber>2</buildNumber>
        </snapshot>
        <lastUpdated>20250521153923</lastUpdated>
        <snapshotVersions>
            <snapshotVersion>
                <extension>jar</extension>
                <value>2.5.x-20250521.153917-1</value>
                <updated>20250521153920</updated>
            </snapshotVersion>
            <snapshotVersion>
                <extension>jar.sha1</extension>
                <value>2.5.x-20250521.153917-1</value>
                <updated>20250521153921</updated>
            </snapshotVersion>
            <snapshotVersion>
                <extension>jar.md5</extension>
                <value>2.5.x-20250521.153917-1</value>
                <updated>20250521153923</updated>
            </snapshotVersion>
            <snapshotVersion>
                <extension>jar</extension>
                <value>2.5.x-20250522.153927-2</value>
                <updated>20250522153924</updated>
            </snapshotVersion>
            <snapshotVersion>
                <extension>jar.sha1</extension>
                <value>2.5.x-20250522.153927-2</value>
                <updated>20250522153926</updated>
            </snapshotVersion>
            <snapshotVersion>
                <extension>jar.md5</extension>
                <value>2.5.x-20250522.153927-2</value>
                <updated>20250522153927</updated>
            </snapshotVersion>
        </snapshotVersions>
    </versioning>
</metadata>

As you can see, both snapshot builds are still present in the metadata file. With this configuration, coursier always fetches the first built JAR (effective version 2.5.x-20250521.153917-1), whereas the mvn dependency:get command correctly fetches the latest one (effective version 2.5.x-20250522.153927-2), which is the expected behavior.

From my research on the topic, this is due to different snapshot version handling between maven and coursier.

Maven

As seen in the maven implementation, the buildNumber is taken into account and the computation is the following:

  • removing the SNAPSHOT suffix
  • adding the timestamp
  • adding a dash
  • adding the buildNumber

Coursier

For coursier, the logic is here. As of today, this logic is the following:

  • looping on each snapshotVersion
  • taking the first one that has the correct classifier and extension

Proposed solution

I would suggest mimicking the effective version computation from maven, that would result in the following code (syntax may not follow project standards, just to give a rough idea)

def mavenVersioning(
                     snapshotVersioning: SnapshotVersioning,
                     classifier: Classifier,
                     extension: Extension
                   ): Option[Version] =
  snapshotVersioning.buildNumber flatMap {
    buildNumber =>
      // Compute the latest jar expected based on timestamp and buildNumber
      val latestBuildValue = s"${snapshotVersioning.version0.asString.stripSuffix("SNAPSHOT")}${snapshotVersioning.timestamp}-$buildNumber"

      // Make sure it is in the list, otherwise fallback to previous computation (first snapshot version)
      snapshotVersioning
        .snapshotVersions
        .collectFirst { case v if
          (v.classifier == classifier || v.classifier == Classifier("*")) &&
            (v.extension == extension || v.extension == Extension("*")) &&
            (v.value0.asString == latestBuildValue) => v.value0
        }
  } orElse {
    snapshotVersioning
      .snapshotVersions
      .find { v =>
        (v.classifier == classifier || v.classifier == Classifier("*")) &&
          (v.extension == extension || v.extension == Extension("*"))
      }
      .map(_.value0)
      .filter(_.asString.nonEmpty)
  }

This does pass mill compilation and from my testing retrieves the same version as maven from the metadata file.

I could open a PR if required and I am open for feedback.

Thank you for your time !

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0