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.
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'fileutils'
5
+
6
+ module Sycersion
7
+ SYCERSION_DIR = '.sycersion'
8
+ SYCERSION_ENV = '.sycersion/environment.yml'
9
+ SYCERSION_VER = '.sycersion/version'
10
+
11
+ # Creates a version and a version file where the version is stored to.
12
+ class VersionEnvironment
13
+ attr_accessor :version
14
+
15
+ def initialize
16
+ return if load_environment
17
+
18
+ determine_version_and_version_file
19
+ end
20
+
21
+ def setup
22
+ puts "\nSetup the version environment"
23
+ puts "=============================\n"
24
+ prompt_version_and_version_file
25
+ create_environment
26
+ summary
27
+ end
28
+
29
+ def summary
30
+ summary_of_configuration
31
+ summary_of_environment
32
+ end
33
+
34
+ def summary_of_configuration
35
+ puts "\nYour configuration"
36
+ puts "------------------\n"
37
+ puts "\nVersion #{@version}"
38
+ puts "Version-file #{@version_file}\n"
39
+ puts create_code_snippet(@version_file)
40
+ end
41
+
42
+ def summary_of_environment
43
+ puts "\nWhere to find the configuration files"
44
+ puts "-------------------------------------\n"
45
+ puts "\nDirectory: #{SYCERSION_DIR}"
46
+ puts "Configuration file: #{SYCERSION_ENV}\n"
47
+ puts "\nChange the configuration file only if you know what you are doing."
48
+ puts 'Otherwise run `sycersion --init` again.'
49
+ end
50
+
51
+ def determine_version_and_version_file
52
+ files = Dir.glob('**/*version*')
53
+ files.each do |file|
54
+ File.readlines(file, chomp: true).each do |line|
55
+ scan_result = line.scan(Sycersion::SEMVER_LAX_REGEX)
56
+ if scan_result[0]
57
+ @version_files[file] = [scan_result[0], line]
58
+ break
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def prompt_version_and_version_file
65
+ if File.exist?(SYCERSION_VER)
66
+ resume_version_and_version_file
67
+ elsif @version_files.empty?
68
+ define_version_and_version_file
69
+ else
70
+ select_version_and_version_file
71
+ end
72
+ end
73
+
74
+ def resume_version_and_version_file
75
+ print "Current version-file #{@version_file}. To keep hit RETURN otherwise specify new: "
76
+ selection = gets.chomp
77
+ @version_file = selection.empty? ? @version_file : selection
78
+ print "Current version #{@version}. To keep hit RETURN otherwise enter new: "
79
+ selection = gets.chomp
80
+ @version = selection.empty? ? @version : selection
81
+ end
82
+
83
+ def define_version_and_version_file
84
+ puts 'No version and version-file found'
85
+ print "To use #{SYCERSION_VER} hit RETURN or specify own file: "
86
+ selection = gets.chomp
87
+ @version_file = selection.empty? ? SYCERSION_VER : selection
88
+ print 'To use `0.0.1` as initial version hit RETURN or specify own version: '
89
+ selection = gets.chomp.scan(Sycersion::SEMVER_REGEX)
90
+ @version = selection.empty? ? @version : selection
91
+ @version_string = @version
92
+ end
93
+
94
+ def select_version_and_version_file
95
+ puts "\nFound version-files\n"
96
+ puts "-------------------\n"
97
+ list_versions_and_version_files
98
+ print "\nChoose version-file and version with number or hit return for [0]: "
99
+ selection = gets.chomp.to_i
100
+ app_version_file = @version_files.keys[selection]
101
+ @version = Sycersion::Semver.version(@version_files[app_version_file][0])
102
+ @version_string = @version_files[@version_file[1]]
103
+ end
104
+
105
+ def list_versions_and_version_files
106
+ digits = digit_counter(@version_files)
107
+ filler = filler_string(' ', digits + 2)
108
+ @version_files.each_with_index do |entry, index|
109
+ choice = "[#{index.to_s.rjust(digits, ' ')}]"
110
+ print_line(choice, 'file: ', entry[0])
111
+ print_line(filler, 'version:', Sycersion::Semver.version(entry[1][0]))
112
+ print_line(filler, 'line: ', (entry[1][1]).strip)
113
+ end
114
+ end
115
+
116
+ def digit_counter(object)
117
+ object.size.to_s.length
118
+ end
119
+
120
+ def filler_string(fill_char, size)
121
+ fill_char * size
122
+ end
123
+
124
+ def print_line(prescriptor, descriptor, value)
125
+ puts "#{prescriptor} #{descriptor} #{value}"
126
+ end
127
+
128
+ def create_code_snippet(version_file)
129
+ <<-CODE_SNIP
130
+
131
+ In your application you can now access the version with
132
+
133
+ > File.read(#{version_file})
134
+
135
+ If you application framework has a defined place to assign
136
+ the version you could do like so
137
+
138
+ > version = File.read(#{version_file})
139
+ CODE_SNIP
140
+ end
141
+
142
+ def save
143
+ create_environment
144
+ end
145
+
146
+ def create_environment
147
+ FileUtils.mkdir(SYCERSION_DIR) unless Dir.exist?(SYCERSION_DIR)
148
+ File.open(@version_file, 'w') { |f| f.write(@version) }
149
+ File.open(SYCERSION_ENV, 'w') do |f|
150
+ YAML.dump([@version_file, @version], f)
151
+ end
152
+ rescue IOError => e
153
+ puts e.message
154
+ end
155
+
156
+ def load_environment
157
+ if File.exist?(SYCERSION_ENV)
158
+ @version_file, @version = YAML.load_file(SYCERSION_ENV)
159
+ true
160
+ else
161
+ @version_file = SYCERSION_VER
162
+ @version = '0.1.0'
163
+ @version_files = {}
164
+ @version_string = ''
165
+ false
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sycersion
4
+ NORMAL_REGEX = /^(\d+)\.(\d+)\.(\d+)/.freeze
5
+
6
+ # Increments the elements of a semantic version number major, minor, patch
7
+ class VersionIncrementer
8
+ def initialize
9
+ @environment = Sycersion::VersionEnvironment.new
10
+ end
11
+
12
+ def increment(position)
13
+ @environment.version = case position
14
+ when :major
15
+ increment_major
16
+ when :minor
17
+ increment_minor
18
+ when :patch
19
+ increment_patch
20
+ end
21
+ @environment.save
22
+ end
23
+
24
+ def increment_major
25
+ "#{current_version[0].to_i + 1}.0.0"
26
+ end
27
+
28
+ def increment_minor
29
+ "#{current_version[0]}.#{current_version[1].to_i + 1}.0"
30
+ end
31
+
32
+ def increment_patch
33
+ "#{current_version[0]}.#{current_version[1]}.#{current_version[2].to_i + 1}"
34
+ end
35
+
36
+ def current_version
37
+ @environment.version.scan(NORMAL_REGEX).flatten
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Managing the application's version according semver
4
+ module Sycersion
5
+ # Provides information about the `sycersion` settings and the current version
6
+ class VersionInfo
7
+ def initialize
8
+ @environment = Sycersion::VersionEnvironment.new
9
+ end
10
+
11
+ def process(options)
12
+ case options[:info]
13
+ when :version
14
+ print @environment.version
15
+ when :summary
16
+ @environment.summary
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sycersion
4
+ # Sets the version
5
+ class VersionSetter
6
+ def initialize
7
+ @environment = Sycersion::VersionEnvironment.new
8
+ end
9
+
10
+ # Sets the version provided by the version array. The version array is in
11
+ # the form ["version", "major", "minor", "patch", "pre-release", "build"]
12
+ def version=(version)
13
+ @environment.version = version[0]
14
+ @environment.save
15
+ end
16
+
17
+ # Sets the pre-release part only. The pre-release parameter is of the form
18
+ # ["pre-release", "pre-release"]
19
+ def pre_release=(pre_release)
20
+ create_version(3, pre_release[0])
21
+ end
22
+
23
+ # Sets the build part only. The build parameter is of the form
24
+ # ["build", "build"]
25
+ def build=(build)
26
+ create_version(4, build[0])
27
+ end
28
+
29
+ # Helper method for build= and pre_release=
30
+ def create_version(position, value)
31
+ version = @environment.version
32
+ semver_array = version.scan(Sycersion::SEMVER_REGEX).flatten
33
+ semver_array[position] = value
34
+ @environment.version = Sycersion::Semver.version(semver_array)
35
+ @environment.save
36
+ end
37
+ end
38
+ end
data/lib/sycersion.rb ADDED
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'sycersion/version'
4
+ require_relative 'sycersion/options'
5
+ require_relative 'sycersion/version_environment'
6
+ require_relative 'sycersion/version_setter'
7
+ require_relative 'sycersion/version_incrementer'
8
+ require_relative 'sycersion/version_info'
9
+ require_relative 'sycersion/version_compare'
10
+ require_relative 'sycersion/semver'
11
+
12
+ module Sycersion
13
+ class Error < StandardError; end
14
+
15
+ # Runs the program based on the arguments provided at the commandline
16
+ class Runner
17
+ def initialize(argv)
18
+ @options = Options.new(argv).options
19
+ pp @options if ENV['SYC_DEBUG']
20
+ end
21
+
22
+ def run
23
+ environment_settings
24
+ version_manipulation
25
+ version_compare
26
+ configuration_information
27
+ end
28
+
29
+ def environment_settings
30
+ Sycersion::VersionEnvironment.new.setup if @options[:init]
31
+ end
32
+
33
+ def version_manipulation
34
+ case @options.keys
35
+ when [:set]
36
+ Sycersion::VersionSetter.new.version = (@options[:set])
37
+ when [:pre_release]
38
+ Sycersion::VersionSetter.new.pre_release = (@options[:pre_release])
39
+ when [:build]
40
+ Sycersion::VersionSetter.new.build = (@options[:build])
41
+ when [:inc]
42
+ Sycersion::VersionIncrementer.new.increment(@options[:inc])
43
+ end
44
+ end
45
+
46
+ def version_compare
47
+ return unless @options[:compare]
48
+
49
+ @options[:compare].shift
50
+ puts Sycersion::VersionCompare.new.compare(@options[:compare])
51
+ end
52
+
53
+ def configuration_information
54
+ puts Sycersion::VersionInfo.new.process(@options) if @options[:info]
55
+ end
56
+ end
57
+ end
data/man/sycersion.1 ADDED
@@ -0,0 +1,184 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "SYCERSION" "1" "January 2025" "" ""
5
+ .
6
+ .SH "NAME"
7
+ \fBsycersion\fR \- manage application versions according to semantic versioning
8
+ .
9
+ .SH "SYNOPSIS"
10
+ .
11
+ .nf
12
+
13
+ `sycersion` `\-\-init`
14
+ `sycersion` `\-i`|`\-\-info`
15
+ `sycersion` `\-\-inc major|minor|patch`
16
+ `sycersion` `\-\-set major\.minor\.patch[+build|\-pre\-release+build]`
17
+ `sycersion` `\-p`|`\-\-pre` `pre\-release`
18
+ `sycersion` `\-b`|`\-\-build` `build`
19
+ `sycersion` `\-c`|`\-\-compare` `version`
20
+ `sycersion` `\-h`|`\-\-help`
21
+ .
22
+ .fi
23
+ .
24
+ .SH "Description"
25
+ \fBsycersion\fR is a command\-line tool to manage application versions following the guiding principles of \fIsemantic versioning\fR found at semver\.org \fIhttps://semver\.org\fR\.
26
+ .
27
+ .P
28
+ \fBsycersion\fR has a default start version of 0\.1\.0\. This can be activitated with the initalization running \fBsycersion \-\-init\fR\. During this intialization another version can be chosen\. The version is saved to the \fIversion\-file\fR and also the \fIconfiguration\-directory\fR is created\. While initialization \fBsycersion\fR additionally searches for files that contain a version according to semantic versioning and the user can select out of the list of files which version out of that files to intially start with\.
29
+ .
30
+ .P
31
+ The \fIversion\-file\fR and \fIconfiguration\-directory\fR are also created it the user is setting an initial version with \fBsycersion \-\-set 0\.1\.1\fR\.
32
+ .
33
+ .P
34
+ If the version is updated the version is written into the \fIversion\-file\fR\. Within the application the version can be read from the file and displayed somewhere in the application\'s UI\.
35
+ .
36
+ .P
37
+ \fBsycersion\fR evaluates version numbers provided that they comply to semantic versioning\.
38
+ .
39
+ .P
40
+ If \fBsycersion\fR is used within a \fIRuby\fR application, it can be added to the development section within the Gemfile\.
41
+ .
42
+ .SH "FILES"
43
+ .
44
+ .nf
45
+
46
+ `\.sycersion` is the configuration directory
47
+ `\.sycersion/environment\.yml` holds the version file and the version
48
+ `\.sycersion/version` contains the version
49
+ .
50
+ .fi
51
+ .
52
+ .SH "OPTIONS"
53
+ .
54
+ .IP "\(bu" 4
55
+ \fB\-\-init\fR Initializes the \fBsycersion\fR environment with \fIversion\fR and \fIversion\-file\fR
56
+ .
57
+ .IP "\(bu" 4
58
+ \fB\-i\fR, \fB\-\-info VERSION|SUMMARY\fR Shows the current \fIversion\fR (default) or additionally information about the \fIversion\-file\fR, the \fIconfiguration\-directory\fR and \fIcode\fR how to read the version within an application\.
59
+ .
60
+ .IP "\(bu" 4
61
+ \fB\-\-inc MAJOR|MINOR|PATCH\fR increments the major, minor, patch part of the version\.
62
+ .
63
+ .IP "\(bu" 4
64
+ \fB\-\-set MAJOR\.MINOR\.PATCH[+BUILD|\-PRE_RELEASE[+BUILD]]\fR sets the version where all three version parts need to be provided, major\.minor\.patch with optionally adding a pre\-release part and/or a build part\.
65
+ .
66
+ .IP "\(bu" 4
67
+ \fB\-\-pre PRE\-RELEASE\fR Set the pre\-release part in the version
68
+ .
69
+ .IP "\(bu" 4
70
+ \fB\-\-build BUILD\fR Set the build part in the version
71
+ .
72
+ .IP "\(bu" 4
73
+ \fB\-c\fR, \fB\-\-compare VERSION\fR Compares the current version with the version provided following the semver precedence guidline
74
+ .
75
+ .IP "\(bu" 4
76
+ \fB\-\-help\fR Prints the command line help
77
+ .
78
+ .IP "" 0
79
+ .
80
+ .SH "EXAMPLES"
81
+ Initialize \fBsycersion\fR
82
+ .
83
+ .IP "" 4
84
+ .
85
+ .nf
86
+
87
+ $ sycersion \-\-init
88
+ .
89
+ .fi
90
+ .
91
+ .IP "" 0
92
+ .
93
+ .P
94
+ Set the version with pre\-release
95
+ .
96
+ .IP "" 4
97
+ .
98
+ .nf
99
+
100
+ $ sycersion \-\-set 0\.1\.1\-beta\.1\.0
101
+ .
102
+ .fi
103
+ .
104
+ .IP "" 0
105
+ .
106
+ .P
107
+ Set the version with a build
108
+ .
109
+ .IP "" 4
110
+ .
111
+ .nf
112
+
113
+ $ sycersion \-\-set 0\.1\.1+build\-a\.1
114
+ .
115
+ .fi
116
+ .
117
+ .IP "" 0
118
+ .
119
+ .P
120
+ Set the version with a pre\-release and a build
121
+ .
122
+ .IP "" 4
123
+ .
124
+ .nf
125
+
126
+ $ sycersion \-\-set 0\.1\.1\-beta\.1\.0+build\-a\.1
127
+ .
128
+ .fi
129
+ .
130
+ .IP "" 0
131
+ .
132
+ .P
133
+ Show the current version
134
+ .
135
+ .IP "" 4
136
+ .
137
+ .nf
138
+
139
+ $ sycersion \-i
140
+ 0\.1\.1\-beta\.1\.0+build\-a\.1
141
+ .
142
+ .fi
143
+ .
144
+ .IP "" 0
145
+ .
146
+ .P
147
+ Increment minor part of the version 0\.1\.1, which will lead to 0\.2\.0
148
+ .
149
+ .IP "" 4
150
+ .
151
+ .nf
152
+
153
+ $ sycersion \-\-inc minor
154
+ $ sycersion \-i
155
+ 0\.2\.0
156
+ .
157
+ .fi
158
+ .
159
+ .IP "" 0
160
+ .
161
+ .P
162
+ When increasing one of major, minor or patch, the subsequent numbers are eather reset to 0 or pre\-release and build are removed\.
163
+ .
164
+ .P
165
+ Compare the assumed current version 0\.1\.1 to the provided version
166
+ .
167
+ .IP "" 4
168
+ .
169
+ .nf
170
+
171
+ $ sycersion \-c 0\.1\.1\-alpha
172
+ 0\.1\.1 > 0\.1\.1\-alpha
173
+ .
174
+ .fi
175
+ .
176
+ .IP "" 0
177
+ .
178
+ .SH "ENVIRONMENT"
179
+ .
180
+ .IP "\(bu" 4
181
+ SYC_DEBUG=true Will display erros and show contents of the parsed options\. To be called as \fBSYC_DEBUG=true sycersion [options]\fR
182
+ .
183
+ .IP "" 0
184
+