gitt 3.8.0 → 3.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: 72a1ef8d6a3caccc88017da2ee4a6f639c9851c8dc6c9ee2ef8510fe83130718
4
- data.tar.gz: 418b7d5e9ac48472cc9112ec031ab7d10e6ca04e0e1503dbe42b65c9a9c50d6f
3
+ metadata.gz: '089dc63b1472c88edd6c3135f33cf1888ff2e8c2a2c7653ed274fb76b0758bec'
4
+ data.tar.gz: 0e0f51674ebb293d760b5a9c7f07716e8a3d277ca25823a24decb7d57239bc86
5
5
  SHA512:
6
- metadata.gz: 4637a417134c91608e031acc5d10cb4594b3db50253a2b5fdd059ee505dd67f43f34e685f0df656f8fd524449053adebb38e19e882ec1349cc667e2cdf323f53
7
- data.tar.gz: a2f821d2cf5757e6c373855c5695452890589e701def37dde9b892958b8f5708c85e4f232bd4ad30f888c9eb4810e0d31307cb193ca7b9c6d08a9866c9c02797
6
+ metadata.gz: 918247b90b31936c807ad6643c3fdd31f6ba873599c83ce609b64c897ddc9e95bb3b323caa715a03737ed164ceca6be4fc7ea80b56dcb1550425da1d27bc2c29
7
+ data.tar.gz: 458707c1d8fdfa687ca9d3939da56192199e8bfe3ec050285003062e0a2febb62ee8247dc3668faed3755fc8d89f2b7b74ce99f86bf392b7eaa9f7d9701ebf9a
checksums.yaml.gz.sig CHANGED
Binary file
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 = "3.8.0"
5
+ spec.version = "3.9.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://alchemists.io/projects/gitt"
@@ -58,8 +58,8 @@ module Gitt
58
58
  attr_reader :shell, :key_map, :parser
59
59
 
60
60
  def pretty_format
61
- key_map.reduce("") { |string, (key, value)| string + "<#{key}>#{value}</#{key}>%n" }
62
- .then { |structure| %(--pretty=format:"#{structure}") }
61
+ key_map.reduce(+"") { |format, (key, value)| format << "<#{key}>#{value}</#{key}>%n" }
62
+ .then { |format| %(--pretty=format:"#{format}") }
63
63
  end
64
64
 
65
65
  def build_records entries
@@ -70,15 +70,16 @@ module Gitt
70
70
 
71
71
  # :reek:UtilityFunction
72
72
  def wrap_statistics entries
73
- entries.gsub!(/\d+\sfile.+\d+\s(insertion|deletion).+\n/) do |match|
74
- "<statistics>#{match}</statistics><break/>"
73
+ entries.gsub!(/\n"\n\s\d+\sfile.+\d+\s(insertion|deletion).+\n/) do |match|
74
+ match.delete_prefix!("\n\"\n").strip!
75
+ "\n<statistics>#{match}</statistics>\n<break/>"
75
76
  end
76
77
  end
77
78
 
78
79
  # :reek:UtilityFunction
79
80
  def add_empty_statistics entries
80
81
  entries.gsub! %(</trailers>\n"\n"<author_email>),
81
- "</trailers>\n<statistics></statistics>\n<author_email>"
82
+ "</trailers>\n<statistics></statistics><break/>\n<author_email>"
82
83
  end
83
84
  end
84
85
  end
@@ -23,6 +23,7 @@ module Gitt
23
23
  sha: "%(objectname)",
24
24
  signature: "%(contents:signature)",
25
25
  subject: "%(subject)",
26
+ trailers: "%(trailers)",
26
27
  version: "%(refname)"
27
28
  }.freeze
28
29
 
@@ -88,7 +89,7 @@ module Gitt
88
89
  attr_reader :shell, :key_map, :parser
89
90
 
90
91
  def pretty_format
91
- key_map.reduce("") { |content, (key, value)| content + "<#{key}>#{value}</#{key}>%n" }
92
+ key_map.reduce(+"") { |format, (key, value)| format << "<#{key}>#{value}</#{key}>%n" }
92
93
  .then { |format| %(--format="#{format}") }
93
94
  end
94
95
 
@@ -32,30 +32,13 @@ module Gitt
32
32
  :trailers
33
33
  ) do
34
34
  include Directable
35
+ include Trailable
35
36
  include Dry::Monads[:result]
36
37
 
37
38
  def initialize(**)
38
39
  super
39
40
  freeze
40
41
  end
41
-
42
- def find_trailer key
43
- trailers.find { |trailer| trailer.key == key }
44
- .then do |trailer|
45
- return Success trailer if trailer
46
-
47
- Failure "Unable to find trailer for key: #{key.inspect}."
48
- end
49
- end
50
-
51
- def find_trailers key
52
- trailers.select { |trailer| trailer.key == key }
53
- .then { |trailers| Success trailers }
54
- end
55
-
56
- def trailer_value_for(key) = find_trailer(key).fmap(&:value)
57
-
58
- def trailer_values_for(key) = find_trailers(key).fmap { |trailers| trailers.map(&:value) }
59
42
  end
60
43
  end
61
44
  end
@@ -16,8 +16,11 @@ module Gitt
16
16
  :sha,
17
17
  :signature,
18
18
  :subject,
19
+ :trailers,
19
20
  :version
20
21
  ) do
22
+ include Trailable
23
+
21
24
  def initialize(**)
22
25
  super
23
26
  freeze
@@ -18,7 +18,7 @@ module Gitt
18
18
 
19
19
  def call content
20
20
  attributer.call(content)
21
- .then { |attributes| process attributes }
21
+ .then { |attributes| mutate attributes }
22
22
  .then { |attributes| model[**attributes] }
23
23
  end
24
24
 
@@ -27,7 +27,7 @@ module Gitt
27
27
  attr_reader :attributer, :sanitizers, :model
28
28
 
29
29
  # :reek:TooManyStatements
30
- def process attributes
30
+ def mutate attributes
31
31
  body, trailers = attributes.values_at :body, :trailers
32
32
  body = scissors_sanitizer.call body
33
33
 
@@ -16,13 +16,16 @@ module Gitt
16
16
  @model = model
17
17
  end
18
18
 
19
+ # :reek:TooManyStatements
19
20
  def call content
20
21
  attributes = attributer.call content
21
- attributes.transform_with! author_email: email_sanitizer,
22
- authored_at: date_sanitizer,
23
- committed_at: date_sanitizer,
24
- committer_email: email_sanitizer,
25
- version: version_serializer
22
+ body, trailers = attributes.values_at :body, :trailers
23
+ sanitize attributes
24
+
25
+ attributes[:body] = (
26
+ trailers ? body.sub(/\n??#{Regexp.escape trailers}\n??/, "") : body
27
+ ).to_s.chomp
28
+
26
29
  model[**attributes]
27
30
  end
28
31
 
@@ -30,10 +33,21 @@ module Gitt
30
33
 
31
34
  attr_reader :attributer, :sanitizers, :model
32
35
 
36
+ def sanitize attributes
37
+ attributes.transform_with! author_email: email_sanitizer,
38
+ authored_at: date_sanitizer,
39
+ committed_at: date_sanitizer,
40
+ committer_email: email_sanitizer,
41
+ trailers: trailers_sanitizer,
42
+ version: version_serializer
43
+ end
44
+
33
45
  def date_sanitizer = sanitizers.fetch :date
34
46
 
35
47
  def email_sanitizer = sanitizers.fetch :email
36
48
 
49
+ def trailers_sanitizer = sanitizers.fetch :trailers
50
+
37
51
  def version_serializer = sanitizers.fetch :version
38
52
  end
39
53
  end
@@ -4,7 +4,6 @@ require "core"
4
4
 
5
5
  module Gitt
6
6
  # Primary object/wrapper for processing all Git related commands.
7
- # :reek:TooManyMethods
8
7
  class Repository
9
8
  COMMANDS = {
10
9
  branch: Commands::Branch,
@@ -34,6 +33,11 @@ module Gitt
34
33
 
35
34
  def get(...) = commands.fetch(:config).get(...)
36
35
 
36
+ def inspect
37
+ "#<#{self.class}:#{object_id} @shell=#{shell.inspect} " \
38
+ "@commands=#{commands.values.map(&:class).inspect}>"
39
+ end
40
+
37
41
  def log(...) = commands.fetch(__method__).call(...)
38
42
 
39
43
  def origin? = commands.fetch(:config).origin?
@@ -6,7 +6,7 @@ module Gitt
6
6
  date: Date,
7
7
  email: Email,
8
8
  lines: Lines,
9
- paragraphs: Paragraphs,
9
+ paragraphs: Paragraphs.new,
10
10
  scissors: Scissors,
11
11
  signature: Signature,
12
12
  statistic: Statistic.new,
@@ -1,9 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "core"
4
+ require "refinements/array"
5
+ require "strscan"
4
6
 
5
7
  module Gitt
6
8
  module Sanitizers
7
- Paragraphs = -> text { text ? text.split("\n\n").map(&:chomp) : Core::EMPTY_ARRAY }
9
+ # Detects and parses paragraphs (including code blocks).
10
+ class Paragraphs
11
+ using Refinements::Array
12
+
13
+ PATTERN = /
14
+ ( # Condition start.
15
+ (?:\..*?\n)? # Optional ASCII Doc label.
16
+ (?:\[.*\]\n)? # Optional ASCII Doc directive.
17
+ [-_=+\.\*]{4} # ASCII Doc block start.
18
+ [\s\S]*? # Lazy block content of any character.
19
+ [-_=+\.\*]{4} # ASCII Doc block end.
20
+ | # Or.
21
+ ``` # Markdown start.
22
+ [\s\S]*? # Lazy block content of any character.
23
+ ``` # Markdown end.
24
+ ) # Condition end.
25
+ /mx
26
+
27
+ def initialize pattern: PATTERN, client: StringScanner
28
+ @pattern = pattern
29
+ @client = client
30
+ end
31
+
32
+ def call(text) = scan(client.new(text.to_s))
33
+
34
+ private
35
+
36
+ attr_reader :pattern, :client
37
+
38
+ # :reek:FeatureEnvy
39
+ def scan scanner, collection = []
40
+ until scanner.eos?
41
+ match = scanner.scan_until pattern
42
+
43
+ break collection << scanner.string[scanner.rest].tap(&:strip!).split("\n\n") unless match
44
+
45
+ collection << scanner.pre_match.strip
46
+ collection << scanner.captures
47
+ end
48
+
49
+ collection.tap(&:flatten!).tap(&:compress!)
50
+ end
51
+ end
8
52
  end
9
53
  end
@@ -12,24 +12,25 @@ module Gitt
12
12
  (?<kind>file|insertion|deletion) # Kind capture group.
13
13
  /x
14
14
 
15
+ def self.update_stats attributes, kind, total
16
+ case kind
17
+ when "file" then attributes[:files_changed] = total
18
+ when "insertion" then attributes[:insertions] = total
19
+ when "deletion" then attributes[:deletions] = total
20
+ else fail StandardError, "Invalid kind: #{kind.inspect}."
21
+ end
22
+ end
23
+
15
24
  def initialize empty: EMPTY, pattern: PATTERN
16
25
  @empty = empty
17
26
  @pattern = pattern
18
27
  end
19
28
 
20
- # :reek:TooManyStatements
21
29
  def call text
22
30
  return empty unless text
23
31
 
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
32
+ text.scan(pattern).each.with_object(empty.dup) do |(number, kind), aggregate|
33
+ self.class.update_stats aggregate, kind, number.to_i
33
34
  end
34
35
  end
35
36
 
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitt
4
+ # Provides shared behavior for objects that have trailers.
5
+ module Trailable
6
+ def find_trailer key
7
+ trailers.find { |trailer| trailer.key == key }
8
+ .then do |trailer|
9
+ return Success trailer if trailer
10
+
11
+ Failure "Unable to find trailer for key: #{key.inspect}."
12
+ end
13
+ end
14
+
15
+ def find_trailers key
16
+ trailers.select { |trailer| trailer.key == key }
17
+ .then { |trailers| Success trailers }
18
+ end
19
+
20
+ def trailer_value_for(key) = find_trailer(key).fmap(&:value)
21
+
22
+ def trailer_values_for(key) = find_trailers(key).fmap { |trailers| trailers.map(&:value) }
23
+ end
24
+ end
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: 3.8.0
4
+ version: 3.9.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: 2024-09-01 00:00:00.000000000 Z
38
+ date: 2024-09-07 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: core
@@ -135,6 +135,7 @@ files:
135
135
  - lib/gitt/sanitizers/trailers.rb
136
136
  - lib/gitt/sanitizers/version.rb
137
137
  - lib/gitt/shell.rb
138
+ - lib/gitt/trailable.rb
138
139
  homepage: https://alchemists.io/projects/gitt
139
140
  licenses:
140
141
  - Hippocratic-2.1
metadata.gz.sig CHANGED
Binary file