From 405e820b0bbb65b5510bb0110c5ec8a47acfc0e1 Mon Sep 17 00:00:00 2001 From: Gabriel Silveira <gabriel.silveira@poli.ufrj.br> Date: Fri, 9 Dec 2022 14:51:46 -0300 Subject: [PATCH 1/2] Add methods to manipulate semantic versions --- spec/std/semantic_version_spec.cr | 32 ++++++++++++++++++++ src/semantic_version.cr | 49 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/spec/std/semantic_version_spec.cr b/spec/std/semantic_version_spec.cr index 9902e1fe46ee..bf0fd7cc42e0 100644 --- a/spec/std/semantic_version_spec.cr +++ b/spec/std/semantic_version_spec.cr @@ -88,6 +88,38 @@ describe SemanticVersion do end end + it "copies with specified modifications" do + base_version = SemanticVersion.new(1, 2, 3, "rc", "0000") + base_version.copy_with(major: 0).should eq SemanticVersion.new(0, 2, 3, "rc", "0000") + base_version.copy_with(minor: 0).should eq SemanticVersion.new(1, 0, 3, "rc", "0000") + base_version.copy_with(patch: 0).should eq SemanticVersion.new(1, 2, 0, "rc", "0000") + base_version.copy_with(prerelease: "alpha").should eq SemanticVersion.new(1, 2, 3, "alpha", "0000") + base_version.copy_with(build: "0001").should eq SemanticVersion.new(1, 2, 3, "rc", "0001") + base_version.copy_with(prerelease: nil, build: nil).should eq SemanticVersion.new(1, 2, 3) + end + + it "bumps to the correct version" do + sversions = %w( + 1.1.1 + 1.2.0 + 1.2.1 + 2.0.0 + 2.0.1 + 2.1.0 + 3.0.0 + ) + versions = sversions.map { |s| SemanticVersion.parse(s) }.to_a + + {% for bump, i in %w(minor patch major patch minor major) %} + versions[{{i}}].bump_{{bump.id}}.should eq versions[{{i + 1}}] + {% end %} + + version_with_prerelease = SemanticVersion.new(1, 2, 3, "rc", "0001") + version_with_prerelease.bump_major.should eq SemanticVersion.new(2, 0, 0) + version_with_prerelease.bump_minor.should eq SemanticVersion.new(1, 3, 0) + version_with_prerelease.bump_patch.should eq SemanticVersion.new(1, 2, 3) + end + describe SemanticVersion::Prerelease do it "compares <" do sprereleases = %w( diff --git a/src/semantic_version.cr b/src/semantic_version.cr index 1e15321a3089..7e6632322d58 100644 --- a/src/semantic_version.cr +++ b/src/semantic_version.cr @@ -82,6 +82,55 @@ struct SemanticVersion end end + # Returns a new `SemanticVersion` created with the specified parts. The + # default for each part is its current value. + # + # ``` + # require "semantic_version" + # + # current_version = SemanticVersion.new 1, 1, 1, "rc" + # current_version.copy_with(patch: 2) # => SemanticVersion(@build=nil, @major=1, @minor=1, @patch=2, @prerelease=SemanticVersion::Prerelease(@identifiers=["rc"])) + # current_version.copy_with(prerelease: nil) # => SemanticVersion(@build=nil, @major=1, @minor=1, @patch=2, @prerelease=SemanticVersion::Prerelease(@identifiers=[])) + def copy_with(major : Int32 = @major, minor : Int32 = @minor, patch : Int32 = @patch, prerelease : String | Prerelease | Nil = @prerelease, build : String? = @build) + SemanticVersion.new major, minor, patch, prerelease, build + end + + # Returns a copy of the current version with a major bump. + # + # ``` + # require "semantic_version" + # + # current_version = SemanticVersion.new 1, 1, 1, "rc" + # current_version.bump_major # => SemanticVersion(@build=nil, @major=2, @minor=0, @patch=0, @prerelease=SemanticVersion::Prerelease(@identifiers=[])) + def bump_major + copy_with(major: major + 1, minor: 0, patch: 0, prerelease: nil, build: nil) + end + + # Returns a copy of the current version with a minor bump. + # + # ``` + # require "semantic_version" + # + # current_version = SemanticVersion.new 1, 1, 1, "rc" + # current_version.bump_minor # => SemanticVersion(@build=nil, @major=1, @minor=2, @patch=0, @prerelease=SemanticVersion::Prerelease(@identifiers=[])) + def bump_minor + copy_with(minor: minor + 1, patch: 0, prerelease: nil, build: nil) + end + + # Returns a copy of the current version with a patch bump. Bumping a patch of + # a prerelease just erase the prerelease data. + # + # ``` + # require "semantic_version" + # + # current_version = SemanticVersion.new 1, 1, 1, "rc" + # next_patch = current_version.bump_patch # => SemanticVersion(@build=nil, @major=1, @minor=1, @patch=1, @prerelease=SemanticVersion::Prerelease(@identifiers=[])) + # next_patch.bump_patch # => SemanticVersion(@build=nil, @major=1, @minor=1, @patch=2, @prerelease=SemanticVersion::Prerelease(@identifiers=[])) + def bump_patch + return copy_with(prerelease: nil, build: nil) unless prerelease.identifiers.empty? + copy_with(patch: patch + 1, prerelease: nil, build: nil) + end + # The comparison operator. # # Returns `-1`, `0` or `1` depending on whether `self`'s version is lower than *other*'s, From 71641d6a19c62871d57903f473587998f46115df Mon Sep 17 00:00:00 2001 From: Gabriel Silveira <gabriel.silveira@poli.ufrj.br> Date: Mon, 12 Dec 2022 12:47:51 -0300 Subject: [PATCH 2/2] Refactor code to make it easier to read --- spec/std/semantic_version_spec.cr | 20 ++++++-------------- src/semantic_version.cr | 7 +++++-- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/spec/std/semantic_version_spec.cr b/spec/std/semantic_version_spec.cr index bf0fd7cc42e0..41403505b776 100644 --- a/spec/std/semantic_version_spec.cr +++ b/spec/std/semantic_version_spec.cr @@ -99,20 +99,12 @@ describe SemanticVersion do end it "bumps to the correct version" do - sversions = %w( - 1.1.1 - 1.2.0 - 1.2.1 - 2.0.0 - 2.0.1 - 2.1.0 - 3.0.0 - ) - versions = sversions.map { |s| SemanticVersion.parse(s) }.to_a - - {% for bump, i in %w(minor patch major patch minor major) %} - versions[{{i}}].bump_{{bump.id}}.should eq versions[{{i + 1}}] - {% end %} + SemanticVersion.new(1, 1, 1).bump_minor.should eq SemanticVersion.new(1, 2, 0) + SemanticVersion.new(1, 2, 0).bump_patch.should eq SemanticVersion.new(1, 2, 1) + SemanticVersion.new(1, 2, 1).bump_major.should eq SemanticVersion.new(2, 0, 0) + SemanticVersion.new(2, 0, 0).bump_patch.should eq SemanticVersion.new(2, 0, 1) + SemanticVersion.new(2, 0, 1).bump_minor.should eq SemanticVersion.new(2, 1, 0) + SemanticVersion.new(2, 1, 0).bump_major.should eq SemanticVersion.new(3, 0, 0) version_with_prerelease = SemanticVersion.new(1, 2, 3, "rc", "0001") version_with_prerelease.bump_major.should eq SemanticVersion.new(2, 0, 0) diff --git a/src/semantic_version.cr b/src/semantic_version.cr index 7e6632322d58..8c35e9998eae 100644 --- a/src/semantic_version.cr +++ b/src/semantic_version.cr @@ -127,8 +127,11 @@ struct SemanticVersion # next_patch = current_version.bump_patch # => SemanticVersion(@build=nil, @major=1, @minor=1, @patch=1, @prerelease=SemanticVersion::Prerelease(@identifiers=[])) # next_patch.bump_patch # => SemanticVersion(@build=nil, @major=1, @minor=1, @patch=2, @prerelease=SemanticVersion::Prerelease(@identifiers=[])) def bump_patch - return copy_with(prerelease: nil, build: nil) unless prerelease.identifiers.empty? - copy_with(patch: patch + 1, prerelease: nil, build: nil) + if prerelease.identifiers.empty? + copy_with(patch: patch + 1, prerelease: nil, build: nil) + else + copy_with(prerelease: nil, build: nil) + end end # The comparison operator.