sycersion 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 296451fb7d60ad509421f5bfdfa718e726a06f7377f063a4f27a5176fc3f8a8c
4
+ data.tar.gz: 8291b661655aed0ccce7f24e085e26185e8f6a43d7bca101c4dfcc77a34911a7
5
+ SHA512:
6
+ metadata.gz: a21a9851fb8b5961565423189306c44ee6189d18c101e5f0c690d97977c11418eb5bd09c04e3ca4b5b80a7a42a05264e1867bba1a4a28eb9c428cb2c5e138f98
7
+ data.tar.gz: 94bcfc3960cc42798e5620f7bb391a10f6d945021e734ae1099bb2f88b333d71faf304aef964d16c324acd606ebe2533eff702be7f7164cffc18e46fab996a3b
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.6
@@ -0,0 +1,3 @@
1
+ ---
2
+ - ".sycersion/version"
3
+ - 0.1.0
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5.7
7
+ before_install: gem install bundler -v 1.17.3
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at pierre@sugaryourcoffee.de. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in sycersion.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,121 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sycersion (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ activesupport (8.0.1)
10
+ base64
11
+ benchmark (>= 0.3)
12
+ bigdecimal
13
+ concurrent-ruby (~> 1.0, >= 1.3.1)
14
+ connection_pool (>= 2.2.5)
15
+ drb
16
+ i18n (>= 1.6, < 2)
17
+ logger (>= 1.4.2)
18
+ minitest (>= 5.1)
19
+ securerandom (>= 0.3)
20
+ tzinfo (~> 2.0, >= 2.0.5)
21
+ uri (>= 0.13.1)
22
+ aruba (1.1.2)
23
+ bundler (>= 1.17, < 3.0)
24
+ childprocess (>= 2.0, < 5.0)
25
+ contracts (>= 0.16.0, < 0.18.0)
26
+ cucumber (>= 2.4, < 7.0)
27
+ rspec-expectations (~> 3.4)
28
+ thor (~> 1.0)
29
+ base64 (0.2.0)
30
+ benchmark (0.4.0)
31
+ bigdecimal (3.1.9)
32
+ builder (3.3.0)
33
+ childprocess (4.1.0)
34
+ concurrent-ruby (1.3.5)
35
+ connection_pool (2.5.0)
36
+ contracts (0.17.2)
37
+ cucumber (6.1.0)
38
+ builder (~> 3.2, >= 3.2.4)
39
+ cucumber-core (~> 9.0, >= 9.0.1)
40
+ cucumber-create-meta (~> 4.0, >= 4.0.0)
41
+ cucumber-cucumber-expressions (~> 12.1, >= 12.1.1)
42
+ cucumber-gherkin (~> 18.1, >= 18.1.0)
43
+ cucumber-html-formatter (~> 13.0, >= 13.0.0)
44
+ cucumber-messages (~> 15.0, >= 15.0.0)
45
+ cucumber-wire (~> 5.0, >= 5.0.1)
46
+ diff-lcs (~> 1.4, >= 1.4.4)
47
+ mime-types (~> 3.3, >= 3.3.1)
48
+ multi_test (~> 0.1, >= 0.1.2)
49
+ sys-uname (~> 1.2, >= 1.2.2)
50
+ cucumber-core (9.0.1)
51
+ cucumber-gherkin (~> 18.1, >= 18.1.0)
52
+ cucumber-messages (~> 15.0, >= 15.0.0)
53
+ cucumber-tag-expressions (~> 3.0, >= 3.0.1)
54
+ cucumber-create-meta (4.0.0)
55
+ cucumber-messages (~> 15.0, >= 15.0.0)
56
+ sys-uname (~> 1.2, >= 1.2.2)
57
+ cucumber-cucumber-expressions (12.1.3)
58
+ cucumber-gherkin (18.1.1)
59
+ cucumber-messages (~> 15.0, >= 15.0.0)
60
+ cucumber-html-formatter (13.0.0)
61
+ cucumber-messages (~> 15.0, >= 15.0.0)
62
+ cucumber-messages (15.0.0)
63
+ protobuf-cucumber (~> 3.10, >= 3.10.8)
64
+ cucumber-tag-expressions (3.0.1)
65
+ cucumber-wire (5.0.1)
66
+ cucumber-core (~> 9.0, >= 9.0.1)
67
+ cucumber-cucumber-expressions (~> 12.1, >= 12.1.1)
68
+ cucumber-messages (~> 15.0, >= 15.0.0)
69
+ diff-lcs (1.5.1)
70
+ drb (2.2.1)
71
+ ffi (1.17.1)
72
+ i18n (1.14.7)
73
+ concurrent-ruby (~> 1.0)
74
+ logger (1.6.5)
75
+ middleware (0.1.0)
76
+ mime-types (3.6.0)
77
+ logger
78
+ mime-types-data (~> 3.2015)
79
+ mime-types-data (3.2025.0107)
80
+ minitest (5.25.4)
81
+ multi_test (0.1.2)
82
+ protobuf-cucumber (3.10.8)
83
+ activesupport (>= 3.2)
84
+ middleware
85
+ thor
86
+ thread_safe
87
+ rake (10.5.0)
88
+ rspec (3.13.0)
89
+ rspec-core (~> 3.13.0)
90
+ rspec-expectations (~> 3.13.0)
91
+ rspec-mocks (~> 3.13.0)
92
+ rspec-core (3.13.2)
93
+ rspec-support (~> 3.13.0)
94
+ rspec-expectations (3.13.3)
95
+ diff-lcs (>= 1.2.0, < 2.0)
96
+ rspec-support (~> 3.13.0)
97
+ rspec-mocks (3.13.2)
98
+ diff-lcs (>= 1.2.0, < 2.0)
99
+ rspec-support (~> 3.13.0)
100
+ rspec-support (3.13.2)
101
+ securerandom (0.4.1)
102
+ sys-uname (1.3.1)
103
+ ffi (~> 1.1)
104
+ thor (1.3.2)
105
+ thread_safe (0.3.6)
106
+ tzinfo (2.0.6)
107
+ concurrent-ruby (~> 1.0)
108
+ uri (1.0.2)
109
+
110
+ PLATFORMS
111
+ ruby
112
+
113
+ DEPENDENCIES
114
+ aruba (~> 1.0)
115
+ bundler (~> 2.0)
116
+ rake (~> 10.0)
117
+ rspec (~> 3.0)
118
+ sycersion!
119
+
120
+ BUNDLED WITH
121
+ 2.2.26
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Pierre Sugar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # Sycersion
2
+
3
+ **sycersion** is a command-line tool to manage application versions following
4
+ the guiding principles of _semantic versioning_ found at
5
+ [semver.org](https://semver.org).
6
+
7
+ **sycersion** has a default start version of 0.1.0. This can be activitated with
8
+ the initalization running `sycersion --init`. During this intialization another
9
+ version can be chosen. The version is saved to the _version-file_ and also the
10
+ _configuration-directory_ is created. While initialization **sycersion**
11
+ additionally searches for files that contain a version according to semantic
12
+ versioning and the user can select out of the list of files which version out of
13
+ that files to intially start with.
14
+
15
+ The _version-file_ and _configuration-directory_ are also created if the user is
16
+ setting an initial version with `sycersion --set 0.1.1`.
17
+
18
+ If the version is updated the version is written into the _version-file_. Within
19
+ the application the version can be read from the file and displayed somewhere in
20
+ the application's UI.
21
+
22
+ **sycersion** evaluates version numbers provided that they comply to semantic
23
+ versioning.
24
+
25
+ ## Installation
26
+
27
+ Add this line to your application's Gemfile:
28
+
29
+ ```ruby
30
+ gem 'sycersion'
31
+ ```
32
+
33
+ And then execute:
34
+
35
+ $ bundle
36
+
37
+ Or install it yourself as:
38
+
39
+ $ gem install sycersion
40
+
41
+ ## Usage
42
+
43
+ * `--init`
44
+ Initializes the **sycersion** environment with _version_ and _version-file_
45
+ * `-i`, `--info VERSION|SUMMARY`
46
+ Shows the current _version_ (default) or additionally information about the
47
+ _version-file_, the _configuration-directory_ and _code_ how to read the
48
+ version within an application.
49
+ * `--inc MAJOR|MINOR|PATCH`
50
+ increments the major, minor, patch part of the version.
51
+ * `--set MAJOR.MINOR.PATCH[+BUILD|-PRE_RELEASE[+BUILD]]`
52
+ sets the version where all three version parts need to be provided,
53
+ major.minor.patch with optionally adding a pre-release part and/or a build
54
+ part.
55
+ * `--pre PRE-RELEASE`
56
+ Set the pre-release part in the version
57
+ * `--build BUILD`
58
+ Set the build part in the version
59
+ * `-c`, `--compare VERSION`
60
+ Compares the current version with the version provided following the semver
61
+ precedence guidline
62
+ * `--help`
63
+ Prints the command line help
64
+
65
+ ## Examples
66
+
67
+ Initialize **sycersion**
68
+
69
+ $ sycersion --init
70
+
71
+ Set the version with a pre-release
72
+
73
+ $ sycersion --set 0.1.1-beta.1.0
74
+
75
+ Set the version with a build
76
+
77
+ $ sycersion --set 0.1.1+build-a.1
78
+
79
+ Set the version with a pre-release and a build
80
+
81
+ $ sycersion --set 0.1.1-beta.1.0+build-a.1
82
+
83
+ Show the current version
84
+
85
+ $ sycersion -i
86
+ 0.1.1-beta.1.0+build-a.1
87
+
88
+ Increment minor part of the version 0.1.1, which will lead to 0.2.0
89
+
90
+ $ sycersion --inc minor
91
+ $ sycersion -i
92
+ 0.2.0
93
+
94
+ When increasing one of major, minor or patch, the subsequent numbers are eather
95
+ reset to 0 or pre-release and build are removed.
96
+
97
+ Compare the assumed current version 0.1.1 to the provided version
98
+
99
+ $ sycersion -c 0.1.1-alpha
100
+ 0.1.1 > 0.1.1-alpha
101
+
102
+ ## Development
103
+
104
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
105
+ `rake features` to run the tests. You can also run `bin/console` for an
106
+ interactive prompt that will allow you to experiment. Running **sycersion** with
107
+ `SYC_DEBUG=true sycersion [options]` will print debug information to the
108
+ console.
109
+
110
+ To install this gem onto your local machine, run `bundle exec rake install`. To
111
+ release a new version, update the version number with `sycersion --set X.Y.Z`
112
+ while the version is accessible in `version.rb`, and then run `bundle exec rake
113
+ release`, which will create a git tag for the version, push git commits and
114
+ tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
115
+
116
+ ## Contributing
117
+
118
+ Bug reports and pull requests are welcome on GitHub at
119
+ https://github.com/sugaryourcoffee/sycersion. This project is intended to be a
120
+ safe, welcoming space for collaboration, and contributors are expected to adhere
121
+ to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
122
+
123
+ ## License
124
+
125
+ The gem is available as open source under the terms of the [MIT
126
+ License](https://opensource.org/licenses/MIT).
127
+
128
+ ## Code of Conduct
129
+
130
+ Everyone interacting in the Sycersion project’s codebases, issue trackers, chat
131
+ rooms and mailing lists is expected to follow the [code of
132
+ conduct](https://github.com/[USERNAME]/sycersion/blob/master/CODE_OF_CONDUCT.md).
133
+
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "cucumber"
4
+ require "cucumber/rake/task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
9
+
10
+ Cucumber::Rake::Task.new(:features) do |task|
11
+ task.cucumber_opts = "features --format pretty -x"
12
+ task.fork = false
13
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "sycersion"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/sycersion ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/sycersion'
4
+
5
+ # Kicking off the application by reading the arguments from commandline and
6
+ # forwarding it to the `Runner` which is operating on the ARGV that is holding
7
+ # the command line arguments
8
+ runner = Sycersion::Runner.new(ARGV)
9
+ runner.run
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ # Creating and managing version following semver. Part commangline parsing
6
+ module Sycersion
7
+ # Parses the commandline arguments provided by the user and provides them to
8
+ # the calling class
9
+ class Options
10
+ attr_reader :options
11
+
12
+ # SEMVER_REGEX = /^(\d+\.\d+\.\d+)-?(beta|staging|\w*)?$/
13
+
14
+ def initialize(argv)
15
+ @options = {}
16
+ parse(argv)
17
+ end
18
+
19
+ def parse(_argv)
20
+ parser = OptionParser.new do |opts|
21
+ opts.banner = banner
22
+
23
+ opts.on('--init',
24
+ 'Setup the sycersion environment:',
25
+ '* file where the app version is stored',
26
+ '* initial version will be stored in version file',
27
+ '* code that provides the version to the application') do |opt|
28
+ @options[:init] = opt
29
+ end
30
+
31
+ opts.on('-i', '--info [VERSION|SUMMARY]', %i[version summary],
32
+ 'Print information about the application version and environment:',
33
+ '* current version of the application (default)',
34
+ '* file where the app version is stored',
35
+ '* file where the version is read into the application') do |opt|
36
+ @options[:info] = opt || :version
37
+ end
38
+
39
+ opts.on('--inc [MAJOR|MINOR|PATCH]', %i[major minor patch],
40
+ 'Increment the provided verion element (major, minor, patch)') do |opt|
41
+ @options[:inc] = opt
42
+ end
43
+
44
+ opts.on('--set MAJOR.MINOR.PATCH[+BUILD|-PRE_RELEASE+BUILD]',
45
+ Sycersion::SEMVER_REGEX,
46
+ 'Set the application version according to semver:',
47
+ '* major.minor.patch optionally add a pre-release and/or build',
48
+ '* major.minor.patch-prerelease+build or',
49
+ '* major.minor.patch+build') do |opt|
50
+ @options[:set] = opt
51
+ end
52
+
53
+ opts.on('-p', '--pre PRE_RELEASE', Sycersion::SEMVER_PRE_RELEASE_REGEX,
54
+ 'Set a pre-release suffix') do |opt|
55
+ @options[:pre_release] = opt
56
+ end
57
+
58
+ opts.on('-b', '--build BUILD', Sycersion::SEMVER_BUILD_REGEX,
59
+ 'Set a build suffix') do |opt|
60
+ @options[:build] = opt
61
+ end
62
+
63
+ opts.on('-c', '--compare VERSION', Sycersion::SEMVER_REGEX,
64
+ 'Compare current version with VERSION regarding precedence') do |opt|
65
+ @options[:compare] = opt
66
+ end
67
+
68
+ opts.on('-h', '--help', 'Show this help') do
69
+ puts opts
70
+ exit(0)
71
+ end
72
+ end
73
+
74
+ begin
75
+ puts "Run `#{File.basename($PROGRAM_NAME)} --help` for usage information" if ARGV.empty?
76
+ parser.parse!
77
+ rescue OptionParser::ParseError => e
78
+ warn e.message, "\n", options
79
+ parser.opts if ENV['SYC_DEBUG']
80
+ parser.parse(%w[--help])
81
+ exit(1)
82
+ end
83
+ end
84
+
85
+ def banner
86
+ program_name = File.basename($PROGRAM_NAME)
87
+ <<-CL_BANNER
88
+ Usage: #{program_name} [options]
89
+
90
+ #{program_name} supports applications to manage semantic versioning. Details
91
+ can be found at https://semver.org
92
+
93
+ CL_BANNER
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sycersion
4
+ SEMVER_REGEX = /
5
+ ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)
6
+ (?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
7
+ (?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?
8
+ (?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$
9
+ /x.freeze
10
+
11
+ SEMVER_LAX_REGEX = /
12
+ (0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)
13
+ (?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
14
+ (?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?
15
+ (?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?
16
+ /x.freeze
17
+
18
+ SEMVER_PRE_RELEASE_REGEX = /
19
+ ^((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
20
+ (?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?$
21
+ /x.freeze
22
+
23
+ SEMVER_BUILD_REGEX = /
24
+ ^([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)$
25
+ /x.freeze
26
+
27
+ # Semver contains methods to support semver operations
28
+ class Semver
29
+ # semver_array is of the form ["major", "minor", "patch", "pre-release",
30
+ # "build"]. version creates a version string in the form
31
+ # major.minor.patch-per-release+build. If only a build is given it creates
32
+ # major.minor.patch+build.
33
+ def self.version(semver_array)
34
+ semver = "#{semver_array[0]}.#{semver_array[1]}.#{semver_array[2]}"
35
+ semver += "-#{semver_array[3]}" unless semver_array[3].to_s.empty?
36
+ semver += "+#{semver_array[4]}" unless semver_array[4].to_s.empty?
37
+ semver
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sycersion
4
+ VERSION = File.exist?('.sycersion/version') ? File.read('.sycersion/version') : '0.1.0'
5
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sycersion
4
+ # Comparisson of two versions regarding semver guiding principles
5
+ class VersionCompare
6
+ COMPARATORS = ['=', '>', '<'].freeze
7
+ SUFFIX_REGEX = /([A-Za-z\-|\d]+)/.freeze
8
+ NUMBER_REGEX = /\A\d+\z/.freeze
9
+
10
+ def initialize
11
+ @current_version = Sycersion::VersionEnvironment.new
12
+ .version
13
+ .scan(Sycersion::SEMVER_REGEX)
14
+ .flatten
15
+ end
16
+
17
+ # Compares two semantic versions. The expected representation of the versions is:
18
+ # ["major", "minor", "patch", "pre-release", "build"]
19
+ def compare(comparer, current = @current_version)
20
+ result = compare_core(current[0..2], comparer[0..2])
21
+ result = compare_pre_release(current[3], comparer[3]) if result.zero?
22
+ result_string(current, COMPARATORS[result], comparer)
23
+ end
24
+
25
+ def compare_core(core1, core2)
26
+ 3.times do |_i|
27
+ result = core1.shift.to_i <=> core2.shift.to_i
28
+ return result unless result.zero?
29
+ end
30
+ 0
31
+ end
32
+
33
+ def compare_pre_release(version1, version2)
34
+ result = compare_on_nil(version1, version2)
35
+ return result unless result.zero? && !(version1.nil? && version2.nil?)
36
+
37
+ parts1 = version1.scan(SUFFIX_REGEX).flatten
38
+ parts2 = version2.scan(SUFFIX_REGEX).flatten
39
+
40
+ result = compare_parts(parts1, parts2)
41
+ return result unless result.zero?
42
+
43
+ compare_pre_release_field_size(parts1, parts2)
44
+ end
45
+
46
+ def compare_parts(parts1, parts2)
47
+ [parts1.size, parts2.size].min.times do |_i|
48
+ value1 = parts1.shift
49
+ value2 = parts2.shift
50
+
51
+ result = compare_numerically(value1, value2)
52
+ return result unless result.zero?
53
+
54
+ result = compare_lexically(value1, value2)
55
+ return result unless result.zero?
56
+ end
57
+ 0
58
+ end
59
+
60
+ def compare_pre_release_field_size(value1, value2)
61
+ value1.size <=> value2.size
62
+ end
63
+
64
+ def compare_lexically(value1, value2)
65
+ value1 <=> value2
66
+ end
67
+
68
+ def compare_numerically(value1, value2)
69
+ v1_is_number = value1.match(NUMBER_REGEX)
70
+ v2_is_number = value2.match(NUMBER_REGEX)
71
+ result = value1.to_i <=> value2.to_i if v1_is_number && v2_is_number
72
+ return result unless result.nil? || result.zero?
73
+ return 1 if v2_is_number
74
+ return -1 if v1_is_number
75
+
76
+ 0
77
+ end
78
+
79
+ def compare_on_nil(value1, value2)
80
+ return 1 if value1.nil? && !value2.nil?
81
+ return -1 if !value1.nil? && value2.nil?
82
+
83
+ 0
84
+ end
85
+
86
+ def result_string(value1, comparator, value2)
87
+ "#{Sycersion::Semver.version(value1)} #{comparator} #{Sycersion::Semver.version(value2)}"
88
+ end
89
+ end
90
+ end