version-manager 0.0.9 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79b79f83cae2d7a380e74c9bb8ba6658f0713f00
4
- data.tar.gz: d4f02a71475f77b35ee8a989ff6861fbbbba70d4
3
+ metadata.gz: 3860c7e4394f7d49d1c467cabb0fe944f0d049f3
4
+ data.tar.gz: a8c9694661eca4f788d28a7c991d9b41f1c874aa
5
5
  SHA512:
6
- metadata.gz: c0a3ba13361846f03c59387d92e831fda1c2edc8d504a5ab094360e14d88551d84267dda075c891980b27f0592ddcf4c3a37d7061c433dcc8308eb4ed32e4d98
7
- data.tar.gz: ef2a48b62669f0a412d916a988f9d2039041140f40f74559eb176b57aa7fc374e14c7297eb810d9ba4f1b4b65a4677d13df36565ac8d38718e7eeb60f9be17ff
6
+ metadata.gz: eebd799dc897df1e401c74a80a01ff12fca1cce18d37f8a6037df74c1a7e3c7f2aa01bc45f5e572ba3616a70b4ee23d6fdbc1fcac07f1d7279c23c9dd3caf782
7
+ data.tar.gz: 4492d44cce10b4249c2fd543d11ebea4b154d8e2db06ed3f6f9ac9c0d77913356e36df2e4d132165799644ee5365b8321ce0d2cc9dd8e66fd7d83aed4e81cf05
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
@@ -0,0 +1,10 @@
1
+ Metrics/LineLength:
2
+ Max: 120
3
+ Metrics/AbcSize:
4
+ Max: 25
5
+ Style/Documentation:
6
+ Enabled: false
7
+ AllCops:
8
+ TargetRubyVersion: 2.3
9
+ Metrics/MethodLength:
10
+ Max: 15
data/Gemfile CHANGED
@@ -1,3 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  gemspec
5
+
6
+ group :development, :test do
7
+ gem 'byebug'
8
+ end
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![Code Climate](https://codeclimate.com/github/isolo/version-manager/badges/gpa.svg)](https://codeclimate.com/github/isolo/version-manager)
1
2
  # version-manager
2
3
  versioning lib (with Git support) written in Ruby
3
4
 
data/Rakefile CHANGED
@@ -1,2 +1,5 @@
1
- require "bundler/gem_tasks"
2
- task :default => :spec
1
+ # frozen_string_literal: true
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
data/exe/manver CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require_relative '../lib/version-manager'
4
5
  VersionManager::CLI.new(exec_name: File.basename(__FILE__)).start
@@ -1,3 +1,5 @@
1
+ # rubocop:disable Style/FileName
2
+ # frozen_string_literal: true
1
3
  require 'docopt'
2
4
  require 'git'
3
5
  require 'pathname'
@@ -10,10 +12,12 @@ module VersionManager
10
12
  DEFAULTS = {
11
13
  vcs: {
12
14
  name: 'git',
13
- default_commit_message: -> (version) { "Bumped to version #{version}" },
15
+ default_commit_message: ->(version) { "Bumped to version #{version}" },
14
16
  options: {
15
17
  remote: 'origin',
16
- master_branch: 'master'
18
+ master_branch: 'master',
19
+ dir: ROOT_DIR,
20
+ version_name: ->(version) { "release-#{version.short_version}" }
17
21
  }
18
22
  },
19
23
  authorized_branches: {
@@ -24,9 +28,8 @@ module VersionManager
24
28
  storage: {
25
29
  filename: 'VERSION',
26
30
  filepath: ROOT_DIR
27
- },
28
- version_name: -> (version) { "release-#{version.short_version}" }
29
- }
31
+ }
32
+ }.freeze
30
33
 
31
34
  def self.options
32
35
  @options ||= DEFAULTS.dup
@@ -43,6 +46,7 @@ require_relative 'version-manager/vcs/git'
43
46
  require_relative 'version-manager/version'
44
47
  require_relative 'version-manager/cli'
45
48
 
49
+ require_relative 'version-manager/action_manager'
50
+ require_relative 'version-manager/release_manager'
46
51
  require_relative 'version-manager/release_version'
47
52
  require_relative 'version-manager/version_storage'
48
- require_relative 'version-manager/make.rb'
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module VersionManager
3
+ class ActionManager
4
+ def initialize(options)
5
+ @options = options
6
+ @vcs = VCS.build(options[:vcs])
7
+ @storage = VersionStorage.new(vcs, options[:storage])
8
+ @release_manager = ReleaseManager.new(vcs, storage, options)
9
+ end
10
+
11
+ def checkout_to_latest_version
12
+ version = storage.latest_version
13
+ return false unless version
14
+ vcs.switch_branch(VCS.branch_name(version, options.dig(:vcs, :options)))
15
+ true
16
+ end
17
+
18
+ def release_new_version(release_type, confirmation_func, retrieve_initial_version_func)
19
+ release_manager.validate!(release_type)
20
+ version = release_type == :patch ? storage.current_version : storage.latest_version
21
+ if version
22
+ new_version = version.public_send("bump_#{release_type}")
23
+ return unless confirmation_func.call(new_version)
24
+ else
25
+ version = retrieve_initial_version_func.call
26
+ end
27
+ release_manager.public_send("#{release_type}!", version)
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :vcs, :storage, :release_manager, :options
33
+ end
34
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module VersionManager
2
3
  class CLI
3
4
  def initialize(exec_name: __FILE__)
4
5
  @exec_name = exec_name
6
+ @action_manager = ActionManager.new(VersionManager.options)
5
7
  end
6
8
 
7
9
  def start
@@ -21,7 +23,7 @@ module VersionManager
21
23
  DOCOPT
22
24
 
23
25
  begin
24
- parse_options(Docopt::docopt(doc))
26
+ parse_options(Docopt.docopt(doc))
25
27
  rescue StandardError => e
26
28
  puts e.message
27
29
  end
@@ -29,7 +31,7 @@ module VersionManager
29
31
 
30
32
  private
31
33
 
32
- attr_reader :exec_name
34
+ attr_reader :exec_name, :action_manager
33
35
 
34
36
  def parse_options(options)
35
37
  puts VersionManager::VERSION if options['--version']
@@ -41,34 +43,18 @@ module VersionManager
41
43
  end
42
44
 
43
45
  def checkout_to_latest_version
44
- storage = build_storage
45
- version = storage.latest_version
46
- return puts 'There are no any versions.' unless version
47
- VCS.build.switch_branch(version.branch)
46
+ return if action_manager.checkout_to_latest_version
47
+ puts 'There are no any versions.'
48
48
  end
49
49
 
50
50
  def make_release(release_type)
51
- storage = build_storage
52
-
53
- make = Make.new(VCS.build, storage)
54
- make.validate!(release_type)
55
-
56
- version = release_type == :patch ? storage.current_version : storage.latest_version
57
- if version
58
- new_version = version.public_send("bump_#{release_type}")
59
- return unless Ask.confirm("You are going to upgrade version to #{new_version}. Do it?", default: false)
60
- else
61
- version = retrieve_initial_version
62
- end
63
-
64
- make.public_send("#{release_type}!", version)
51
+ action_manager.release_new_version(release_type, method(:confirm_new_version), method(:retrieve_initial_version))
65
52
  rescue VersionManager::VersionStorage::WrongLatestVersionError => e
66
53
  puts "There is inappropriate version #{e.version} in your local/remote repository. Please remove it"
67
54
  end
68
55
 
69
- def build_storage
70
- storage_options = VersionManager.options[:storage]
71
- VersionStorage.new(VCS.build, storage_options)
56
+ def confirm_new_version(new_version)
57
+ Ask.confirm("You are going to upgrade version to #{new_version}. Do it?", default: false)
72
58
  end
73
59
 
74
60
  def retrieve_initial_version
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module VersionManager
2
- class Make
3
+ class ReleaseManager
3
4
  class BranchIsNotUpToDateError < StandardError
4
5
  def message
5
6
  'Remote branch and local one are different. You need to update your branch or push your changes'
@@ -12,9 +13,10 @@ module VersionManager
12
13
  end
13
14
  end
14
15
 
15
- def initialize(vcs, version_storage)
16
+ def initialize(vcs, version_storage, options)
16
17
  @vcs = vcs
17
18
  @version_storage = version_storage
19
+ @options = options
18
20
  end
19
21
 
20
22
  def validate!(release_type)
@@ -40,15 +42,15 @@ module VersionManager
40
42
 
41
43
  private
42
44
 
43
- attr_reader :vcs, :version_storage
45
+ attr_reader :vcs, :version_storage, :options
44
46
 
45
47
  def appropriate_branch_for?(action)
46
- authorized_mask = VersionManager.options[:authorized_branches][action.to_sym]
48
+ authorized_mask = options[:authorized_branches][action.to_sym]
47
49
  !authorized_mask || !vcs.current_branch.match(authorized_mask).nil?
48
50
  end
49
51
 
50
52
  def default_strategy(version)
51
- vcs.create_branch!(version.branch)
53
+ vcs.create_branch!(version)
52
54
  vcs.commit(version_storage.store(version), default_commit_message(version))
53
55
  vcs.add_tag(version.to_s, default_commit_message(version))
54
56
  vcs.push_tag(version.to_s)
@@ -56,7 +58,7 @@ module VersionManager
56
58
  end
57
59
 
58
60
  def default_commit_message(version)
59
- message = VersionManager.options[:vcs][:default_commit_message]
61
+ message = options[:vcs][:default_commit_message]
60
62
  message.respond_to?(:call) ? message.call(version) : message.to_s
61
63
  end
62
64
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module VersionManager
2
3
  class ReleaseVersion
3
4
  include Comparable
@@ -19,28 +20,28 @@ module VersionManager
19
20
  recalculate_parts
20
21
  end
21
22
 
22
- def to_str
23
+ def to_s
23
24
  res = parts.map(&:to_i).join('.')
24
25
  [res, special].compact.join('--')
25
26
  end
26
- alias_method :to_s, :to_str
27
27
 
28
28
  def short_version
29
29
  [major, minor].map(&:to_i).join('.')
30
30
  end
31
31
 
32
- def branch
33
- VersionManager.options[:version_name].call(self)
32
+ def <=>(other)
33
+ parts.zip(other.parts)
34
+ .map { |this, other_part| this <=> other_part }
35
+ .find { |res| res != 0 } || 0
34
36
  end
35
37
 
36
- def <=>(other_version)
37
- parts.zip(other_version.parts).
38
- map { |this, other| this <=> other }.
39
- find { |res| res != 0 } || 0
38
+ def -(other)
39
+ self.class.new(parts.zip(other.parts).map { |x, y| x - y })
40
40
  end
41
41
 
42
- def -(other_version)
43
- self.class.new(parts.zip(other_version.parts).map { |x, y| x - y })
42
+ def bump(release_type)
43
+ raise ArgumentError, 'Unknown release type' unless %i(major minor patch).include?(release_type.to_sym)
44
+ public_send("bump_#{release_type}")
44
45
  end
45
46
 
46
47
  def bump_major
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module VersionManager
2
3
  module VCS
3
4
  class BranchAlreadyExistsError < StandardError
@@ -20,9 +21,14 @@ module VersionManager
20
21
  end
21
22
  end
22
23
 
23
- def self.build
24
- case VersionManager.options[:vcs][:name]
25
- when 'git' then VersionManager::VCS::Git.new(VersionManager.options[:vcs][:options])
24
+ def self.branch_name(version, vcs_options)
25
+ version = ReleaseVersion.new(version) if version.is_a?(String)
26
+ vcs_options[:version_name].call(version)
27
+ end
28
+
29
+ def self.build(vcs_options)
30
+ case vcs_options[:name]
31
+ when 'git' then VersionManager::VCS::Git.new(vcs_options[:options])
26
32
  else raise UnsupportedVCSError
27
33
  end
28
34
  end
@@ -1,33 +1,36 @@
1
+ # frozen_string_literal: true
1
2
  module VersionManager
2
3
  module VCS
3
4
  class Git
4
5
  def initialize(options)
5
6
  @options = options
6
- @git = ::Git.open(ROOT_DIR, options)
7
+ @git = ::Git.open(options[:dir], options)
7
8
  end
8
9
 
9
- def create_branch!(branch_name)
10
- raise VersionManager::VCS::BranchAlreadyExistsError.new(branch_name) if branch_exists?(branch_name)
11
- checkout(branch_name)
10
+ def create_branch!(branch)
11
+ branch = branch_name(branch)
12
+ raise VersionManager::VCS::BranchAlreadyExistsError, branch if branch_exists?(branch)
13
+ checkout(branch)
12
14
  end
13
15
 
14
- def checkout(branch_name)
15
- git.branch(branch_name).checkout
16
+ def checkout(branch)
17
+ git.branch(branch_name(branch)).checkout
16
18
  end
17
19
 
18
- def switch_branch(branch_name) # checkout moves commits to new branch
19
- git.lib.send(:command, 'checkout', branch_name)
20
+ def switch_branch(branch) # checkout moves commits to new branch
21
+ git.lib.send(:command, 'checkout', branch_name(branch))
20
22
  end
21
23
 
22
24
  def show_file(branch, filepath)
23
- git.object("#{remote}/#{branch}:#{filepath}").contents
25
+ relative_filepath = Pathname.new(filepath).relative_path_from(Pathname.new(options[:dir])).to_s
26
+ git.object("#{remote}/#{branch_name(branch)}:#{relative_filepath}").contents
24
27
  rescue StandardError
25
28
  nil
26
29
  end
27
30
 
28
31
  def commit(filepath, message)
29
32
  git.lib.send(:command, 'add', filepath)
30
- git.lib.send(:command, 'commit', "-m #{message}", '-o', "#{filepath}")
33
+ git.lib.send(:command, 'commit', "-m #{message}", '-o', filepath)
31
34
  end
32
35
 
33
36
  def add_tag(tag_name, message)
@@ -52,22 +55,26 @@ module VersionManager
52
55
  end
53
56
 
54
57
  def state_actual?
55
- head = ::Git.ls_remote['branches'][git.current_branch]
58
+ head = git_remote['branches'][git.current_branch]
56
59
  remote_head = find_remote_branch(git.current_branch).last
57
60
  return unless remote_head
58
61
  head[:sha] == remote_head[:sha]
59
62
  end
60
63
 
61
64
  def remote_branch_names
62
- ::Git.ls_remote['remotes'].keys
65
+ git_remote['remotes'].keys
63
66
  end
64
67
 
65
68
  private
66
69
 
67
70
  attr_reader :git, :options
68
71
 
72
+ def branch_name(version)
73
+ VCS.branch_name(version, options)
74
+ end
75
+
69
76
  def branch_exists?(branch_name)
70
- branches = ::Git.ls_remote['branches'].keys + ::Git.ls_remote['remotes'].keys
77
+ branches = git_remote['branches'].keys + git_remote['remotes'].keys
71
78
  branches.any? { |b| b.split('/').last == branch_name }
72
79
  end
73
80
 
@@ -75,16 +82,20 @@ module VersionManager
75
82
  options[:master_branch]
76
83
  end
77
84
 
78
- def remote
79
- options[:remote]
80
- end
81
-
82
85
  def remote_master_branch_name
83
- "#{options[:remote]}/#{master_branch_name}"
86
+ "#{remote}/#{master_branch_name}"
84
87
  end
85
88
 
86
89
  def find_remote_branch(branch_name)
87
- ::Git.ls_remote['remotes'].find { |remote, _| branch_name == remote.split('/').last }
90
+ remote_branch_names.find { |remote| branch_name == remote.split('/').last }
91
+ end
92
+
93
+ def remote
94
+ options[:remote]
95
+ end
96
+
97
+ def git_remote
98
+ ::Git.ls_remote(options[:dir])
88
99
  end
89
100
  end
90
101
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module VersionManager
2
- VERSION = '0.0.9'.freeze
3
+ VERSION = '0.1.0'
3
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module VersionManager
2
3
  class VersionStorage
3
4
  class WrongLatestVersionError < StandardError
@@ -38,7 +39,7 @@ module VersionManager
38
39
 
39
40
  def version_from_file(version)
40
41
  return unless version
41
- file_content = vcs.show_file(version.branch, relative_path) if version
42
+ file_content = vcs.show_file(version, full_path) if version
42
43
  ReleaseVersion.new(file_content) if file_content && ReleaseVersion.valid?(file_content)
43
44
  end
44
45
 
@@ -48,10 +49,6 @@ module VersionManager
48
49
  ReleaseVersion.new(branch_name) if branch_name.include?('release-') && ReleaseVersion.valid?(branch_name)
49
50
  end
50
51
 
51
- def relative_path
52
- Pathname.new(full_path).relative_path_from(Pathname.new(ROOT_DIR)).to_s
53
- end
54
-
55
52
  def full_path
56
53
  File.expand_path(File.join(filepath, filename))
57
54
  end
@@ -62,9 +59,9 @@ module VersionManager
62
59
  return prev_last_version unless last_version
63
60
  diff = last_version - prev_last_version
64
61
  is_appropriate = diff.major == 1
65
- is_appropriate ||= diff.major == 0 && diff.minor == 1
66
- is_appropriate ||= diff.major == 0 && diff.minor == 0 && diff.patch == 1
67
- raise WrongLatestVersionError.new(last_version) unless is_appropriate
62
+ is_appropriate ||= diff.major.zero? && diff.minor == 1
63
+ is_appropriate ||= diff.major.zero? && diff.minor.zero? && diff.patch == 1
64
+ raise WrongLatestVersionError, last_version unless is_appropriate
68
65
  last_version
69
66
  end
70
67
  end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Metrics/BlockLength
3
+ RSpec.describe 'bumping version action' do
4
+ include_context 'shared settings'
5
+ let(:repo) { Test::GitRepository.new(root_dir, options) }
6
+
7
+ context 'when repository does not contain any versions' do
8
+ let(:initial_version) { VersionManager::ReleaseVersion.new('1.0.0') }
9
+ before { repo.init }
10
+ it 'retrieves an initial version' do
11
+ retrieve_initial_version_func = ->() { initial_version }
12
+ release_new_version(:major, default_confirmation_func, retrieve_initial_version_func)
13
+
14
+ expect(repo).to have_version(initial_version.bump_major)
15
+ expect(repo).to have_tag(initial_version.bump_major)
16
+ expect(repo).to have_branch(release_name(initial_version.bump_major))
17
+ end
18
+ end
19
+
20
+ context 'when initial version is presented' do
21
+ let(:initial_version) { VersionManager::ReleaseVersion.new('1.0.0') }
22
+ let(:current_version) { initial_version.bump_major }
23
+ before do
24
+ repo.init
25
+ retrieve_initial_version_func = ->() { initial_version }
26
+ release_new_version(:major, default_confirmation_func, retrieve_initial_version_func)
27
+ end
28
+
29
+ context 'when current branch is a master branch' do
30
+ before { repo.checkout_to_master_branch }
31
+ it 'bumped major version' do
32
+ release_new_version(:major)
33
+ expect(repo).to have_version(current_version.bump_major)
34
+ expect(repo).to have_tag(current_version.bump_major)
35
+ expect(repo).to have_branch(release_name(current_version.bump_major))
36
+ end
37
+
38
+ it 'bumped minor version' do
39
+ release_new_version(:minor)
40
+ expect(repo).to have_version(current_version.bump_minor)
41
+ expect(repo).to have_tag(current_version.bump_minor)
42
+ expect(repo).to have_branch(release_name(current_version.bump_minor))
43
+ end
44
+
45
+ it 'does not bump patch version' do
46
+ expect { release_new_version(:patch) }.to(
47
+ raise_error(VersionManager::ReleaseManager::ForbiddenBranchError)
48
+ )
49
+ end
50
+ end
51
+
52
+ context 'when current branch is different from a master branch' do
53
+ it 'does not bump major version' do
54
+ expect { release_new_version(:major) }.to(
55
+ raise_error(VersionManager::ReleaseManager::ForbiddenBranchError)
56
+ )
57
+ end
58
+
59
+ it 'does not bump minor version' do
60
+ expect { release_new_version(:minor) }.to(
61
+ raise_error(VersionManager::ReleaseManager::ForbiddenBranchError)
62
+ )
63
+ end
64
+
65
+ it 'bumped patch version' do
66
+ release_new_version(:patch)
67
+ expect(repo).to have_version(current_version.bump_patch)
68
+ expect(repo).to have_tag(current_version.bump_patch)
69
+ expect(repo).to have_branch(release_name(current_version.bump_patch))
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'when repository is not up to date' do
75
+ let(:initial_version) { VersionManager::ReleaseVersion.new('1.0.0') }
76
+ let(:current_version) { initial_version.bump_major }
77
+ before do
78
+ repo.init
79
+ retrieve_initial_version_func = ->() { initial_version }
80
+ release_new_version(:major, default_confirmation_func, retrieve_initial_version_func)
81
+ repo.checkout_to_master_branch
82
+ repo.add_and_commit_changes
83
+ end
84
+
85
+ %i(major minor patch).each do |version_type|
86
+ it "does not bump #{version_type} version" do
87
+ expect { release_new_version(version_type) }.to(
88
+ raise_error(VersionManager::ReleaseManager::BranchIsNotUpToDateError)
89
+ )
90
+ end
91
+ end
92
+ end
93
+
94
+ after(:each) do
95
+ repo.teardown if tmp_dir?
96
+ end
97
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Metrics/BlockLength
3
+ RSpec.describe 'latest version action' do
4
+ include_context 'shared settings'
5
+ let(:repo) { Test::GitRepository.new(root_dir, options) }
6
+
7
+ def checkout_to_latest_version
8
+ VersionManager::ActionManager.new(options).checkout_to_latest_version
9
+ end
10
+
11
+ context 'when a repository does not contain any versions' do
12
+ before { repo.init }
13
+ it 'do nothing' do
14
+ expect(checkout_to_latest_version).to be_falsy
15
+ end
16
+ end
17
+
18
+ context 'when a repository has several releases' do
19
+ let(:initial_version) { VersionManager::ReleaseVersion.new('1.0.0') }
20
+ let(:current_version) { @current_version }
21
+ before do
22
+ repo.init
23
+ @current_version = initial_version
24
+ retrieve_initial_version_func = ->() { initial_version }
25
+ (1..10).to_a.sample.times do
26
+ release_type = %i(major minor).sample
27
+ @current_version = @current_version.bump(release_type)
28
+ release_new_version(release_type, default_confirmation_func, retrieve_initial_version_func)
29
+ repo.checkout_to_master_branch
30
+ end
31
+ end
32
+
33
+ it 'checkouts to latest version' do
34
+ expect(checkout_to_latest_version).to be_truthy
35
+ expect(repo).to have_version(current_version)
36
+ expect(repo).to have_tag(current_version)
37
+ expect(repo).to have_branch(release_name(current_version))
38
+ end
39
+ end
40
+
41
+ after(:each) do
42
+ repo.teardown if tmp_dir?
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ begin
3
+ require 'byebug'
4
+ rescue LoadError
5
+ nil
6
+ end
7
+
8
+ require 'securerandom'
9
+
10
+ require 'version-manager'
11
+
12
+ require_relative 'support/git_repository'
13
+ require_relative 'support/shared_settings'
14
+ require_relative 'support/repository_matchers'
15
+
16
+ RSpec.configure do |config|
17
+ config.order = :random
18
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+ module Test
3
+ class GitRepository
4
+ def initialize(root_dir, options)
5
+ @options = options
6
+ @root_dir = root_dir
7
+ end
8
+
9
+ def init
10
+ @remote_dir = File.join(@root_dir, 'remote')
11
+ @remote = Git.init(@remote_dir, bare: true)
12
+ @local = Git.clone(@remote_dir, 'local', path: @root_dir)
13
+ @local2 = Git.clone(@remote_dir, 'local2', path: @root_dir)
14
+
15
+ initial_commit(@local)
16
+ @local
17
+ end
18
+
19
+ def checkout_to_master_branch
20
+ @local.lib.send(:command, 'checkout', @options.dig(:vcs, :options, :master_branch))
21
+ end
22
+
23
+ def current_local_branch_version
24
+ path = File.join(@options[:storage][:filepath], @options[:storage][:filename])
25
+ File.open(path).read
26
+ end
27
+
28
+ def current_local_tag
29
+ @local.tags.last&.name
30
+ end
31
+
32
+ def current_local_branch
33
+ @local.branches.to_a.last&.name
34
+ end
35
+
36
+ def add_and_commit_changes
37
+ add_random_changes(@local)
38
+ @local.add
39
+ @local.commit('some changes')
40
+ end
41
+
42
+ def teardown
43
+ FileUtils.rm_f(@remote_dir)
44
+ FileUtils.rm_f(@local.dir.path)
45
+ FileUtils.rm_f(@local2.dir.path)
46
+ end
47
+
48
+ private
49
+
50
+ def initial_commit(repo)
51
+ add_random_changes(repo)
52
+ repo.add
53
+ repo.commit('initial commit')
54
+ repo.push
55
+ end
56
+
57
+ def add_random_changes(repo)
58
+ File.open(File.join(repo.dir.path, SecureRandom.urlsafe_base64), 'w') do |f|
59
+ f << SecureRandom.urlsafe_base64
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ RSpec::Matchers.define :have_version do |version|
3
+ match do |repo|
4
+ repo.current_local_branch_version == version.to_s
5
+ end
6
+ end
7
+
8
+ RSpec::Matchers.define :have_tag do |version|
9
+ match do |repo|
10
+ repo.current_local_tag == version.to_s
11
+ end
12
+ end
13
+
14
+ RSpec::Matchers.define :have_branch do |version|
15
+ match do |repo|
16
+ repo.current_local_branch == version.to_s
17
+ end
18
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Metrics/BlockLength
3
+ RSpec.shared_context 'shared settings' do
4
+ let(:root_dir) { Dir.mktmpdir }
5
+ let(:tmp_dir?) { true }
6
+ let(:repo_dir) { File.join(root_dir, 'local') }
7
+
8
+ let(:vcs) { 'git' }
9
+ let(:default_commit_message) do
10
+ ->(version) { "Bumped to version #{version}" }
11
+ end
12
+ let(:vcs_opts) do
13
+ {
14
+ name: vcs,
15
+ default_commit_message: default_commit_message,
16
+ options: {
17
+ remote: 'origin',
18
+ master_branch: 'master',
19
+ dir: repo_dir,
20
+ version_name: ->(version) { "release-#{version.short_version}" }
21
+ }
22
+ }
23
+ end
24
+
25
+ let(:authorized_branches_opts) do
26
+ {
27
+ major: '^\bmaster\b$',
28
+ minor: '^\bmaster\b$',
29
+ patch: '^\brelease-[a-zA-Z0-9.]*$\b$'
30
+ }
31
+ end
32
+
33
+ let(:storage_opts) do
34
+ {
35
+ filename: 'VERSION',
36
+ filepath: repo_dir
37
+ }
38
+ end
39
+
40
+ let(:options) do
41
+ {
42
+ vcs: vcs_opts,
43
+ authorized_branches: authorized_branches_opts,
44
+ storage: storage_opts
45
+ }
46
+ end
47
+
48
+ let(:default_confirmation_func) { ->(_new_version) { true } }
49
+
50
+ def release_new_version(release_type, confirmation_func = default_confirmation_func, retrieve_init_version_func = nil)
51
+ VersionManager::ActionManager
52
+ .new(options)
53
+ .release_new_version(release_type, confirmation_func, retrieve_init_version_func)
54
+ end
55
+
56
+ def release_name(version)
57
+ VersionManager::VCS.branch_name(version, options.dig(:vcs, :options))
58
+ end
59
+ end
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'version-manager/version'
@@ -6,7 +7,7 @@ require 'version-manager/version'
6
7
  Gem::Specification.new do |spec|
7
8
  spec.name = 'version-manager'
8
9
  spec.version = VersionManager::VERSION
9
- spec.authors = ['isolo']
10
+ spec.authors = ['Ilya Solo']
10
11
  spec.email = ['ilya.i.solo@gmail.com']
11
12
 
12
13
  spec.summary = 'Versioning lib (with Git support)'
@@ -18,9 +19,20 @@ Gem::Specification.new do |spec|
18
19
  spec.bindir = 'exe'
19
20
  spec.require_paths = ['lib']
20
21
 
22
+ spec.required_ruby_version = '>= 2.3'
23
+
21
24
  spec.add_development_dependency 'bundler', '~> 1.12'
22
25
  spec.add_development_dependency 'rake', '~> 10.0'
26
+
27
+ # Testing
28
+ spec.add_development_dependency 'rspec'
29
+ spec.add_development_dependency 'simplecov'
30
+ spec.add_development_dependency 'rubocop'
31
+
32
+ # Command line utils
23
33
  spec.add_dependency 'docopt', '~> 0.5'
24
34
  spec.add_dependency 'inquirer', '~> 0.2'
35
+
36
+ # Other
25
37
  spec.add_dependency 'git', '~> 1.3'
26
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: version-manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - isolo
7
+ - Ilya Solo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-02 00:00:00.000000000 Z
11
+ date: 2017-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,48 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: docopt
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -89,22 +131,28 @@ extensions: []
89
131
  extra_rdoc_files: []
90
132
  files:
91
133
  - ".gitignore"
92
- - ".ruby-version"
134
+ - ".rspec"
135
+ - ".rubocop.yml"
93
136
  - Gemfile
94
137
  - LICENSE
95
138
  - README.md
96
139
  - Rakefile
97
- - bin/console
98
- - bin/setup
99
140
  - exe/manver
100
141
  - lib/version-manager.rb
142
+ - lib/version-manager/action_manager.rb
101
143
  - lib/version-manager/cli.rb
102
- - lib/version-manager/make.rb
144
+ - lib/version-manager/release_manager.rb
103
145
  - lib/version-manager/release_version.rb
104
146
  - lib/version-manager/vcs.rb
105
147
  - lib/version-manager/vcs/git.rb
106
148
  - lib/version-manager/version.rb
107
149
  - lib/version-manager/version_storage.rb
150
+ - spec/features/git_bumping_version_action_spec.rb
151
+ - spec/features/git_latest_version_action_spec.rb
152
+ - spec/spec_helper.rb
153
+ - spec/support/git_repository.rb
154
+ - spec/support/repository_matchers.rb
155
+ - spec/support/shared_settings.rb
108
156
  - version-manager.gemspec
109
157
  homepage: https://github.com/isolo/version-manager
110
158
  licenses:
@@ -118,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
166
  requirements:
119
167
  - - ">="
120
168
  - !ruby/object:Gem::Version
121
- version: '0'
169
+ version: '2.3'
122
170
  required_rubygems_version: !ruby/object:Gem::Requirement
123
171
  requirements:
124
172
  - - ">="
@@ -1 +0,0 @@
1
- 2.3.1
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "version/manager"
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
data/bin/setup DELETED
@@ -1,8 +0,0 @@
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