diff options
| author | Leitwolf11 | 2026-11-14 22:03:45 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-11-14 22:03:45 +0300 |
| commit | 2d21d2e0f9c6e0789e9c55d6cba611234dc61a60 (patch) | |
| tree | 6750468ab3926a4c3cdcaed7a826a730708c6b72 /tools/Versions.cpp | |
| parent | 94a996a3ceafa9f0004ffc28a7de5c543cdb51c2 (diff) | |
| download | catch3-2d21d2e0f9c6e0789e9c55d6cba611234dc61a60.tar.gz | |
Number versions MAJOR.MINOR.PATCH in the version tool
Progmasoft repositories use Semantic Versioning since 2026-11-12, but
//tools:version still knew the four-number counters: given 0.4.0 it
wrote 0.4.0.0 everywhere, and --next stepped the fourth number.
- A Version is three numbers; ParseVersion takes exactly three, without
leading zeros, and FormatVersion writes three.
- --next is the next patch release. It also follows a four-number
version as the rule says: the fourth number goes and the patch rises,
so 0.3.0.2 is followed by 0.3.1.
- ReleaseNotesOf finds a section by the version it was published as.
Its fallback for "D = 0" read the fourth element of what is now a
three-element array; it is gone.
- Tests for the new parsing, NextPatch and release-note lookup;
docs/contributing.md and the tool's usage say what the tool does.
Claude-Session: https://claude.ai/code/session_01Ji7xZMYjc4zankoc7hGBE1
Diffstat (limited to 'tools/Versions.cpp')
| -rw-r--r-- | tools/Versions.cpp | 104 |
1 files changed, 46 insertions, 58 deletions
diff --git a/tools/Versions.cpp b/tools/Versions.cpp index abc6d5b3..acc0fb4e 100644 --- a/tools/Versions.cpp +++ b/tools/Versions.cpp @@ -17,72 +17,67 @@ namespace Progmasoft::Catch3::Tools = "src/Progmasoft/Catch3/Version.hpp"; } // namespace - std::optional<Version> - ParseVersion(std::string_view text) + namespace { - Version version{}; - std::size_t count = 0; - while (true) + /// The dot-separated numbers of `text`, at most `limit` of them, none + /// empty or with a leading zero; nothing for anything else. + std::optional<std::vector<unsigned>> + Numbers(std::string_view text, std::size_t limit) { - const auto dot = text.find('.'); - const auto number = text.substr(0, dot); - if (count == version.size() || number.empty() - || (number.size() > 1 && number.front() == '0')) + std::vector<unsigned> numbers; + while (true) { - return std::nullopt; + const auto dot = text.find('.'); + const auto number = text.substr(0, dot); + if (numbers.size() == limit || number.empty() + || (number.size() > 1 && number.front() == '0')) + { + return std::nullopt; + } + unsigned value = 0; + const auto *end = number.data() + number.size(); + const auto parsed = std::from_chars(number.data(), end, value); + if (parsed.ec != std::errc{} || parsed.ptr != end) + { + return std::nullopt; + } + numbers.push_back(value); + if (dot == std::string_view::npos) + { + return numbers; + } + text.remove_prefix(dot + 1); } - const auto *end = number.data() + number.size(); - const auto parsed - = std::from_chars(number.data(), end, version[count]); - if (parsed.ec != std::errc{} || parsed.ptr != end) - { - return std::nullopt; - } - ++count; - if (dot == std::string_view::npos) - { - break; - } - text.remove_prefix(dot + 1); } - if (count < 3) + } // namespace + + std::optional<Version> + ParseVersion(std::string_view text) + { + const auto numbers = Numbers(text, 3); + if (!numbers || numbers->size() != 3) { return std::nullopt; } - return version; + return Version{ (*numbers)[0], (*numbers)[1], (*numbers)[2] }; } std::string FormatVersion(const Version &version) { return std::to_string(version[0]) + "." + std::to_string(version[1]) - + "." + std::to_string(version[2]) + "." - + std::to_string(version[3]); + + "." + std::to_string(version[2]); } - Version - NextVersion(Version version) + std::optional<Version> + NextPatch(std::string_view current) { - if (version[3] < 9) + const auto numbers = Numbers(current, 4); + if (!numbers || numbers->size() < 3) { - ++version[3]; - return version; - } - version[3] = 0; - if (version[2] < 9) - { - ++version[2]; - return version; - } - version[2] = 0; - if (version[1] < 19) - { - ++version[1]; - return version; + return std::nullopt; } - version[1] = 0; - ++version[0]; - return version; + return Version{ (*numbers)[0], (*numbers)[1], (*numbers)[2] + 1 }; } const std::array<VersionSite, 5> & @@ -211,17 +206,10 @@ namespace Progmasoft::Catch3::Tools std::optional<std::string> ReleaseNotesOf(std::string_view notes, std::string_view version) { - auto heading = "\n## " + std::string{ version } + "\n"; - auto found = notes.find(heading); - // A release with D = 0 may be headed by its three numbers. - const auto parsed = ParseVersion(version); - if (found == std::string_view::npos && parsed && (*parsed)[3] == 0) - { - heading = "\n## " + std::to_string((*parsed)[0]) + "." - + std::to_string((*parsed)[1]) + "." - + std::to_string((*parsed)[2]) + "\n"; - found = notes.find(heading); - } + // Every release is headed by its version as it was published: three + // numbers, or four for the releases before Semantic Versioning. + const auto heading = "\n## " + std::string{ version } + "\n"; + const auto found = notes.find(heading); if (found == std::string_view::npos) { return std::nullopt; |