gliss 0.1.2 → 0.1.3

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.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/lib/gliss.rb +81 -21
  3. data/spec/gliss_spec.rb +90 -1
  4. metadata +4 -4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
@@ -24,19 +24,25 @@ require 'set'
24
24
  module Gliss
25
25
  Gloss = Struct.new(:sha, :tag, :text)
26
26
  CommitMsg = Struct.new(:sha, :log)
27
- GLOSS_RE=/^((?:[^\s]){3})(-?)(.*?)\1(.*)/
28
- GLOSS_TAG=3
29
- GLOSS_TEXT=4
30
- GLOSS_STRIP=2
31
- INDENT_RE=/^(\s+)(.*)$/
27
+ GLOSS_TAG_RE=/(([^\s])\3\3)(-?)(.*?)\2(.*)/
28
+ GLOSS_INDENTED_RE=/^(\s*)#{GLOSS_TAG_RE}/
29
+ GLOSS_MIDLINE_RE=/^(.*?)#{GLOSS_TAG_RE}/
30
+ GLOSS_RE=/^()#{GLOSS_TAG_RE}/
31
+
32
+ GLOSS_TAG=5
33
+ GLOSS_TEXT=6
34
+ GLOSS_STRIP=4
35
+ GLOSS_BEFORE=1
36
+
37
+ BARE_INDENT_RE=/(\s+)(.*)/
32
38
  INDENT_AMOUNT=1
33
39
  INDENTED_TEXT=2
34
40
 
35
41
  attr_reader :filter
36
42
 
37
- def self.glosses_between(repo, older, newer)
43
+ def self.glosses_between(repo, older, newer, allow_indented=false)
38
44
  commits_between(repo, older, newer).inject([]) do |acc, commit|
39
- acc + glosses_in(commit.log, commit.sha)
45
+ acc + glosses_in(commit.log, commit.sha, allow_indented)
40
46
  end
41
47
  end
42
48
 
@@ -51,40 +57,79 @@ module Gliss
51
57
  end
52
58
  end
53
59
 
54
- def self.glosses_in(message, sha=nil)
60
+ def self.glosses_in(message, sha=nil, allow_indented=false)
55
61
  result = []
56
62
  continuing = false
63
+ ws = ""
57
64
  indent_matcher = nil
58
65
 
59
66
  message.each_line do |line|
60
67
  line.chomp!
61
68
  match = nil
62
69
  if continuing
63
- match = line.match((indent_matcher || INDENT_RE))
70
+ match = line.match((indent_matcher || /^(?:#{ws})#{BARE_INDENT_RE}$/))
64
71
 
65
72
  if match
66
- indent_matcher ||= /^(#{match[INDENT_AMOUNT]})(.*)$/
73
+ indent_matcher ||= /^(?:#{ws})(#{match[INDENT_AMOUNT]})(.*)$/
67
74
  text = match[INDENTED_TEXT].strip
68
75
  result[-1].text << text
76
+ next
69
77
  else
70
78
  indent_matcher = nil
71
79
  continuing = false
72
80
  end
73
81
  end
74
-
75
- match = line.match(GLOSS_RE)
82
+
83
+ match = begins_gloss(line, sha, allow_indented)
76
84
  if match
77
- continuing = true
78
- indent_matcher = nil
79
- tag = match[GLOSS_TAG].strip
80
- text = match[GLOSS_TEXT].strip
81
- result << Gloss.new(sha, tag, [text])
85
+ continuing, indent_matcher, ws, new_gloss = match
86
+ result << new_gloss
82
87
  end
83
88
  end
84
89
 
85
90
  result.each {|g| g.text.reject! {|t| t == ''}; g.text = g.text.join(" ")}
86
91
  end
87
92
 
93
+ def self.begins_gloss(line, sha, allow_indented=false)
94
+ match = line.match(allow_indented ? GLOSS_INDENTED_RE : GLOSS_RE)
95
+ if match
96
+ ws = match[GLOSS_BEFORE]
97
+ tag = match[GLOSS_TAG].strip
98
+ text = match[GLOSS_TEXT].strip
99
+ return [true, nil, ws, Gloss.new(sha, tag, [text])]
100
+ end
101
+ nil
102
+ end
103
+
104
+ def self.split_glosses(gloss, split_glosses=false)
105
+ if split_glosses
106
+ result_glosses = [gloss]
107
+ text = gloss.text
108
+ match = text.match(GLOSS_MIDLINE_RE)
109
+ while match
110
+ result_glosses[-1].text = match[GLOSS_BEFORE].strip if result_glosses[-1]
111
+ tag = match[GLOSS_TAG].strip
112
+ text = match[GLOSS_TEXT].strip
113
+ result_glosses << Gloss.new(gloss.sha, tag, text)
114
+ match = text.match(GLOSS_MIDLINE_RE)
115
+ end
116
+
117
+ if block_given?
118
+ result_glosses.each do |g|
119
+ yield g
120
+ end
121
+ else
122
+ result_glosses
123
+ end
124
+ else
125
+ if block_given?
126
+ yield gloss
127
+ else
128
+ return [gloss]
129
+ end
130
+ end
131
+ end
132
+
88
133
  class App
89
134
  def initialize(args=nil)
90
135
  @args = (args || ARGV.dup)
@@ -104,9 +149,11 @@ module Gliss
104
149
 
105
150
  private
106
151
  def output_glosses(repo)
107
- Gliss::glosses_between(repo, @from, @to).each do |gloss|
108
- if gloss.tag =~ @filter
109
- @output_proc.call(gloss)
152
+ Gliss::glosses_between(repo, @from, @to, @allow_indented_glosses).each do |gloss|
153
+ Gliss::split_glosses(gloss, @split_glosses) do |gl|
154
+ if gl.tag =~ @filter
155
+ @output_proc.call(gl)
156
+ end
110
157
  end
111
158
  end
112
159
  end
@@ -147,11 +194,24 @@ module Gliss
147
194
  @repo = repo
148
195
  end
149
196
 
150
- opts.on("-f REGEX", "--filter REGEX", "Output only messages with tags matching REGEX", "(default is all tags)") do |filter|
197
+ opts.on("-f REGEX", "--filter REGEX", "Output only messages with tags matching", "REGEX (default is all tags)") do |filter|
151
198
  new_filter = Regexp.new(filter)
152
199
  @filter = @filter ? Regexp.union(@filter, new_filter) : new_filter
153
200
  end
154
201
 
202
+ opts.on("--split-glosses", "Attempt to find multiple glosses in a line.", "Note that this option may return","spurious glosses") do
203
+ @split_glosses = true
204
+ end
205
+
206
+ opts.on("--allow-indented-glosses", "Find glosses that don't begin at","the beginning of a line") do
207
+ @allow_indented_glosses = true
208
+ end
209
+
210
+ opts.on("--permissive", "Find as many malformed glosses as possible.","Implies --allow-indented-glosses and", "--split-glosses") do
211
+ @split_glosses = true
212
+ @allow_indented_glosses = true
213
+ end
214
+
155
215
  opts.on("-w", "--whole-commit", "Output entire commit messages that contain glosses") do
156
216
  @seen_messages = Set.new
157
217
  @output_proc = Proc.new do |gloss|
@@ -17,15 +17,104 @@ This line does not contain a gloss.
17
17
 
18
18
  This is a gloss in paragraph format.
19
19
  This is a good format for longer comments.
20
+ ===UGH=== this is a gloss that has a ===MALFORMED=== gloss attached
21
+
22
+ ===YUCK=== this is a gloss that has two ===MALFORMED=== glosses attached ===TO=== it
23
+
24
+ ===BLEAH=== this is a gloss that has two ===MALFORMED=== glosses attached
25
+ ===ONE=== of which is on the second line
26
+
27
+ Foo
28
+
29
+ ===INDENTED=== this should only be a gloss if indenting is allowed
30
+ ===INDENTED2=== this should not be part of the preceding gloss
31
+ but these lines should be appended on
32
+
33
+ abcCRUFTabc this should not be a gloss
34
+ END
35
+
36
+ SECOND_TEST = <<-END
37
+ This is a test commit.
38
+ ===FOO=== this is a bogus gloss
39
+
40
+ ===BAR=== this is not a bogus gloss, but ===MIDLINE=== this is
41
+ ===MIDLINE2=== and so is this
42
+
43
+
20
44
  END
21
45
 
22
46
  before(:each) do
23
47
  @glosses = Gliss.glosses_in(TEST_MESSAGE)
24
48
  end
25
49
 
50
+ it "correctly splits glosses when asked to" do
51
+ ugh = @glosses.select {|g| g.tag == "UGH"}
52
+ ugh.size.should == 1
53
+ splits = Gliss::split_glosses(ugh[0], true)
54
+ splits.size.should == 2
55
+ splits[0].tag.should == "UGH"
56
+ splits[0].text.should == "this is a gloss that has a"
57
+ splits[1].text.should == "gloss attached"
58
+ splits[1].tag.should == "MALFORMED"
59
+ end
60
+
61
+ it "correctly splits malformed glosses with more than one midline gloss when asked to" do
62
+ yuck = @glosses.select {|g| g.tag == "YUCK"}
63
+ yuck.size.should == 1
64
+ splits = Gliss::split_glosses(yuck[0], true)
65
+ splits.size.should == 3
66
+ splits.map{|g| g.tag}.should == %w{YUCK MALFORMED TO}
67
+ splits.map{|g| g.text}.should == ["this is a gloss that has two", "glosses attached", "it"]
68
+ end
69
+
70
+ it "correctly splits malformed glosses with more than one mid-multiline gloss gloss when asked to" do
71
+ bleah = @glosses.select {|g| g.tag == "BLEAH"}
72
+ bleah.size.should == 1
73
+ splits = Gliss::split_glosses(bleah[0], true)
74
+ splits.size.should == 3
75
+ splits.map{|g| g.tag}.should == %w{BLEAH MALFORMED ONE}
76
+ splits.map{|g| g.text}.should == ["this is a gloss that has two", "glosses attached", "of which is on the second line"]
77
+ end
78
+
79
+ it "correctly operates in permissive mode" do
80
+ @glosses = Gliss.glosses_in(SECOND_TEST, nil, true)
81
+ @glosses.size.should == 2
82
+ bar = @glosses.select {|g| g.tag == "BAR"}
83
+ bar.size.should == 1
84
+ splits = Gliss::split_glosses(bar[0], true)
85
+ splits.size.should == 3
86
+ splits.map{|g| g.tag}.should == %w{BAR MIDLINE MIDLINE2}
87
+ splits.map{|g| g.text}.should == ["this is not a bogus gloss, but", "this is", "and so is this"]
88
+ end
89
+
26
90
  it "correctly identifies single-line glosses" do
27
91
  @glosses.select {|g| g.tag == "FOO" && g.text == "is an example gloss of type FOO"}.size.should == 1
28
92
  end
93
+
94
+ it "does not spuriously identify indented glosses" do
95
+ @glosses.select {|g| g.tag == "INDENTED"}.size.should == 0
96
+ @glosses.select {|g| g.tag == "INDENTED2"}.size.should == 0
97
+ end
98
+
99
+ it "correctly identifies indented glosses when told to" do
100
+ @glosses = Gliss.glosses_in(TEST_MESSAGE, nil, true)
101
+ @glosses.select {|g| g.tag == "INDENTED"}.size.should == 1
102
+ end
103
+
104
+ it "correctly identifies consecutive indented glosses" do
105
+ @glosses = Gliss.glosses_in(TEST_MESSAGE, nil, true)
106
+ @glosses.select {|g| g.tag == "INDENTED"}.size.should == 1
107
+ @glosses.select {|g| g.tag == "INDENTED" && g.text == "this should only be a gloss if indenting is allowed"}.size.should == 1
108
+ @glosses.select {|g| g.tag == "INDENTED" && g.text =~ /INDENTED2/}.size.should == 0
109
+ @glosses.select {|g| g.tag == "INDENTED2"}.size.should == 1
110
+ @glosses.select {|g| g.tag == "INDENTED2" && g.text =~ /not be part of the preceding gloss/}.size.should == 1
111
+ end
112
+
113
+ it "correctly identifies indented multiline glosses when told to" do
114
+ @glosses = Gliss.glosses_in(TEST_MESSAGE, nil, true)
115
+ @glosses.select {|g| g.tag == "INDENTED2"}.size.should == 1
116
+ @glosses.select {|g| g.tag == "INDENTED2" && g.text =~ /but these lines should be appended on/}.size.should == 1
117
+ end
29
118
 
30
119
  it "correctly identifies multiple-line glosses" do
31
120
  @glosses.select {|g| g.tag == "BAR" && g.text == "is a gloss that spans several lines because each line has the same indent or at least that much"}.size.should == 1
@@ -46,7 +135,7 @@ END
46
135
  end
47
136
 
48
137
  it "finds multiple glosses in a message" do
49
- @glosses.size.should == 5
138
+ @glosses.size.should == 8
50
139
  end
51
140
 
52
141
  it "does not create spurious glosses" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gliss
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Will Benton
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-28 00:00:00 -05:00
18
+ date: 2011-07-20 00:00:00 -05:00
19
19
  default_executable: gliss
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency