git 4.0.0 → 4.0.2
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 +4 -4
- data/.gitignore +1 -0
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +51 -0
- data/.rubocop_todo.yml +12 -0
- data/CHANGELOG.md +57 -0
- data/README.md +25 -0
- data/Rakefile +15 -3
- data/git.gemspec +35 -30
- data/lib/git/args_builder.rb +103 -0
- data/lib/git/author.rb +6 -5
- data/lib/git/base.rb +254 -165
- data/lib/git/branch.rb +14 -15
- data/lib/git/branches.rb +9 -13
- data/lib/git/command_line.rb +97 -55
- data/lib/git/config.rb +4 -6
- data/lib/git/diff.rb +75 -39
- data/lib/git/diff_path_status.rb +4 -3
- data/lib/git/diff_stats.rb +1 -1
- data/lib/git/errors.rb +8 -2
- data/lib/git/escaped_path.rb +1 -1
- data/lib/git/lib.rb +865 -557
- data/lib/git/log.rb +74 -210
- data/lib/git/object.rb +85 -66
- data/lib/git/path.rb +18 -8
- data/lib/git/remote.rb +3 -4
- data/lib/git/repository.rb +0 -2
- data/lib/git/stash.rb +13 -6
- data/lib/git/stashes.rb +5 -5
- data/lib/git/status.rb +108 -247
- data/lib/git/url.rb +3 -3
- data/lib/git/version.rb +1 -1
- data/lib/git/worktree.rb +4 -5
- data/lib/git/worktrees.rb +4 -6
- data/lib/git.rb +16 -15
- metadata +35 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edf8c0ca68f2c4a5e2ecd4a72cfc49bf30edf8406bd7016ebd8e96e8bb016065
|
4
|
+
data.tar.gz: 76c74e062482a50b780c3af13767e5bbd9d361f7fe4aad44c593d11de53a3acf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49d11d3ae7d6a26365c594381f94d426130fa3d62c819d575b1b8868fa9af3f83b42ba81b0a9404e3aeedc422962f13d6f10203bdfd2074e9e9fbc36c1fc3422
|
7
|
+
data.tar.gz: bf6e926d267120715fbfef1d2008dc3f4951130cdfe6266203caceb9fe63bd55c02282b0798a39c3917ea927af6215da805253eb85210a35a531bc066e62ed78
|
data/.gitignore
CHANGED
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,63 @@
|
|
5
5
|
|
6
6
|
# Change Log
|
7
7
|
|
8
|
+
## [4.0.2](https://github.com/ruby-git/ruby-git/compare/v4.0.1...v4.0.2) (2025-07-08)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Call Git::Index#new correctly from initialize_components ([07dfab5](https://github.com/ruby-git/ruby-git/commit/07dfab5804874cbc52469bd40203b6d0b08be7a1))
|
14
|
+
|
15
|
+
|
16
|
+
### Other Changes
|
17
|
+
|
18
|
+
* Announce that the project has adopted RuboCop ([3d6cac9](https://github.com/ruby-git/ruby-git/commit/3d6cac94b47b3c1b1915f5c37f9e811041210ddc))
|
19
|
+
* Update comment to be accurate ([3a87722](https://github.com/ruby-git/ruby-git/commit/3a87722760176db54dfef9631de6191b183ab223))
|
20
|
+
|
21
|
+
## [4.0.1](https://github.com/ruby-git/ruby-git/compare/v4.0.0...v4.0.1) (2025-07-06)
|
22
|
+
|
23
|
+
|
24
|
+
### Bug Fixes
|
25
|
+
|
26
|
+
* Fix Rubocop Layout/LineLength offense ([52d80ac](https://github.com/ruby-git/ruby-git/commit/52d80ac592d9139655d47af8e764eebf8577fda7))
|
27
|
+
* Fix Rubocop Lint/EmptyBlock offense ([9081f0f](https://github.com/ruby-git/ruby-git/commit/9081f0fb055e0d6cc693fd8f8bf47b2fa13efef0))
|
28
|
+
* Fix Rubocop Lint/MissingSuper offense ([e9e91a8](https://github.com/ruby-git/ruby-git/commit/e9e91a88fc338944b816ee6929cadf06ff1daab5))
|
29
|
+
* Fix Rubocop Lint/StructNewOverride offense ([141c2cf](https://github.com/ruby-git/ruby-git/commit/141c2cfd8215f5120f536f78b3c066751d74aabe))
|
30
|
+
* Fix Rubocop Lint/SuppressedException offense ([4372a20](https://github.com/ruby-git/ruby-git/commit/4372a20b0b61e862efb7558f2274769ae17aa2c9))
|
31
|
+
* Fix Rubocop Lint/UselessConstantScoping offense ([54c4a3b](https://github.com/ruby-git/ruby-git/commit/54c4a3bba206ab379a0849fbc9478db5b61e192a))
|
32
|
+
* Fix Rubocop Metrics/AbcSize offense ([256d860](https://github.com/ruby-git/ruby-git/commit/256d8602a4024d1fbe432eda8bbcb1891fb726bc))
|
33
|
+
* Fix Rubocop Metrics/BlockLength offense ([9c856ba](https://github.com/ruby-git/ruby-git/commit/9c856ba42d0955cb6c3f5848f9c3253b54fd3735))
|
34
|
+
* Fix Rubocop Metrics/ClassLength offense (exclude tests) ([d70c800](https://github.com/ruby-git/ruby-git/commit/d70c800263ff1347109688dbb5b66940c6d64f2c))
|
35
|
+
* Fix Rubocop Metrics/ClassLength offense (refactor Git::Log) ([1aae57a](https://github.com/ruby-git/ruby-git/commit/1aae57a631aa331a84c37122ffc8fa09b415c6c5))
|
36
|
+
* Fix Rubocop Metrics/ClassLength offense (refactor Git::Status) ([e3a378b](https://github.com/ruby-git/ruby-git/commit/e3a378b6384bf1d0dc80ebc5aea792f9ff5b512a))
|
37
|
+
* Fix Rubocop Metrics/CyclomaticComplexity offense ([abfcf94](https://github.com/ruby-git/ruby-git/commit/abfcf948a08578635f7e832c31deaf992e6f3fb1))
|
38
|
+
* Fix Rubocop Metrics/MethodLength offense ([e708c36](https://github.com/ruby-git/ruby-git/commit/e708c3673321bdcae13516bd63f3c5d051b3ba33))
|
39
|
+
* Fix Rubocop Metrics/ParameterLists offense ([c7946b0](https://github.com/ruby-git/ruby-git/commit/c7946b089aba648d0e56a7435f85ed337e33d116))
|
40
|
+
* Fix Rubocop Metrics/PerceivedComplexity offense ([5dd5e0c](https://github.com/ruby-git/ruby-git/commit/5dd5e0c55fd37bb4baf3cf196f752a4f6c142ca7))
|
41
|
+
* Fix Rubocop Naming/AccessorMethodName offense ([e9d9c4f](https://github.com/ruby-git/ruby-git/commit/e9d9c4f2488d2527176b87c547caecfae4040219))
|
42
|
+
* Fix Rubocop Naming/HeredocDelimiterNaming offense ([b4297a5](https://github.com/ruby-git/ruby-git/commit/b4297a54ef4a0106e9786d10230a7219dcdbf0e8))
|
43
|
+
* Fix Rubocop Naming/PredicateMethod offense ([d33f7a8](https://github.com/ruby-git/ruby-git/commit/d33f7a8969ef1bf47adbca16589021647d5d2bb9))
|
44
|
+
* Fix Rubocop Naming/PredicatePrefix offense ([57edc79](https://github.com/ruby-git/ruby-git/commit/57edc7995750b8c1f792bcae480b9082e86d14d3))
|
45
|
+
* Fix Rubocop Naming/VariableNumber offense ([3fba6fa](https://github.com/ruby-git/ruby-git/commit/3fba6fa02908c632891c67f32ef7decc388e8147))
|
46
|
+
* Fix Rubocop Style/ClassVars offense ([a2f651a](https://github.com/ruby-git/ruby-git/commit/a2f651aea60e43b9b41271f03fe6cb6c4ef12b70))
|
47
|
+
* Fix Rubocop Style/Documentation offense ([e80c27d](https://github.com/ruby-git/ruby-git/commit/e80c27dbb50b38e71db55187ce1a630682d2ef3b))
|
48
|
+
* Fix Rubocop Style/IfUnlessModifier offense ([c974832](https://github.com/ruby-git/ruby-git/commit/c97483239e64477adab4ad047c094401ea008591))
|
49
|
+
* Fix Rubocop Style/MultilineBlockChain offense ([dd4e4ec](https://github.com/ruby-git/ruby-git/commit/dd4e4ecf0932ab02fa58ebe7a4189b44828729f5))
|
50
|
+
* Fix Rubocop Style/OptionalBooleanParameter offense ([c010a86](https://github.com/ruby-git/ruby-git/commit/c010a86cfc265054dc02ab4b7d778e4ba7e5426c))
|
51
|
+
* Fix typo in status.rb ([284fae7](https://github.com/ruby-git/ruby-git/commit/284fae7d3606724325ec21b0da7794d9eae2f0bd))
|
52
|
+
* Remove duplicate methods found by rubocop ([bd691c5](https://github.com/ruby-git/ruby-git/commit/bd691c58e3312662f07f8f96a1b48a7533f9a2e1))
|
53
|
+
* Result of running rake rubocop:autocorrect ([8f1e3bb](https://github.com/ruby-git/ruby-git/commit/8f1e3bb25fb4567093e9b49af42847a918d7d0c4))
|
54
|
+
* Result of running rake rubocop:autocorrect_all ([5c75783](https://github.com/ruby-git/ruby-git/commit/5c75783c0f50fb48d59012176cef7e985f7f83e2))
|
55
|
+
|
56
|
+
|
57
|
+
### Other Changes
|
58
|
+
|
59
|
+
* Add rubocop todo file to silence known offenses until they can be fixed ([2c36f8c](https://github.com/ruby-git/ruby-git/commit/2c36f8c9eb8ff14defe8f6fff1b6eb81d277f620))
|
60
|
+
* Avoid deprecated dsa for tests keys ([1da8c28](https://github.com/ruby-git/ruby-git/commit/1da8c2894b727757a909d015fb5a4bcd00133f59))
|
61
|
+
* Fix yarddoc error caused by rubocop autocorrect ([58c4af3](https://github.com/ruby-git/ruby-git/commit/58c4af3513df3c854e49380adfe5685023275684))
|
62
|
+
* Integrate Rubocop with the project ([a04297d](https://github.com/ruby-git/ruby-git/commit/a04297d8d6568691b71402d9dbba36c45427ebc3))
|
63
|
+
* Rename Gem::Specification variable from s to spec ([4d976c4](https://github.com/ruby-git/ruby-git/commit/4d976c443c3a3cf25cc2fec7caa213ae7f090853))
|
64
|
+
|
8
65
|
## [4.0.0](https://github.com/ruby-git/ruby-git/compare/v3.1.1...v4.0.0) (2025-07-02)
|
9
66
|
|
10
67
|
|
data/README.md
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
[](https://github.com/ruby-git/ruby-git/actions?query=workflow%3ACI)
|
12
12
|
[](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
|
17
|
+
# $ bin/test test_archive.rb
|
16
18
|
#
|
17
|
-
# $ bin/test
|
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
|
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
|
-
|
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 |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|