gitt 2.1.1 → 3.0.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +36 -15
- data/gitt.gemspec +4 -4
- data/lib/gitt/commands/branch.rb +8 -3
- data/lib/gitt/commands/config.rb +5 -7
- data/lib/gitt/commands/log.rb +24 -5
- data/lib/gitt/commands/tag.rb +9 -3
- data/lib/gitt/directable.rb +16 -0
- data/lib/gitt/models/commit.rb +24 -4
- data/lib/gitt/models/person.rb +12 -4
- data/lib/gitt/models/trailer.rb +3 -4
- data/lib/gitt/parsers/attributer.rb +9 -7
- data/lib/gitt/parsers/commit.rb +8 -5
- data/lib/gitt/parsers/person.rb +15 -13
- data/lib/gitt/parsers/tag.rb +3 -3
- data/lib/gitt/parsers/trailer.rb +4 -3
- data/lib/gitt/repository.rb +1 -1
- data/lib/gitt/rspec/shared_contexts/git_repo.rb +1 -1
- data/lib/gitt/rspec/shared_contexts/temp_dir.rb +1 -1
- data/lib/gitt/sanitizers/container.rb +1 -0
- data/lib/gitt/sanitizers/date.rb +3 -1
- data/lib/gitt/sanitizers/email.rb +3 -1
- data/lib/gitt/sanitizers/scissors.rb +3 -1
- data/lib/gitt/sanitizers/statistic.rb +41 -0
- data/lib/gitt/shell.rb +2 -2
- data/lib/gitt.rb +2 -0
- data.tar.gz.sig +0 -0
- metadata +10 -11
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a62c7af41ef6056ceb816436a8c80f1d2ee3fd792fbbcadadbc82a2b5eba97d
|
4
|
+
data.tar.gz: bc3d13fbd0296b5ca483f02033446fc79fbbd46617d0fd2b06cf07477ba06d3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df96432454f47a6d4fd57c741949dabd088f61c1a62af03b25fac1860a766b52ecf19e7bd3973b29ee617e1c015588953ba34ca17fd56201f894ec9279819f80
|
7
|
+
data.tar.gz: da01de46bb99ad4c59a328101772184703da241949ba9678dfb19c71c2e616a7fd6ab4d422035592ffe15473d33663e4e07e73fa9dede99c5e06660940d9ecdb
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/README.adoc
CHANGED
@@ -24,7 +24,7 @@ toc::[]
|
|
24
24
|
== Features
|
25
25
|
|
26
26
|
* Wraps a subset of native {git_link} commands with additional enhancements to improve your working experience.
|
27
|
-
* Answers link:https://dry-rb.org/gems/dry-monads[monads] you can
|
27
|
+
* Answers link:https://dry-rb.org/gems/dry-monads[monads] you can link:https://alchemists.io/projects/transactable[pipe] together for more complex workflows.
|
28
28
|
* Provides _optional_ {rspec_link} shared contexts that speed up the testing of your own Git related implementations.
|
29
29
|
|
30
30
|
== Requirements
|
@@ -65,17 +65,19 @@ git.tag? # Answers if local or remote tag exists.
|
|
65
65
|
git.tag_create # Create a new tag.
|
66
66
|
git.tag_last # Answers last tag created.
|
67
67
|
git.tag_local? # Answers if local tag exists?
|
68
|
-
git.tag_parse # Parses and answers a tag record.
|
69
68
|
git.tag_remote? # Answers if remote tag exists?
|
69
|
+
git.tag_show # Answers information about a single tag.
|
70
70
|
git.tagged? # Answers if the repository has any tags.
|
71
|
+
git.tags # Answers all tags.
|
71
72
|
git.tags_push # Pushes local tags to remote git.
|
72
73
|
git.uncommitted # Parses a file and answers an unsaved commit message.
|
74
|
+
|
73
75
|
----
|
74
76
|
|
75
77
|
=== Commands
|
76
78
|
|
77
79
|
Should you want to use individual commands instead of interacting with the `Repository` object, you
|
78
|
-
can leverage any of the objects in the `Commands` namespace which -- at a minimum -- use the link:https://alchemists.io/articles/interactor_pattern[Command Pattern]. Here are the
|
80
|
+
can leverage any of the objects in the `Commands` namespace which -- at a minimum -- use the link:https://alchemists.io/articles/interactor_pattern[Command Pattern]. Here are the specific commands which are enhanced further:
|
79
81
|
|
80
82
|
==== link:https://git-scm.com/docs/git-branch[Branch]
|
81
83
|
|
@@ -85,9 +87,12 @@ Handles branches.
|
|
85
87
|
----
|
86
88
|
branch = Gitt::Commands::Branch.new
|
87
89
|
|
88
|
-
# Answers branch default (via Git `init.defaultBranch` configuration).
|
90
|
+
# Answers branch default (via Git `init.defaultBranch` configuration) of if blank.
|
89
91
|
branch.default # Success "main"
|
90
92
|
|
93
|
+
# Answers branch default fallback if unset or error is detected.
|
94
|
+
branch.default "source" # Success "source"
|
95
|
+
|
91
96
|
# Accepts any argument you'd send to `git branch`. Example:
|
92
97
|
branch.call "--list" # Success " main\n"
|
93
98
|
|
@@ -157,6 +162,9 @@ tag = Gitt::Commands::Tag.new
|
|
157
162
|
# Example: tag.call "--list"
|
158
163
|
stdout, stderr, status = tag.call
|
159
164
|
|
165
|
+
# Creates a new tag.
|
166
|
+
tag.create "0.0.0", "Version 0.0.0"
|
167
|
+
|
160
168
|
# Answers true or false base on whether local and remote tag exist.
|
161
169
|
tag.exist? "0.1.0"
|
162
170
|
|
@@ -172,6 +180,9 @@ tag.push
|
|
172
180
|
# Answers if remote tag exists.
|
173
181
|
tag.remote? "0.1.0"
|
174
182
|
|
183
|
+
# Answers details about a specific tag.
|
184
|
+
tag.show "1.0.0"
|
185
|
+
|
175
186
|
# Answers true or false based on whether repository is tagged.
|
176
187
|
tag.tagged?
|
177
188
|
----
|
@@ -221,21 +232,31 @@ An instance of `Gitt::Models::Tag` is what is answered back to when using `Gitt:
|
|
221
232
|
[source,ruby]
|
222
233
|
----
|
223
234
|
# #<struct Gitt::Models::Tag
|
224
|
-
# author_date="Tue Dec 29 17:33:01 2020 -0700",
|
225
235
|
# author_email="demo@example.com",
|
226
|
-
# author_name="
|
227
|
-
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
236
|
+
# author_name="Brooke Kuhlmann",
|
237
|
+
# authored_at="1671892451",
|
238
|
+
# authored_relative_at="1 year ago",
|
239
|
+
# body="A demo body.",
|
240
|
+
# committed_at="1671997684",
|
241
|
+
# committed_relative_at="1 year ago",
|
242
|
+
# committer_email="demo@example.com",
|
243
|
+
# committer_name="Brooke Kuhlmann",
|
244
|
+
# sha="662f32b2846c7bd4f153560478f035197f5279d5",
|
245
|
+
# subject="Version 1.0.0",
|
246
|
+
# version="1.0.0">
|
231
247
|
----
|
232
248
|
|
233
249
|
You get a {struct_link} with the following attributes:
|
234
250
|
|
235
|
-
* `author_date`: Stores author creation date.
|
236
251
|
* `author_email`: Stores author email.
|
237
252
|
* `author_name`: Store author name.
|
253
|
+
* `authored_at`: Stores author creation date.
|
254
|
+
* `authored_relative_at`: Stores author creation date relative to current time.
|
238
255
|
* `body`: Stores body of tag which can be sentences, multiple paragraphs, and/or signature information.
|
256
|
+
* `committer_email`: Stores committer email.
|
257
|
+
* `committer_name`: Store committer name.
|
258
|
+
* `committed_at`: Stores committer creation date.
|
259
|
+
* `committed_relative_at`: Stores committer creation date relative to current time.
|
239
260
|
* `sha`: Stores the commit SHA for which this tag labels
|
240
261
|
* `subject`: Stores the subject.
|
241
262
|
* `version`: Stores the version.
|
@@ -280,12 +301,12 @@ Provides a simple Git repository with a single commit for testing purposes. This
|
|
280
301
|
[source,ruby]
|
281
302
|
----
|
282
303
|
require "gitt/rspec/shared_contexts/git_repo"
|
283
|
-
require "refinements/
|
304
|
+
require "refinements/pathname"
|
284
305
|
|
285
306
|
describe Demo do
|
286
307
|
include_context "with Git repository"
|
287
308
|
|
288
|
-
using Refinements::
|
309
|
+
using Refinements::Pathname
|
289
310
|
|
290
311
|
it "is a demo" do
|
291
312
|
git_repo_dir.change_dir { # Your expectation goes here. }
|
@@ -300,12 +321,12 @@ Provides a temporary directory (i.e. `tmp/rspec`) for creating directories and o
|
|
300
321
|
[source,ruby]
|
301
322
|
----
|
302
323
|
require "gitt/rspec/shared_contexts/temp_dir"
|
303
|
-
require "refinements/
|
324
|
+
require "refinements/pathname"
|
304
325
|
|
305
326
|
describe Demo do
|
306
327
|
include_context "with temporary directory"
|
307
328
|
|
308
|
-
using Refinements::
|
329
|
+
using Refinements::Pathname
|
309
330
|
|
310
331
|
it "is a demo" do
|
311
332
|
temp_dir.change_dir { # Your expectation goes here. }
|
data/gitt.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "gitt"
|
5
|
-
spec.version = "
|
5
|
+
spec.version = "3.0.0"
|
6
6
|
spec.authors = ["Brooke Kuhlmann"]
|
7
7
|
spec.email = ["brooke@alchemists.io"]
|
8
8
|
spec.homepage = "https://alchemists.io/projects/gitt"
|
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.signing_key = Gem.default_key_path
|
23
23
|
spec.cert_chain = [Gem.default_cert_path]
|
24
24
|
|
25
|
-
spec.required_ruby_version =
|
26
|
-
spec.add_dependency "core", "~> 0
|
25
|
+
spec.required_ruby_version = "~> 3.3"
|
26
|
+
spec.add_dependency "core", "~> 1.0"
|
27
27
|
spec.add_dependency "dry-monads", "~> 1.6"
|
28
|
-
spec.add_dependency "refinements", "~>
|
28
|
+
spec.add_dependency "refinements", "~> 12.0"
|
29
29
|
spec.add_dependency "zeitwerk", "~> 2.6"
|
30
30
|
|
31
31
|
spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
|
data/lib/gitt/commands/branch.rb
CHANGED
@@ -1,20 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "dry/monads"
|
4
|
+
|
3
5
|
module Gitt
|
4
6
|
module Commands
|
5
7
|
# A Git branch command wrapper.
|
6
8
|
class Branch
|
9
|
+
include Dry::Monads[:result]
|
10
|
+
|
7
11
|
def initialize shell: SHELL
|
8
12
|
@shell = shell
|
9
13
|
end
|
10
14
|
|
11
|
-
def default
|
15
|
+
def default fallback = "main"
|
12
16
|
shell.call("config", "init.defaultBranch")
|
13
17
|
.fmap(&:chomp)
|
14
|
-
.fmap { |name| name.empty? ?
|
18
|
+
.fmap { |name| name.empty? ? fallback : name }
|
19
|
+
.or(Success(fallback))
|
15
20
|
end
|
16
21
|
|
17
|
-
def call(*
|
22
|
+
def call(*) = shell.call("branch", *)
|
18
23
|
|
19
24
|
def name = shell.call("rev-parse", "--abbrev-ref", "HEAD").fmap(&:chomp)
|
20
25
|
|
data/lib/gitt/commands/config.rb
CHANGED
@@ -13,18 +13,16 @@ module Gitt
|
|
13
13
|
@shell = shell
|
14
14
|
end
|
15
15
|
|
16
|
-
def call(*
|
16
|
+
def call(*) = shell.call("config", *)
|
17
17
|
|
18
|
-
def get
|
19
|
-
call(
|
20
|
-
|
21
|
-
block_given? ? yield(error) : Success(fallback)
|
22
|
-
end
|
18
|
+
def get(key, fallback = Core::EMPTY_STRING, *)
|
19
|
+
call(*, "--get", key).fmap(&:chomp)
|
20
|
+
.or { |error| block_given? ? yield(error) : Success(fallback) }
|
23
21
|
end
|
24
22
|
|
25
23
|
def origin? = !get("remote.origin.url").value_or(Core::EMPTY_STRING).empty?
|
26
24
|
|
27
|
-
def set(key, value, *
|
25
|
+
def set(key, value, *) = call(*, "--add", key, value).fmap { value }
|
28
26
|
|
29
27
|
private
|
30
28
|
|
data/lib/gitt/commands/log.rb
CHANGED
@@ -18,6 +18,8 @@ module Gitt
|
|
18
18
|
committed_relative_at: "%cr",
|
19
19
|
committer_email: "%ce",
|
20
20
|
committer_name: "%cn",
|
21
|
+
encoding: "%e",
|
22
|
+
notes: "%N",
|
21
23
|
raw: "%B",
|
22
24
|
sha: "%H",
|
23
25
|
signature: "%G?",
|
@@ -25,18 +27,18 @@ module Gitt
|
|
25
27
|
trailers: "%(trailers)"
|
26
28
|
}.freeze
|
27
29
|
|
28
|
-
def initialize shell: SHELL, key_map: KEY_MAP, parser: Parsers::Commit
|
30
|
+
def initialize shell: SHELL, key_map: KEY_MAP, parser: Parsers::Commit.new
|
29
31
|
@shell = shell
|
30
32
|
@key_map = key_map
|
31
33
|
@parser = parser
|
32
34
|
end
|
33
35
|
|
34
|
-
def call(*
|
36
|
+
def call(*) = shell.call("log", *)
|
35
37
|
|
36
38
|
def index *arguments
|
37
|
-
arguments.prepend(pretty_format)
|
39
|
+
arguments.prepend("--shortstat", pretty_format)
|
38
40
|
.then { |pretty_format| call(*pretty_format) }
|
39
|
-
.fmap { |content| String(content).scrub("?")
|
41
|
+
.fmap { |content| String(content).scrub("?") }
|
40
42
|
.fmap { |entries| build_records entries }
|
41
43
|
end
|
42
44
|
|
@@ -58,7 +60,24 @@ module Gitt
|
|
58
60
|
.then { |structure| %(--pretty=format:"#{structure}") }
|
59
61
|
end
|
60
62
|
|
61
|
-
def build_records
|
63
|
+
def build_records entries
|
64
|
+
wrap_statistics entries
|
65
|
+
add_empty_statistics entries
|
66
|
+
entries.split("<break/>").map { |entry| parser.call entry }
|
67
|
+
end
|
68
|
+
|
69
|
+
# :reek:UtilityFunction
|
70
|
+
def wrap_statistics entries
|
71
|
+
entries.gsub!(/\d+\sfile.+\d+\s(insertion|deletion).+\n/) do |match|
|
72
|
+
"<statistics>#{match}</statistics><break/>"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# :reek:UtilityFunction
|
77
|
+
def add_empty_statistics entries
|
78
|
+
entries.gsub! %(</trailers>\n"\n"<author_email>),
|
79
|
+
"</trailers>\n<statistics></statistics>\n<author_email>"
|
80
|
+
end
|
62
81
|
end
|
63
82
|
end
|
64
83
|
end
|
data/lib/gitt/commands/tag.rb
CHANGED
@@ -31,7 +31,7 @@ module Gitt
|
|
31
31
|
@parser = parser
|
32
32
|
end
|
33
33
|
|
34
|
-
def call(*
|
34
|
+
def call(*) = shell.call("tag", *)
|
35
35
|
|
36
36
|
def create version, body = Core::EMPTY_STRING, *flags
|
37
37
|
return Failure "Unable to create Git tag without version." unless version
|
@@ -53,9 +53,15 @@ module Gitt
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def last
|
56
|
-
shell.call("describe", "--abbrev=0", "--tags"
|
56
|
+
shell.call("describe", "--abbrev=0", "--tags")
|
57
57
|
.fmap(&:strip)
|
58
|
-
.or
|
58
|
+
.or do |error|
|
59
|
+
if error.match?(/no names found/i)
|
60
|
+
Failure "No tags found."
|
61
|
+
else
|
62
|
+
Failure error.delete_prefix("fatal: ").chomp
|
63
|
+
end
|
64
|
+
end
|
59
65
|
end
|
60
66
|
|
61
67
|
def local? version
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitt
|
4
|
+
# Provides shared behavior for objects that can act like a commit.
|
5
|
+
module Directable
|
6
|
+
def directive? = amend? || fixup? || squash?
|
7
|
+
|
8
|
+
def amend? = subject.match?(/\Aamend!\s/)
|
9
|
+
|
10
|
+
def fixup? = subject.match?(/\Afixup!\s/)
|
11
|
+
|
12
|
+
def squash? = subject.match?(/\Asquash!\s/)
|
13
|
+
|
14
|
+
def prefix = subject[/\A[\w\!]+/]
|
15
|
+
end
|
16
|
+
end
|
data/lib/gitt/models/commit.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "dry/monads"
|
4
|
+
|
3
5
|
module Gitt
|
4
6
|
module Models
|
5
7
|
# Represents commit details.
|
@@ -15,25 +17,43 @@ module Gitt
|
|
15
17
|
:committed_relative_at,
|
16
18
|
:committer_email,
|
17
19
|
:committer_name,
|
20
|
+
:deletions,
|
21
|
+
:encoding,
|
22
|
+
:files_changed,
|
23
|
+
:insertions,
|
18
24
|
:lines,
|
25
|
+
:notes,
|
19
26
|
:raw,
|
20
27
|
:sha,
|
21
28
|
:signature,
|
22
29
|
:subject,
|
23
30
|
:trailers
|
24
31
|
) do
|
32
|
+
include Directable
|
33
|
+
include Dry::Monads[:result]
|
34
|
+
|
25
35
|
def initialize(**)
|
26
36
|
super
|
27
37
|
freeze
|
28
38
|
end
|
29
39
|
|
30
|
-
def
|
40
|
+
def find_trailer key
|
41
|
+
trailers.find { |trailer| trailer.key == key }
|
42
|
+
.then do |trailer|
|
43
|
+
return Success trailer if trailer
|
31
44
|
|
32
|
-
|
45
|
+
Failure "Unable to find trailer for key: #{key.inspect}."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_trailers key
|
50
|
+
trailers.select { |trailer| trailer.key == key }
|
51
|
+
.then { |trailers| Success trailers }
|
52
|
+
end
|
33
53
|
|
34
|
-
def
|
54
|
+
def trailer_value_for(key) = find_trailer(key).fmap(&:value)
|
35
55
|
|
36
|
-
def
|
56
|
+
def trailer_values_for(key) = find_trailers(key).fmap { |trailers| trailers.map(&:value) }
|
37
57
|
end
|
38
58
|
end
|
39
59
|
end
|
data/lib/gitt/models/person.rb
CHANGED
@@ -1,17 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "core"
|
4
|
+
|
3
5
|
module Gitt
|
4
6
|
module Models
|
5
7
|
# Represents a person within a repository.
|
6
|
-
Person =
|
8
|
+
Person = Data.define :name, :delimiter, :email do
|
7
9
|
def self.for(string, parser: Parsers::Person.new) = parser.call string
|
8
10
|
|
9
|
-
def initialize
|
11
|
+
def initialize name: nil, delimiter: " ", email: nil
|
10
12
|
super
|
11
|
-
freeze
|
12
13
|
end
|
13
14
|
|
14
|
-
def to_s
|
15
|
+
def to_s
|
16
|
+
case self
|
17
|
+
in String, String, String then "#{name}#{delimiter}<#{email}>"
|
18
|
+
in String, String, nil then name
|
19
|
+
in nil, String, String then "<#{email}>"
|
20
|
+
else Core::EMPTY_STRING
|
21
|
+
end
|
22
|
+
end
|
15
23
|
end
|
16
24
|
end
|
17
25
|
end
|
data/lib/gitt/models/trailer.rb
CHANGED
@@ -3,15 +3,14 @@
|
|
3
3
|
module Gitt
|
4
4
|
module Models
|
5
5
|
# Represents commit trailer details.
|
6
|
-
Trailer =
|
6
|
+
Trailer = Data.define :key, :delimiter, :space, :value do
|
7
7
|
def self.for(string, parser: Parsers::Trailer.new) = parser.call string
|
8
8
|
|
9
|
-
def initialize
|
9
|
+
def initialize key:, value:, delimiter: ":", space: " "
|
10
10
|
super
|
11
|
-
freeze
|
12
11
|
end
|
13
12
|
|
14
|
-
def to_s = values.join
|
13
|
+
def to_s = to_h.values.join
|
15
14
|
end
|
16
15
|
end
|
17
16
|
end
|
@@ -6,23 +6,25 @@ module Gitt
|
|
6
6
|
module Parsers
|
7
7
|
# Extracts attributes from XML formatted content.
|
8
8
|
class Attributer
|
9
|
-
def self.with(...) = new(...)
|
10
|
-
|
11
9
|
def initialize keys = Core::EMPTY_ARRAY
|
12
10
|
@keys = keys
|
13
11
|
end
|
14
12
|
|
15
13
|
def call content
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
attributes.merge key => scrub[%r(<#{key}>(?<value>.*?)</#{key}>)m, :value]
|
20
|
-
end
|
14
|
+
build String(content)
|
15
|
+
rescue ArgumentError => error
|
16
|
+
error.message.include?("invalid byte") ? build(content.scrub("?")) : raise
|
21
17
|
end
|
22
18
|
|
23
19
|
private
|
24
20
|
|
25
21
|
attr_reader :keys
|
22
|
+
|
23
|
+
def build content
|
24
|
+
keys.each.with_object({}) do |key, attributes|
|
25
|
+
attributes[key] = content[%r(<#{key}>(?<value>.*?)</#{key}>)m, :value]
|
26
|
+
end
|
27
|
+
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
data/lib/gitt/parsers/commit.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "refinements/
|
3
|
+
require "refinements/hash"
|
4
4
|
|
5
5
|
module Gitt
|
6
6
|
module Parsers
|
7
7
|
# Parses raw commit information to produce a commit record.
|
8
8
|
class Commit
|
9
|
-
using Refinements::
|
9
|
+
using Refinements::Hash
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
def initialize attributer: Attributer.with(Commands::Log::KEY_MAP.keys),
|
11
|
+
def initialize attributer: Attributer.new(Commands::Log::KEY_MAP.keys.append(:statistics)),
|
14
12
|
sanitizers: Sanitizers::CONTAINER,
|
15
13
|
model: Models::Commit
|
16
14
|
@attributer = attributer
|
@@ -18,11 +16,14 @@ module Gitt
|
|
18
16
|
@model = model
|
19
17
|
end
|
20
18
|
|
19
|
+
# rubocop:todo Layout/LineLength
|
21
20
|
def call content
|
22
21
|
attributer.call(content)
|
23
22
|
.then { |attributes| process attributes }
|
23
|
+
.then { |attributes| attributes.merge! statistic_sanitizer.call(attributes.delete(:statistics)) }
|
24
24
|
.then { |attributes| model[**attributes] }
|
25
25
|
end
|
26
|
+
# rubocop:enable Layout/LineLength
|
26
27
|
|
27
28
|
private
|
28
29
|
|
@@ -64,6 +65,8 @@ module Gitt
|
|
64
65
|
|
65
66
|
def scissors_sanitizer = sanitizers.fetch :scissors
|
66
67
|
|
68
|
+
def statistic_sanitizer = sanitizers.fetch :statistic
|
69
|
+
|
67
70
|
def signature_sanitizer = sanitizers.fetch :signature
|
68
71
|
|
69
72
|
def trailers_sanitizer = sanitizers.fetch :trailers
|
data/lib/gitt/parsers/person.rb
CHANGED
@@ -2,26 +2,28 @@
|
|
2
2
|
|
3
3
|
module Gitt
|
4
4
|
module Parsers
|
5
|
-
# Parses
|
5
|
+
# Parses trailer to produce a person.
|
6
6
|
class Person
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
(?<delimiter>\s?) # Space delimiter (optional).
|
11
|
-
(?<email><.+>)? # Collaborator email (optional).
|
12
|
-
\Z # End of line.
|
13
|
-
/x
|
14
|
-
|
15
|
-
def initialize model: Models::Person, pattern: PATTERN
|
16
|
-
@pattern = pattern
|
7
|
+
def initialize email_start: "<", email_end: ">", model: Models::Person
|
8
|
+
@email_start = email_start
|
9
|
+
@email_end = email_end
|
17
10
|
@model = model
|
18
11
|
end
|
19
12
|
|
20
|
-
def call
|
13
|
+
def call content
|
14
|
+
if content.start_with? email_start
|
15
|
+
model[email: content.delete_prefix(email_start).delete_suffix(email_end)]
|
16
|
+
else
|
17
|
+
name, email = content.split " #{email_start}"
|
18
|
+
email.delete_suffix! email_end if email
|
19
|
+
|
20
|
+
model[name:, email:]
|
21
|
+
end
|
22
|
+
end
|
21
23
|
|
22
24
|
private
|
23
25
|
|
24
|
-
attr_reader :
|
26
|
+
attr_reader :email_start, :email_end, :model
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
data/lib/gitt/parsers/tag.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "refinements/
|
3
|
+
require "refinements/hash"
|
4
4
|
|
5
5
|
module Gitt
|
6
6
|
module Parsers
|
7
7
|
# Parses raw tag information to produce a tag record.
|
8
8
|
class Tag
|
9
|
-
using Refinements::
|
9
|
+
using Refinements::Hash
|
10
10
|
|
11
|
-
def initialize attributer: Attributer.
|
11
|
+
def initialize attributer: Attributer.new(Commands::Tag::KEY_MAP.keys),
|
12
12
|
sanitizers: Sanitizers::CONTAINER,
|
13
13
|
model: Models::Tag
|
14
14
|
@attributer = attributer
|
data/lib/gitt/parsers/trailer.rb
CHANGED
@@ -12,20 +12,21 @@ module Gitt
|
|
12
12
|
\Z # End of line.
|
13
13
|
/x
|
14
14
|
|
15
|
-
def initialize model: Models::Trailer
|
15
|
+
def initialize pattern: PATTERN, model: Models::Trailer
|
16
16
|
@pattern = pattern
|
17
17
|
@model = model
|
18
|
+
@empty = model[key: nil, value: nil].to_h
|
18
19
|
end
|
19
20
|
|
20
21
|
def call content
|
21
22
|
content.match(pattern)
|
22
|
-
.then { |data| data ? data.named_captures :
|
23
|
+
.then { |data| data ? data.named_captures(symbolize_names: true) : empty }
|
23
24
|
.then { |attributes| model[**attributes] }
|
24
25
|
end
|
25
26
|
|
26
27
|
private
|
27
28
|
|
28
|
-
attr_reader :pattern, :model
|
29
|
+
attr_reader :pattern, :model, :empty
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
data/lib/gitt/repository.rb
CHANGED
data/lib/gitt/sanitizers/date.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitt
|
4
|
+
module Sanitizers
|
5
|
+
# Converts raw text into a statistics hash.
|
6
|
+
class Statistic
|
7
|
+
EMPTY = {files_changed: 0, insertions: 0, deletions: 0}.freeze
|
8
|
+
|
9
|
+
PATTERN = /
|
10
|
+
(?<total>\d+) # Total capture group.
|
11
|
+
\s # Space delimiter.
|
12
|
+
(?<kind>file|insertion|deletion) # Kind capture group.
|
13
|
+
/x
|
14
|
+
|
15
|
+
def initialize empty: EMPTY, pattern: PATTERN
|
16
|
+
@empty = empty
|
17
|
+
@pattern = pattern
|
18
|
+
end
|
19
|
+
|
20
|
+
# :reek:TooManyStatements
|
21
|
+
def call text
|
22
|
+
return empty unless text
|
23
|
+
|
24
|
+
text.scan(pattern).each.with_object(empty.dup) do |(number, kind), stats|
|
25
|
+
total = number.to_i
|
26
|
+
|
27
|
+
case kind
|
28
|
+
when "file" then stats[:files_changed] = total
|
29
|
+
when "insertion" then stats[:insertions] = total
|
30
|
+
when "deletion" then stats[:deletions] = total
|
31
|
+
# :nocov:
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_reader :empty, :pattern
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/gitt/shell.rb
CHANGED
@@ -12,8 +12,8 @@ module Gitt
|
|
12
12
|
@client = client
|
13
13
|
end
|
14
14
|
|
15
|
-
def call(
|
16
|
-
client.capture3("git",
|
15
|
+
def call(*, **)
|
16
|
+
client.capture3("git", *, **).then do |stdout, stderr, status|
|
17
17
|
status.success? ? Success(stdout) : Failure(stderr)
|
18
18
|
end
|
19
19
|
end
|
data/lib/gitt.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brooke Kuhlmann
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
3n5C8/6Zh9DYTkpcwPSuIfAga6wf4nXc9m6JAw8AuMLaiWN/r/2s4zJsUHYERJEu
|
36
36
|
gZGm4JqtuSg8pYjPeIJxS960owq+SfuC+jxqmRA54BisFCv/0VOJi7tiJVY=
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date:
|
38
|
+
date: 2024-01-01 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: core
|
@@ -43,14 +43,14 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '0
|
46
|
+
version: '1.0'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '0
|
53
|
+
version: '1.0'
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
55
|
name: dry-monads
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,14 +71,14 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
74
|
+
version: '12.0'
|
75
75
|
type: :runtime
|
76
76
|
prerelease: false
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '12.0'
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: zeitwerk
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- lib/gitt/commands/config.rb
|
111
111
|
- lib/gitt/commands/log.rb
|
112
112
|
- lib/gitt/commands/tag.rb
|
113
|
+
- lib/gitt/directable.rb
|
113
114
|
- lib/gitt/models/commit.rb
|
114
115
|
- lib/gitt/models/person.rb
|
115
116
|
- lib/gitt/models/tag.rb
|
@@ -130,6 +131,7 @@ files:
|
|
130
131
|
- lib/gitt/sanitizers/paragraphs.rb
|
131
132
|
- lib/gitt/sanitizers/scissors.rb
|
132
133
|
- lib/gitt/sanitizers/signature.rb
|
134
|
+
- lib/gitt/sanitizers/statistic.rb
|
133
135
|
- lib/gitt/sanitizers/trailers.rb
|
134
136
|
- lib/gitt/shell.rb
|
135
137
|
homepage: https://alchemists.io/projects/gitt
|
@@ -149,10 +151,7 @@ require_paths:
|
|
149
151
|
- lib
|
150
152
|
required_ruby_version: !ruby/object:Gem::Requirement
|
151
153
|
requirements:
|
152
|
-
- - "
|
153
|
-
- !ruby/object:Gem::Version
|
154
|
-
version: '3.2'
|
155
|
-
- - "<="
|
154
|
+
- - "~>"
|
156
155
|
- !ruby/object:Gem::Version
|
157
156
|
version: '3.3'
|
158
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -161,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
160
|
- !ruby/object:Gem::Version
|
162
161
|
version: '0'
|
163
162
|
requirements: []
|
164
|
-
rubygems_version: 3.
|
163
|
+
rubygems_version: 3.5.3
|
165
164
|
signing_key:
|
166
165
|
specification_version: 4
|
167
166
|
summary: A monadic Object API for the Git CLI.
|
metadata.gz.sig
CHANGED
Binary file
|