git 4.0.0 → 4.0.4

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
  SHA256:
3
- metadata.gz: 93f63d19e697e7cc1f9d6f8fed0a34ff32015c5ed24357f183f2493dca636953
4
- data.tar.gz: 8e7619c86fee8af92c11d60c6af450e3814bbf77d456fcb3c6d3c914d985403f
3
+ metadata.gz: 53b8b74b8c2b17a44030a715fa6d562e989189b2c2b1b6a3195d349ed4cab439
4
+ data.tar.gz: 504029d354e4def312a520cc93ed0ac5857d02093405f776897d50c7f979ffb7
5
5
  SHA512:
6
- metadata.gz: 1f003e0ea707da5dc4a164c041407802650390e6a03b496d1960994dfd79cae393ab16da3ed062b0cbeaa6839e7d21931d8e9954d7c19fb8ec25cbbfb0f46fa7
7
- data.tar.gz: 552efec7c3d8b2e09cfa1c943666e72a3d8aaa336a64252c7d955412cef092c5aede3e87ca7f17df0e8f673a9ed3b35cafcfcf04912b5c8e65ad0082ac415f46
6
+ metadata.gz: 29db48811be6a98b1096bfab4f5347aac762fcc03b9e232246cfb17e574f32a8d5c9d8444e32c242c1b7a30a777cd89b1498d58a7a7fde0c313bfd045f6a8b72
7
+ data.tar.gz: a9d24b3d5aca3a7f63856ce74808d562626992c7c023f51bb01f6167cc1b9ed425ba57ad0aecce0d3c4f77fec5138efbe5a502d512dfcc26bccf6e6004969137
data/.gitignore CHANGED
@@ -11,3 +11,4 @@ Gemfile.lock
11
11
  node_modules
12
12
  package-lock.json
13
13
  ai-prompt.erb
14
+ rubocop-report.json
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "4.0.0"
2
+ ".": "4.0.4"
3
3
  }
data/.rubocop.yml ADDED
@@ -0,0 +1,51 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ inherit_gem:
4
+ main_branch_shared_rubocop_config: config/rubocop.yml
5
+
6
+ # Don't care about complexity offenses in the TestUnit tests This exclusions
7
+ # will be removed when we switch to RSpec.
8
+ Metrics/CyclomaticComplexity:
9
+ Exclude:
10
+ - "tests/test_helper.rb"
11
+ - "tests/units/**/*"
12
+
13
+ Metrics/ClassLength:
14
+ Exclude:
15
+ - "tests/test_helper.rb"
16
+ - "tests/units/**/*"
17
+
18
+ Metrics/AbcSize:
19
+ Exclude:
20
+ - "tests/test_helper.rb"
21
+ - "tests/units/**/*"
22
+
23
+ # Don't care so much about length of methods in tests
24
+ Metrics/MethodLength:
25
+ Exclude:
26
+ - "tests/test_helper.rb"
27
+ - "tests/units/**/*"
28
+
29
+ # Allow test data to have long lines
30
+ Layout/LineLength:
31
+ Exclude:
32
+ - "tests/test_helper.rb"
33
+ - "tests/units/**/*"
34
+ - "*.gemspec"
35
+
36
+ # Testing and gemspec DSL results in large blocks
37
+ Metrics/BlockLength:
38
+ Exclude:
39
+ - "tests/test_helper.rb"
40
+ - "tests/units/**/*"
41
+ - "*.gemspec"
42
+
43
+ # Don't force every test class to be described
44
+ Style/Documentation:
45
+ Exclude:
46
+ - "tests/units/**/*"
47
+
48
+ AllCops:
49
+ # Pin this project to Ruby 3.1 in case the shared config above is upgraded to 3.2
50
+ # or later.
51
+ TargetRubyVersion: 3.2
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,12 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2025-07-06 21:08:14 UTC using RuboCop version 1.77.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 2
10
+ # Configuration parameters: CountComments, CountAsOne.
11
+ Metrics/ClassLength:
12
+ Max: 1032
data/CHANGELOG.md CHANGED
@@ -5,6 +5,96 @@
5
5
 
6
6
  # Change Log
7
7
 
8
+ ## [4.0.4](https://github.com/ruby-git/ruby-git/compare/v4.0.3...v4.0.4) (2025-07-09)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Remove deprecation from Git::Path ([ab1e207](https://github.com/ruby-git/ruby-git/commit/ab1e20773c6a300b546841f79adf8dd6e707250e))
14
+ * Remove deprecation from Git::Stash ([9da1e91](https://github.com/ruby-git/ruby-git/commit/9da1e9112e38c0e964dd2bc638bda7aebe45ba91))
15
+
16
+
17
+ ### Other Changes
18
+
19
+ * Add tests for Git::Base#set_index including deprecation ([e6ccb11](https://github.com/ruby-git/ruby-git/commit/e6ccb11830a794f12235e47032235c3284c84cf6))
20
+ * Add tests for Git::Base#set_working including deprecation ([ee11137](https://github.com/ruby-git/ruby-git/commit/ee1113706a8e34e9631f0e2d89bd602bca87f05f))
21
+ * Add tests to verify Git::Object.new creates the right type of object ([ab17621](https://github.com/ruby-git/ruby-git/commit/ab17621d65a02b70844fde3127c9cbb219add7f5))
22
+ * Verify deprecated Git::Log methods emit a deprecation warning ([abb0efb](https://github.com/ruby-git/ruby-git/commit/abb0efbdb3b6bb49352d097b1fece708477d4362))
23
+
24
+ ## [4.0.3](https://github.com/ruby-git/ruby-git/compare/v4.0.2...v4.0.3) (2025-07-08)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * Correct the deprecation horizon for Git deprecations ([b7b7f38](https://github.com/ruby-git/ruby-git/commit/b7b7f38ccb88ba719e8ea7cb3fea14474b19a00c))
30
+ * Fix Rubocop Layout/EmptyLinesAroundClassBody offense ([1de27da](https://github.com/ruby-git/ruby-git/commit/1de27daabed18b47a42539fe69b735d8ee90cbbb))
31
+ * Internally create a Stash with non-deprecated initializer args ([8b9b9e2](https://github.com/ruby-git/ruby-git/commit/8b9b9e2f3b3fa525973785f642331317ade35936))
32
+ * Report correct line number in deprecation warnings ([cca0deb](https://github.com/ruby-git/ruby-git/commit/cca0debb4166c809af76f9dc586e4fd06e142d44))
33
+ * Un-deprecate Git::Diff methods ([761b6ff](https://github.com/ruby-git/ruby-git/commit/761b6ffcd363f4329a9cbafbf1379513a19ff174))
34
+
35
+
36
+ ### Other Changes
37
+
38
+ * Make tests that emit a deprecation warning fail ([7e211d7](https://github.com/ruby-git/ruby-git/commit/7e211d7b2b7cc8d9da4a860361bef52280a5e73b))
39
+ * Update all tests to not use deprecated features ([33ab0e2](https://github.com/ruby-git/ruby-git/commit/33ab0e255e229e22d84b14a4d4f5fb829c1fe37c))
40
+
41
+ ## [4.0.2](https://github.com/ruby-git/ruby-git/compare/v4.0.1...v4.0.2) (2025-07-08)
42
+
43
+
44
+ ### Bug Fixes
45
+
46
+ * Call Git::Index#new correctly from initialize_components ([07dfab5](https://github.com/ruby-git/ruby-git/commit/07dfab5804874cbc52469bd40203b6d0b08be7a1))
47
+
48
+
49
+ ### Other Changes
50
+
51
+ * Announce that the project has adopted RuboCop ([3d6cac9](https://github.com/ruby-git/ruby-git/commit/3d6cac94b47b3c1b1915f5c37f9e811041210ddc))
52
+ * Update comment to be accurate ([3a87722](https://github.com/ruby-git/ruby-git/commit/3a87722760176db54dfef9631de6191b183ab223))
53
+
54
+ ## [4.0.1](https://github.com/ruby-git/ruby-git/compare/v4.0.0...v4.0.1) (2025-07-06)
55
+
56
+
57
+ ### Bug Fixes
58
+
59
+ * Fix Rubocop Layout/LineLength offense ([52d80ac](https://github.com/ruby-git/ruby-git/commit/52d80ac592d9139655d47af8e764eebf8577fda7))
60
+ * Fix Rubocop Lint/EmptyBlock offense ([9081f0f](https://github.com/ruby-git/ruby-git/commit/9081f0fb055e0d6cc693fd8f8bf47b2fa13efef0))
61
+ * Fix Rubocop Lint/MissingSuper offense ([e9e91a8](https://github.com/ruby-git/ruby-git/commit/e9e91a88fc338944b816ee6929cadf06ff1daab5))
62
+ * Fix Rubocop Lint/StructNewOverride offense ([141c2cf](https://github.com/ruby-git/ruby-git/commit/141c2cfd8215f5120f536f78b3c066751d74aabe))
63
+ * Fix Rubocop Lint/SuppressedException offense ([4372a20](https://github.com/ruby-git/ruby-git/commit/4372a20b0b61e862efb7558f2274769ae17aa2c9))
64
+ * Fix Rubocop Lint/UselessConstantScoping offense ([54c4a3b](https://github.com/ruby-git/ruby-git/commit/54c4a3bba206ab379a0849fbc9478db5b61e192a))
65
+ * Fix Rubocop Metrics/AbcSize offense ([256d860](https://github.com/ruby-git/ruby-git/commit/256d8602a4024d1fbe432eda8bbcb1891fb726bc))
66
+ * Fix Rubocop Metrics/BlockLength offense ([9c856ba](https://github.com/ruby-git/ruby-git/commit/9c856ba42d0955cb6c3f5848f9c3253b54fd3735))
67
+ * Fix Rubocop Metrics/ClassLength offense (exclude tests) ([d70c800](https://github.com/ruby-git/ruby-git/commit/d70c800263ff1347109688dbb5b66940c6d64f2c))
68
+ * Fix Rubocop Metrics/ClassLength offense (refactor Git::Log) ([1aae57a](https://github.com/ruby-git/ruby-git/commit/1aae57a631aa331a84c37122ffc8fa09b415c6c5))
69
+ * Fix Rubocop Metrics/ClassLength offense (refactor Git::Status) ([e3a378b](https://github.com/ruby-git/ruby-git/commit/e3a378b6384bf1d0dc80ebc5aea792f9ff5b512a))
70
+ * Fix Rubocop Metrics/CyclomaticComplexity offense ([abfcf94](https://github.com/ruby-git/ruby-git/commit/abfcf948a08578635f7e832c31deaf992e6f3fb1))
71
+ * Fix Rubocop Metrics/MethodLength offense ([e708c36](https://github.com/ruby-git/ruby-git/commit/e708c3673321bdcae13516bd63f3c5d051b3ba33))
72
+ * Fix Rubocop Metrics/ParameterLists offense ([c7946b0](https://github.com/ruby-git/ruby-git/commit/c7946b089aba648d0e56a7435f85ed337e33d116))
73
+ * Fix Rubocop Metrics/PerceivedComplexity offense ([5dd5e0c](https://github.com/ruby-git/ruby-git/commit/5dd5e0c55fd37bb4baf3cf196f752a4f6c142ca7))
74
+ * Fix Rubocop Naming/AccessorMethodName offense ([e9d9c4f](https://github.com/ruby-git/ruby-git/commit/e9d9c4f2488d2527176b87c547caecfae4040219))
75
+ * Fix Rubocop Naming/HeredocDelimiterNaming offense ([b4297a5](https://github.com/ruby-git/ruby-git/commit/b4297a54ef4a0106e9786d10230a7219dcdbf0e8))
76
+ * Fix Rubocop Naming/PredicateMethod offense ([d33f7a8](https://github.com/ruby-git/ruby-git/commit/d33f7a8969ef1bf47adbca16589021647d5d2bb9))
77
+ * Fix Rubocop Naming/PredicatePrefix offense ([57edc79](https://github.com/ruby-git/ruby-git/commit/57edc7995750b8c1f792bcae480b9082e86d14d3))
78
+ * Fix Rubocop Naming/VariableNumber offense ([3fba6fa](https://github.com/ruby-git/ruby-git/commit/3fba6fa02908c632891c67f32ef7decc388e8147))
79
+ * Fix Rubocop Style/ClassVars offense ([a2f651a](https://github.com/ruby-git/ruby-git/commit/a2f651aea60e43b9b41271f03fe6cb6c4ef12b70))
80
+ * Fix Rubocop Style/Documentation offense ([e80c27d](https://github.com/ruby-git/ruby-git/commit/e80c27dbb50b38e71db55187ce1a630682d2ef3b))
81
+ * Fix Rubocop Style/IfUnlessModifier offense ([c974832](https://github.com/ruby-git/ruby-git/commit/c97483239e64477adab4ad047c094401ea008591))
82
+ * Fix Rubocop Style/MultilineBlockChain offense ([dd4e4ec](https://github.com/ruby-git/ruby-git/commit/dd4e4ecf0932ab02fa58ebe7a4189b44828729f5))
83
+ * Fix Rubocop Style/OptionalBooleanParameter offense ([c010a86](https://github.com/ruby-git/ruby-git/commit/c010a86cfc265054dc02ab4b7d778e4ba7e5426c))
84
+ * Fix typo in status.rb ([284fae7](https://github.com/ruby-git/ruby-git/commit/284fae7d3606724325ec21b0da7794d9eae2f0bd))
85
+ * Remove duplicate methods found by rubocop ([bd691c5](https://github.com/ruby-git/ruby-git/commit/bd691c58e3312662f07f8f96a1b48a7533f9a2e1))
86
+ * Result of running rake rubocop:autocorrect ([8f1e3bb](https://github.com/ruby-git/ruby-git/commit/8f1e3bb25fb4567093e9b49af42847a918d7d0c4))
87
+ * Result of running rake rubocop:autocorrect_all ([5c75783](https://github.com/ruby-git/ruby-git/commit/5c75783c0f50fb48d59012176cef7e985f7f83e2))
88
+
89
+
90
+ ### Other Changes
91
+
92
+ * Add rubocop todo file to silence known offenses until they can be fixed ([2c36f8c](https://github.com/ruby-git/ruby-git/commit/2c36f8c9eb8ff14defe8f6fff1b6eb81d277f620))
93
+ * Avoid deprecated dsa for tests keys ([1da8c28](https://github.com/ruby-git/ruby-git/commit/1da8c2894b727757a909d015fb5a4bcd00133f59))
94
+ * Fix yarddoc error caused by rubocop autocorrect ([58c4af3](https://github.com/ruby-git/ruby-git/commit/58c4af3513df3c854e49380adfe5685023275684))
95
+ * Integrate Rubocop with the project ([a04297d](https://github.com/ruby-git/ruby-git/commit/a04297d8d6568691b71402d9dbba36c45427ebc3))
96
+ * Rename Gem::Specification variable from s to spec ([4d976c4](https://github.com/ruby-git/ruby-git/commit/4d976c443c3a3cf25cc2fec7caa213ae7f090853))
97
+
8
98
  ## [4.0.0](https://github.com/ruby-git/ruby-git/compare/v3.1.1...v4.0.0) (2025-07-02)
9
99
 
10
100
 
data/README.md CHANGED
@@ -11,6 +11,7 @@
11
11
  [![Build Status](https://github.com/ruby-git/ruby-git/workflows/CI/badge.svg?branch=main)](https://github.com/ruby-git/ruby-git/actions?query=workflow%3ACI)
12
12
  [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)
13
13
 
14
+ - [📢 We Now Use RuboCop 📢](#-we-now-use-rubocop-)
14
15
  - [📢 Default Branch Rename 📢](#-default-branch-rename-)
15
16
  - [📢 We've Switched to Conventional Commits 📢](#-weve-switched-to-conventional-commits-)
16
17
  - [Summary](#summary)
@@ -23,6 +24,30 @@
23
24
  - [Ruby version support policy](#ruby-version-support-policy)
24
25
  - [License](#license)
25
26
 
27
+ ## 📢 We Now Use RuboCop 📢
28
+
29
+ To improve code consistency and maintainability, the `ruby-git` project has now
30
+ adopted [RuboCop](https://rubocop.org/) as our static code analyzer and formatter.
31
+
32
+ This integration is a key part of our ongoing commitment to making `ruby-git` a
33
+ high-quality, stable, and easy-to-contribute-to project. All new contributions will
34
+ be expected to adhere to the style guidelines enforced by our RuboCop configuration.
35
+
36
+ RuboCop can be run from the project's Rakefile:
37
+
38
+ ```shell
39
+ rake rubocop
40
+ ```
41
+
42
+ RuboCop is also run as part of the default rake task (by running `rake`) that is run
43
+ in our Continuous Integration workflow.
44
+
45
+ Going forward, any PRs that have any Robocop offenses will not be merged. In
46
+ certain rare cases, it might be acceptable to disable a RuboCop check for the most
47
+ limited scope possible.
48
+
49
+ If you have a problem fixing a RuboCop offense, don't be afraid to ask a contributor.
50
+
26
51
  ## 📢 Default Branch Rename 📢
27
52
 
28
53
  On June 6th, 2025, the default branch was renamed from 'master' to 'main'.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'English'
3
5
 
@@ -12,12 +14,22 @@ task :test do
12
14
  # You can run individual test files (or multiple files) from the command
13
15
  # line with:
14
16
  #
15
- # $ bin/test tests/units/test_archive.rb
17
+ # $ bin/test test_archive.rb
16
18
  #
17
- # $ bin/test tests/units/test_archive.rb tests/units/test_object.rb
19
+ # $ bin/test test_archive.rb test_object.rb
18
20
  end
19
21
  default_tasks << :test
20
22
 
23
+ # Rubocop
24
+
25
+ require 'rubocop/rake_task'
26
+
27
+ RuboCop::RakeTask.new
28
+
29
+ default_tasks << :rubocop
30
+
31
+ # YARD
32
+
21
33
  unless RUBY_PLATFORM == 'java' || RUBY_ENGINE == 'truffleruby'
22
34
  #
23
35
  # YARD documentation for this project can NOT be built with JRuby.
@@ -51,7 +63,7 @@ default_tasks << :build
51
63
  task default: default_tasks
52
64
 
53
65
  desc 'Build and install the git gem and run a sanity check'
54
- task :'test:gem' => :install do
66
+ task 'test:gem': :install do
55
67
  output = `ruby -e "require 'git'; g = Git.open('.'); puts g.log.size"`.chomp
56
68
  raise 'Gem test failed' unless $CHILD_STATUS.success?
57
69
  raise 'Expected gem test to return an integer' unless output =~ /^\d+$/
data/git.gemspec CHANGED
@@ -1,52 +1,57 @@
1
- $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('lib', __dir__)
2
4
  require 'git/version'
3
5
 
4
- Gem::Specification.new do |s|
5
- s.author = 'Scott Chacon and others'
6
- s.email = 'schacon@gmail.com'
7
- s.homepage = 'http://github.com/ruby-git/ruby-git'
8
- s.license = 'MIT'
9
- s.name = 'git'
10
- s.summary = 'An API to create, read, and manipulate Git repositories'
11
- s.description = <<~DESCRIPTION
6
+ Gem::Specification.new do |spec|
7
+ spec.author = 'Scott Chacon and others'
8
+ spec.email = 'schacon@gmail.com'
9
+ spec.homepage = 'http://github.com/ruby-git/ruby-git'
10
+ spec.license = 'MIT'
11
+ spec.name = 'git'
12
+ spec.summary = 'An API to create, read, and manipulate Git repositories'
13
+ spec.description = <<~DESCRIPTION
12
14
  The git gem provides an API that can be used to
13
15
  create, read, and manipulate Git repositories by wrapping system calls to the git
14
16
  command line. The API can be used for working with Git in complex interactions
15
17
  including branching and merging, object inspection and manipulation, history, patch
16
18
  generation and more.
17
19
  DESCRIPTION
18
- s.version = Git::VERSION
20
+ spec.version = Git::VERSION
19
21
 
22
+ spec.metadata['homepage_uri'] = spec.homepage
23
+ spec.metadata['source_code_uri'] = spec.homepage
24
+ spec.metadata['changelog_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}/file/CHANGELOG.md"
25
+ spec.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}"
26
+ spec.metadata['rubygems_mfa_required'] = 'true'
20
27
 
21
- s.metadata['homepage_uri'] = s.homepage
22
- s.metadata['source_code_uri'] = s.homepage
23
- s.metadata['changelog_uri'] = "https://rubydoc.info/gems/#{s.name}/#{s.version}/file/CHANGELOG.md"
24
- s.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{s.name}/#{s.version}"
28
+ spec.require_paths = ['lib']
29
+ spec.required_ruby_version = '>= 3.2.0'
30
+ spec.requirements = ['git 2.28.0 or greater']
25
31
 
26
- s.require_paths = ['lib']
27
- s.required_ruby_version = '>= 3.2.0'
28
- s.requirements = ['git 2.28.0 or greater']
32
+ spec.add_dependency 'activesupport', '>= 5.0'
33
+ spec.add_dependency 'addressable', '~> 2.8'
34
+ spec.add_dependency 'process_executer', '~> 4.0'
35
+ spec.add_dependency 'rchardet', '~> 1.9'
29
36
 
30
- s.add_runtime_dependency 'activesupport', '>= 5.0'
31
- s.add_runtime_dependency 'addressable', '~> 2.8'
32
- s.add_runtime_dependency 'process_executer', '~> 4.0'
33
- s.add_runtime_dependency 'rchardet', '~> 1.9'
37
+ spec.add_development_dependency 'create_github_release', '~> 2.1'
38
+ spec.add_development_dependency 'main_branch_shared_rubocop_config', '~> 0.1'
39
+ spec.add_development_dependency 'minitar', '~> 1.0'
40
+ spec.add_development_dependency 'mocha', '~> 2.7'
41
+ spec.add_development_dependency 'rake', '~> 13.2'
42
+ spec.add_development_dependency 'rubocop', '~> 1.77'
34
43
 
35
- s.add_development_dependency 'create_github_release', '~> 2.1'
36
- s.add_development_dependency 'minitar', '~> 1.0'
37
- s.add_development_dependency 'mocha', '~> 2.7'
38
- s.add_development_dependency 'rake', '~> 13.2'
39
- s.add_development_dependency 'test-unit', '~> 3.6'
44
+ spec.add_development_dependency 'test-unit', '~> 3.6'
40
45
 
41
46
  unless RUBY_PLATFORM == 'java'
42
- s.add_development_dependency 'redcarpet', '~> 3.6'
43
- s.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
44
- s.add_development_dependency 'yardstick', '~> 0.9'
47
+ spec.add_development_dependency 'redcarpet', '~> 3.6'
48
+ spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
49
+ spec.add_development_dependency 'yardstick', '~> 0.9'
45
50
  end
46
51
 
47
52
  # Specify which files should be added to the gem when it is released.
48
53
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
49
- s.files = Dir.chdir(File.expand_path(__dir__)) do
54
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
50
55
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(tests|spec|features|bin)/}) }
51
56
  end
52
57
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Git
4
+ # Takes a hash of user options and a declarative map and produces
5
+ # an array of command-line arguments. Also validates that only
6
+ # supported options are provided based on the map.
7
+ #
8
+ # @api private
9
+ class ArgsBuilder
10
+ # This hash maps an option type to a lambda that knows how to build the
11
+ # corresponding command-line argument. This is a scalable dispatch table.
12
+ ARG_BUILDERS = {
13
+ boolean: ->(config, value) { value ? config[:flag] : [] },
14
+
15
+ valued_equals: ->(config, value) { "#{config[:flag]}=#{value}" if value },
16
+
17
+ valued_space: ->(config, value) { [config[:flag], value.to_s] if value },
18
+
19
+ repeatable_valued_space: lambda do |config, value|
20
+ Array(value).flat_map { |v| [config[:flag], v.to_s] }
21
+ end,
22
+
23
+ custom: ->(config, value) { config[:builder].call(value) },
24
+
25
+ validate_only: ->(_config, _value) { [] } # Does not build any args
26
+ }.freeze
27
+
28
+ # Main entrypoint to validate options and build arguments
29
+ def self.build(opts, option_map)
30
+ validate!(opts, option_map)
31
+ new(opts, option_map).build
32
+ end
33
+
34
+ # Public validation method that can be called independently
35
+ def self.validate!(opts, option_map)
36
+ validate_unsupported_keys!(opts, option_map)
37
+ validate_configured_options!(opts, option_map)
38
+ end
39
+
40
+ def initialize(opts, option_map)
41
+ @opts = opts
42
+ @option_map = option_map
43
+ end
44
+
45
+ def build
46
+ @option_map.flat_map do |config|
47
+ type = config[:type]
48
+ next config[:flag] if type == :static
49
+
50
+ key = config[:keys].find { |k| @opts.key?(k) }
51
+ next [] unless key
52
+
53
+ build_arg_for_option(config, @opts[key])
54
+ end.compact
55
+ end
56
+
57
+ private
58
+
59
+ def build_arg_for_option(config, value)
60
+ builder = ARG_BUILDERS[config[:type]]
61
+ builder&.call(config, value) || []
62
+ end
63
+
64
+ private_class_method def self.validate_unsupported_keys!(opts, option_map)
65
+ all_valid_keys = option_map.flat_map { |config| config[:keys] }.compact
66
+ unsupported_keys = opts.keys - all_valid_keys
67
+
68
+ return if unsupported_keys.empty?
69
+
70
+ raise ArgumentError, "Unsupported options: #{unsupported_keys.map(&:inspect).join(', ')}"
71
+ end
72
+
73
+ private_class_method def self.validate_configured_options!(opts, option_map)
74
+ option_map.each do |config|
75
+ next unless config[:keys] # Skip static flags
76
+
77
+ check_for_missing_required_option!(opts, config)
78
+ validate_option_value!(opts, config)
79
+ end
80
+ end
81
+
82
+ private_class_method def self.check_for_missing_required_option!(opts, config)
83
+ return unless config[:required]
84
+
85
+ key_provided = config[:keys].any? { |k| opts.key?(k) }
86
+ return if key_provided
87
+
88
+ raise ArgumentError, "Missing required option: #{config[:keys].first}"
89
+ end
90
+
91
+ private_class_method def self.validate_option_value!(opts, config)
92
+ validator = config[:validator]
93
+ return unless validator
94
+
95
+ user_key = config[:keys].find { |k| opts.key?(k) }
96
+ return unless user_key # Don't validate if the user didn't provide the option
97
+
98
+ return if validator.call(opts[user_key])
99
+
100
+ raise ArgumentError, "Invalid value for option: #{user_key}"
101
+ end
102
+ end
103
+ end
data/lib/git/author.rb CHANGED
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Git
4
+ # An author in a Git commit
4
5
  class Author
5
6
  attr_accessor :name, :email, :date
6
7
 
7
8
  def initialize(author_string)
8
- if m = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string)
9
- @name = m[1]
10
- @email = m[2]
11
- @date = Time.at(m[3].to_i)
12
- end
9
+ return unless (m = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string))
10
+
11
+ @name = m[1]
12
+ @email = m[2]
13
+ @date = Time.at(m[3].to_i)
13
14
  end
14
15
  end
15
16
  end