git_toolbox 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 500f22d2000495865a5671476122c580ea0e5fdb6ebf2804ce42d209828a1841
4
- data.tar.gz: 70a3c312974ce5ee382a8c6793325bf676dba7fb40206ed828f56c2019ce9d64
3
+ metadata.gz: d18e02ebf90eb2595af4735f88043d1fdea653a03d8500dec75a7cf9a510bc51
4
+ data.tar.gz: c0344b2969623ab61aa94c6960fa88bdad522057541ece00052bfdf9f4cbf636
5
5
  SHA512:
6
- metadata.gz: ce3a643b6a110c7b70e7ddc33649548b15f064e61dbe35c13fa5eba3fa70b7c71a5118185ee88b89aab83f74602b605d9175b4633e58c933ae30ebfae97c2dab
7
- data.tar.gz: 5125a3a0af8ab4a6590af9166c95d442c1dae5f89648f1d94224ff5a4d3e18fcaf21ec5e9d52b1f50939340d17d60ddd5cd37fa7bd6bd16b4e7ce88f2ac868da
6
+ metadata.gz: a9cbe2abd8b068d78436841419dddd776f72e97b57a5575f8447ae31e7744d8a7e54de9eaa55a242ff0c177b52a1f81b74309b044970c12ccaf98f4dc7d431d4
7
+ data.tar.gz: 9248e4bcce0371b73542e336591bc6844ac8a66f6d93334702fa0e7fbb2b13556c6d914682d9e8f62e964f5eb8aee6462bd4ebe739c4881effe69241c141ca1a
@@ -23,6 +23,15 @@ require_relative './command_issuer'
23
23
  module Git
24
24
  # Groups: 1 = type, 2 = scope with (), 3 = scope, 4 = breaking change, 5 = summary
25
25
  CONVENTIONAL_COMMIT_REGEX = %r{^(\w+)(\(([\w/-]+)\))?(!)?:(.*)}
26
+ DEFAULT_RELEASE_VERSION = '0.1.0'
27
+ # Groups:
28
+ # 1 = full stable version ; 2,3,4 = major,minor,patch
29
+ # 5 = prerelease ; 6 = metadata
30
+ FULL_SEMANTIC_VERSION_REGEX = /
31
+ ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)) # Stable version, major, minor, patch
32
+ (?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))? # prerelease
33
+ (?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ # metadata
34
+ /x
26
35
 
27
36
  # Check if the command is called while in a git repository.
28
37
  # If the command fails, it is assumed to not be in a git repository.
@@ -61,11 +70,12 @@ module Git
61
70
  # Returns the last release and caches it for the next calls.
62
71
  def self.last_release
63
72
  @last_release ||=
64
- CommandIssuer.run('git', '--no-pager', 'tag', '--list')
73
+ CommandIssuer.run('git', '--no-pager', 'tag', '--list', '--merged')
65
74
  .then do |value|
66
75
  unless value.output.empty?
67
76
  value.output
68
77
  .split("\n")
78
+ .select { |str| str.match(FULL_SEMANTIC_VERSION_REGEX)[5].nil? }
69
79
  .map { |str| str.sub('+', '_') }
70
80
  .sort
71
81
  .map { |str| str.sub('_', '+') }
@@ -28,6 +28,10 @@ module BashCompletion
28
28
  private
29
29
 
30
30
  INITIAL_LEVEL = 1
31
+ NOT_NEGABLE_OPTIONS = [
32
+ 'help',
33
+ 'version',
34
+ ].freeze
31
35
 
32
36
  HEADER = <<~HEADER
33
37
  #!/usr/bin/env bash
@@ -77,6 +81,7 @@ module BashCompletion
77
81
 
78
82
  command_class.instance.option_parser.specs.each_value do |option|
79
83
  long_options.push("--#{option.long}")
84
+ long_options.push("--no-#{option.long}") if option.flag? && !NOT_NEGABLE_OPTIONS.include?(option.long)
80
85
  short_options.push("-#{option.short.nil? ? option.long[0] : option.short}") if option.short != :none
81
86
  end
82
87
 
@@ -33,8 +33,18 @@ class Complete < Command
33
33
  def initialize
34
34
  super() do
35
35
  @usage = 'complete -h|(<subcommand> [<subcommand-options])'
36
- @description = 'Print the shell completion script.'
36
+ @description = 'Print the shell completion script. ' \
37
+ 'Run \'get complete --info\' to learn how to install the completion.'
37
38
  @subcommands = {}
39
+ @completions = {
40
+ bash: {
41
+ generator: proc { bash_completion(Get, 'get') },
42
+ info: <<~INFO
43
+ Add the following line to your .bashrc (or a sourced script):
44
+ eval "$(get complete)" && complete -F _get_completion get
45
+ INFO
46
+ }
47
+ }
38
48
  end
39
49
  end
40
50
 
@@ -51,6 +61,9 @@ class Complete < Command
51
61
  opt :shell,
52
62
  'Select the type of shell of which the completion will be generated.',
53
63
  { type: :string, default: 'bash' }
64
+ opt :info,
65
+ 'Print the instructions to install the completion for the selected shell.',
66
+ { short: :none }
54
67
  educate_on_error
55
68
  stop_on stop_condition
56
69
  end
@@ -62,16 +75,19 @@ class Complete < Command
62
75
  @option_parser.parse
63
76
  end
64
77
 
65
- @completions = {
66
- bash: proc { bash_completion(Get, 'get') }
67
- }
68
-
69
78
  selected_shell = @options[:shell].to_sym
70
79
 
80
+ print_info_and_exit(selected_shell) if @options[:info]
81
+
71
82
  Common.error "Completion for shell '#{selected_shell}' not available." unless @completions.key?(selected_shell)
72
83
 
73
- puts @completions[selected_shell].call
84
+ puts @completions[selected_shell][:generator].call
74
85
  end
75
86
  end
87
+
88
+ def print_info_and_exit(selected_shell)
89
+ puts @completions[selected_shell][:info]
90
+ exit 0
91
+ end
76
92
  end
77
93
  # rubocop:enable Metrics/ClassLength
@@ -30,6 +30,27 @@ module ChangeHandler
30
30
  Common.module_instance_attr(self, 'minor_trigger', :DEFAULT_MINOR_TRIGGER)
31
31
  Common.module_instance_attr(self, 'patch_trigger', :DEFAULT_PATCH_TRIGGER)
32
32
 
33
+ def updated_stable_version(stable_version)
34
+ return Git::DEFAULT_RELEASE_VERSION if stable_version.nil?
35
+
36
+ greatest_change_from_stable_version = Git.with_commit_list_from(stable_version) do |commits_from_version|
37
+ greatest_change_in(commits_from_version)
38
+ end
39
+ split_version = stable_version.split('.')
40
+ case greatest_change_from_stable_version
41
+ when :MAJOR
42
+ "#{split_version[0].to_i + 1}.0.0"
43
+ when :MINOR
44
+ "#{split_version[0].to_i}.#{split_version[1].to_i + 1}.0"
45
+ when :PATCH
46
+ "#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i + 1}"
47
+ else
48
+ "#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i}"
49
+ end
50
+ end
51
+
52
+ private
53
+
33
54
  def greatest_change_in(commit_list)
34
55
  commit_list
35
56
  .grep(Git::CONVENTIONAL_COMMIT_REGEX)
@@ -37,8 +58,6 @@ module ChangeHandler
37
58
  .max { |a, b| CHANGE_TYPE.index(a) <=> CHANGE_TYPE.index(b) }
38
59
  end
39
60
 
40
- private
41
-
42
61
  # In this block method arguments can be used by user.
43
62
  # Also `eval` is needed to allow users to define their custom triggers.
44
63
  # rubocop:disable Lint/UnusedMethodArgument
@@ -61,8 +80,8 @@ module ChangeHandler
61
80
  def to_change(commit_message)
62
81
  groups = Git::CONVENTIONAL_COMMIT_REGEX.match(commit_message)
63
82
  return :MAJOR if triggers_major?(groups[1], groups[3], !groups[4].nil?)
64
- return :MINOR if triggers_minor?(groups[1], groups[2])
65
- return :PATCH if triggers_patch?(groups[1], groups[2])
83
+ return :MINOR if triggers_minor?(groups[1], groups[3])
84
+ return :PATCH if triggers_patch?(groups[1], groups[3])
66
85
 
67
86
  :NONE
68
87
  end
@@ -38,13 +38,6 @@ class Describe < Command
38
38
  include PrereleaseHandler
39
39
  include MetadataHandler
40
40
 
41
- DEFAULT_RELEASE_VERSION = '0.1.0'
42
- FULL_SEMANTIC_VERSION_REGEX = /
43
- ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)) # Stable version, major, minor, patch
44
- (?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))? # prerelease
45
- (?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ # metadata
46
- /x
47
-
48
41
  def initialize
49
42
  super() do
50
43
  @usage = 'describe -h|(<subcommand> [<subcommand-options])'
@@ -84,50 +77,13 @@ class Describe < Command
84
77
 
85
78
  def next_release
86
79
  if @options[:prerelease]
87
- prepare_prerelease_tag(Git.last_release, Git.last_version)
80
+ updated_stable_version(Git.last_release)
81
+ .then { |stable| "#{stable}-#{updated_prerelease(Git.last_version, stable)}" }
88
82
  else
89
- prepare_release_tag(Git.last_release)
83
+ updated_stable_version(Git.last_release).to_s
90
84
  end + metadata
91
85
  end
92
86
 
93
- def prepare_release_tag(last_release)
94
- updated_stable_version(last_release).to_s
95
- end
96
-
97
- def prepare_prerelease_tag(last_release, last_version)
98
- new_stable_version = updated_stable_version(last_release)
99
- base_version_match_data = FULL_SEMANTIC_VERSION_REGEX.match(last_version)
100
- no_changes_from_last_release = base_version_match_data[1] == new_stable_version && base_version_match_data[5].nil?
101
- Common.error 'No changes from last release' if no_changes_from_last_release
102
- new_stable_version +
103
- "-#{updated_prerelease(base_version_match_data[5], need_reset: base_version_match_data[1] != new_stable_version)}"
104
- end
105
-
106
- def updated_stable_version(stable_version)
107
- return DEFAULT_RELEASE_VERSION if stable_version.nil?
108
-
109
- greatest_change_from_stable_version = Git.with_commit_list_from(stable_version) do |commits_from_version|
110
- greatest_change_in(commits_from_version)
111
- end
112
- split_version = stable_version.split('.')
113
- case greatest_change_from_stable_version
114
- when :MAJOR
115
- "#{split_version[0].to_i + 1}.0.0"
116
- when :MINOR
117
- "#{split_version[0].to_i}.#{split_version[1].to_i + 1}.0"
118
- when :PATCH
119
- "#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i + 1}"
120
- else
121
- "#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i}"
122
- end
123
- end
124
-
125
- # Return the updated prerelease number
126
- def updated_prerelease(prerelease = nil, need_reset: false)
127
- compute_prerelease(prerelease, need_reset: prerelease.nil? || need_reset)
128
- end
129
-
130
- # Compute the metadata string
131
87
  def metadata
132
88
  return '' if @options[:exclude_metadata] || @options[:metadata].empty?
133
89
 
@@ -27,20 +27,31 @@ module PrereleaseHandler
27
27
  Common.module_instance_attr(self, 'prerelease_pattern', :DEFAULT_PRERELEASE_PATTERN)
28
28
  Common.module_instance_attr(self, 'old_prerelease_pattern', 'proc { prerelease_pattern }')
29
29
 
30
- def compute_prerelease(current_prerelease, need_reset: false)
31
- new_prerelease = (need_reset ? FIRST_PRERELEASE : (extract_prerelease_number(current_prerelease) + 1)).to_s
32
- PrereleaseHandler.prerelease_pattern.sub(PRERELEASE_PLACEHOLDER, new_prerelease)
30
+ def updated_prerelease(last_version, new_stable_version)
31
+ if last_version.nil?
32
+ compute_prerelease(nil, need_reset: true)
33
+ else
34
+ base_version_match_data = Git::FULL_SEMANTIC_VERSION_REGEX.match(last_version)
35
+ no_changes_from_last_release = base_version_match_data[1] == new_stable_version &&
36
+ base_version_match_data[5].nil?
37
+ Common.error 'No changes from last release' if no_changes_from_last_release
38
+ compute_prerelease(base_version_match_data[5], need_reset: base_version_match_data[1] != new_stable_version)
39
+ end
33
40
  end
34
41
 
35
42
  private
36
43
 
44
+ def compute_prerelease(current_prerelease, need_reset: false)
45
+ pattern_changed = PrereleaseHandler.prerelease_pattern != actual_old_prerelease_pattern
46
+ new_prerelease = if need_reset || pattern_changed
47
+ FIRST_PRERELEASE
48
+ else
49
+ extract_prerelease_number(current_prerelease) + 1
50
+ end.to_s
51
+ PrereleaseHandler.prerelease_pattern.sub(PRERELEASE_PLACEHOLDER, new_prerelease)
52
+ end
53
+
37
54
  def extract_prerelease_number(current_prerelease)
38
- actual_old_prerelease_pattern =
39
- if PrereleaseHandler.old_prerelease_pattern.respond_to?('call')
40
- PrereleaseHandler.old_prerelease_pattern.call
41
- else
42
- PrereleaseHandler.old_prerelease_pattern
43
- end
44
55
  Common.error "The given old pattern does not contains the placeholder '(p)'" unless
45
56
  actual_old_prerelease_pattern.include?(PRERELEASE_PLACEHOLDER)
46
57
  old_prerelease_regex = actual_old_prerelease_pattern.sub(PRERELEASE_PLACEHOLDER, '(\\d+)')
@@ -51,4 +62,12 @@ module PrereleaseHandler
51
62
  "does not match the analyzed prerelease: '#{current_prerelease}'."
52
63
  end
53
64
  end
65
+
66
+ def actual_old_prerelease_pattern
67
+ if PrereleaseHandler.old_prerelease_pattern.respond_to?('call')
68
+ PrereleaseHandler.old_prerelease_pattern.call
69
+ else
70
+ PrereleaseHandler.old_prerelease_pattern
71
+ end
72
+ end
54
73
  end
@@ -47,7 +47,7 @@ class Init < Command
47
47
 
48
48
  def create_first_commit
49
49
  command_result = CommandIssuer.run('git', 'commit', '--allow-empty', '-m', '"chore: initialize repository"')
50
- Common.error 'Failed to create first commit' if command_result.exit_status.positive?
50
+ Common.error "Failed to create first commit: #{command_result.error}" if command_result.exit_status.positive?
51
51
  end
52
52
 
53
53
  protected
@@ -70,21 +70,18 @@ class Tree < Command
70
70
  # calc color escape codes length
71
71
  time_color_length = first_line_time.length - first_line_time.match(TIME_REGEX)[1].length
72
72
 
73
- # calc max length of time references
74
- time_padding = 0
75
- split_lines.each { |element| time_padding = [time_padding, element[1].length - time_color_length].max }
73
+ time_padding = global_fitting_time_padding(split_lines, time_color_length)
76
74
 
77
- # format strings
78
75
  split_lines
79
76
  .map do |element|
80
77
  # Only lines with the date reference have the color escape codes,
81
78
  # the other lines do not need the additional padding
82
79
  left_padding = TIME_MINIMUM_PADDING + time_padding +
83
- (element[1].match?(TIME_REGEX) ? time_color_length : 0)
80
+ (!element[1].nil? && element[1].match?(TIME_REGEX) ? time_color_length : 0)
84
81
  format(
85
82
  '%<date>s %<tree_mark>s %<pointers>s %<commit_text>s',
86
83
  {
87
- date: element[1].rjust(left_padding),
84
+ date: (element[1].nil? ? '' : element[1]).rjust(left_padding),
88
85
  tree_mark: element[0],
89
86
  pointers: element[2],
90
87
  commit_text: element[3]
@@ -95,6 +92,16 @@ class Tree < Command
95
92
  end
96
93
  # rubocop:enable Metrics/MethodLength
97
94
 
95
+ def global_fitting_time_padding(lines, time_color_length)
96
+ time_padding = 0
97
+ lines
98
+ # If element[1].nil? then the line refers to a intersection between branch lines
99
+ # they do not have a time reference
100
+ .reject { |element| element[1].nil? }
101
+ .each { |element| time_padding = [time_padding, element[1].length - time_color_length].max }
102
+ time_padding
103
+ end
104
+
98
105
  protected
99
106
 
100
107
  def setup_option_parser
data/lib/get/version.rb CHANGED
@@ -17,4 +17,4 @@
17
17
 
18
18
  # frozen_string_literal: true
19
19
 
20
- GET_VERSION = '0.8.0'
20
+ GET_VERSION = '0.9.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_toolbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Speranza
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-22 00:00:00.000000000 Z
11
+ date: 2023-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -96,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
96
  requirements:
97
97
  - - ">="
98
98
  - !ruby/object:Gem::Version
99
- version: 3.1.0
99
+ version: 3.0.0
100
100
  required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  requirements:
102
102
  - - ">="