diff options
| author | Leitwolf | 2026-11-15 12:15:51 +0300 |
|---|---|---|
| committer | GitHub | 2026-11-15 12:15:51 +0300 |
| commit | ac438d0c34d89e14d51aebe3b0314c7e38000bb8 (patch) | |
| tree | 537504b761ed21b6fe821aebbbf9eab6b398d054 /tools/Versions.cpp | |
| parent | 94a996a3ceafa9f0004ffc28a7de5c543cdb51c2 (diff) | |
| parent | e2905c736cf2e36965c071c21bc7911eb3c59a7b (diff) | |
| download | catch3-ac438d0c34d89e14d51aebe3b0314c7e38000bb8.tar.gz | |
Merge pull request #41 from Progmasoft/fix/version-tool-semver
Number versions MAJOR.MINOR.PATCH in the version tool
Diffstat (limited to 'tools/Versions.cpp')
| -rw-r--r-- | tools/Versions.cpp | 108 |
1 files changed, 50 insertions, 58 deletions
diff --git a/tools/Versions.cpp b/tools/Versions.cpp index abc6d5b3..d3ae03cf 100644 --- a/tools/Versions.cpp +++ b/tools/Versions.cpp @@ -4,6 +4,7 @@ #include <algorithm> #include <cctype> #include <charconv> +#include <limits> #include <utility> #include <vector> @@ -17,72 +18,70 @@ 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); + // A patch number at its largest has no next one; adding one would + // wrap around to 0 and move the version back. + if (!numbers || numbers->size() < 3 + || (*numbers)[2] == std::numeric_limits<unsigned>::max()) { - ++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 +210,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; |