Skip to content

Conversation

@mbabauer
Copy link

…git-cliff/issues/1080)

Description

This is an attempt to fix the issue described in Issue #1080.

Motivation and Context

When multiple tags are included in the next release and the tags jump up in digit size, ex moving from 1.9.0 to 1.10.0, the "highest" version was being identified as 1.9.0 due to the tags being sorted alphabetically instead of by the actual version. This causes the next version to be misidentified as 1.10.0 instead of 1.11.0.

The semantic_version_compare function attempts to sort by version. If it fails, it should fall back to alphabetical sort (see like 589). All my changes were to repo.rs. The other files are the results of me running the cargo +nightly fmt. I am fairly new to the Rust toolchain so if that's not correct and you need me to revert those changes I can.

This is an attempt to fix Issue #1080.

How Has This Been Tested?

  1. First, I create a unit test to recreate the issue. The test creates tags v0.9.0, v0.10.0 and v0.11.0 on a temporary repo. The test breaks because it sorted the v0.9.0 tag would sort to the end of the vector. Once I could see it happening in a repeatable test I...
  2. Created the fix so that the test passed. In the test I should expect the sorted order to be: v0.9.0, v0.10.0 then v0.11.0.
  3. I also included a unit test to test the new semantic_version_compare function to have a complete set of tests. It tries to test some "edge" cases, like ensuring v1.0 is less than v1.0.0 and how to handle things like alpha releases and the fall-back to alpha-sorting when the comparison is between 2 non- Semver strings.

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (no code change)
  • Refactor (refactoring production code)
  • Other - formatting changes due to running the formatter tool

Checklist:

  • My code follows the code style of this project.
  • I have updated the documentation accordingly.
  • I have formatted the code with rustfmt.
  • I checked the lints with clippy.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@mbabauer mbabauer requested a review from orhun as a code owner July 28, 2025 13:36
@welcome
Copy link

welcome bot commented Jul 28, 2025

Thanks for opening this pull request! Please check out our contributing guidelines! ⛰️

@codecov-commenter
Copy link

codecov-commenter commented Jul 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 42.41%. Comparing base (8b5a547) to head (16f526a).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1227      +/-   ##
==========================================
+ Coverage   41.59%   42.41%   +0.82%     
==========================================
  Files          22       22              
  Lines        1919     1948      +29     
==========================================
+ Hits          798      826      +28     
- Misses       1121     1122       +1     
Flag Coverage Δ
unit-tests 42.41% <100.00%> (+0.82%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@orhun
Copy link
Owner

orhun commented Jul 28, 2025

Thanks for the PR! I might need to get myself up-to-date with that issue again to understand the changes here so give me some time.

In the meantime, there seems to be unrelated formatting changes in this PR. Can you run cargo +nightly fmt instead and commit the results?

@mbabauer
Copy link
Author

Ok, took a few attempts to get my toolchain setup right apparently, but I think I have all the changes in. Let me know if you see any further updates needed.

Copy link
Owner

@orhun orhun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking pretty good! I had some questions and suggestions.

Also, can you please adjust the PR title accordingly? It should mention what is being added/changed in this PR instead of a general message like the current one.

Comment on lines +1132 to +1133
/// This test simulates the scenario described in GitHub issue #1080 where v0.10.0
/// was incorrectly considered "less than" v0.9.0 due to alphabetical sorting.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// This test simulates the scenario described in GitHub issue #1080 where v0.10.0
/// was incorrectly considered "less than" v0.9.0 due to alphabetical sorting.
/// This test simulates the scenario described in GitHub issue [#1080] where v0.10.0
/// was incorrectly considered "less than" v0.9.0 due to alphabetical sorting.
///
/// [#1080]: https://github.com/orhun/git-cliff/issues/1080

Ordering::Less
);

// Test pre-release vs release (lines 574-575)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pointing out to lines that might change in the future does not make sense, can you remove them and reference to the function instead?

Comment on lines +1115 to +1123
// Test the specific case from the GitHub issue
assert_eq!(
semantic_version_compare("v0.9.0", "v0.10.0"),
Ordering::Less
);
assert_eq!(
semantic_version_compare("v0.10.0", "v0.11.0"),
Ordering::Less
);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear which GitHub issue we are referring to here, it should be linked or the comment should be made more clear

Comment on lines +471 to +473
if time_cmp == std::cmp::Ordering::Equal {
// When commit times are equal, sort by semantic version
semantic_version_compare(&a.1.name, &b.1.name)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I understood how this fixes #1080... In that issue we didn't talk about commit times being equal etc. but we are doing a a check here.

Can you explain it further?

Comment on lines +523 to +527
/// This function attempts to parse version strings and compare them semantically
/// rather than alphabetically. It handles common version formats like:
/// - v1.2.3
/// - 1.2.3
/// - v1.2.3-alpha.1
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
/// This function attempts to parse version strings and compare them semantically
/// rather than alphabetically. It handles common version formats like:
/// - v1.2.3
/// - 1.2.3
/// - v1.2.3-alpha.1
/// This function attempts to parse version strings and compare them semantically
/// rather than alphabetically. It handles common version formats like:
///
/// - v1.2.3
/// - 1.2.3
/// - v1.2.3-alpha.1

use std::cmp::Ordering;

// Helper function to extract version parts and pre-release info
let parse_version = |version: &str| -> Option<(Vec<u64>, Option<String>)> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, Option<(Vec<u64>, Option<String>)> is a bit complex. Do you think defining an inner struct would make the code better in terms of readability? 🤔

Comment on lines +574 to +577
(Some(_), None) => Ordering::Less, // pre-release < release
(None, Some(_)) => Ordering::Greater, // release > pre-release
(Some(pre_a), Some(pre_b)) => pre_a.cmp(&pre_b), /* alphabetical for
* pre-release */
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments seem a bit off here. Maybe use this format:

// pre-release < release
(Some(_), None) => Ordering::Less,
etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Version tags don't get sorted topologically?

3 participants