twig 1.2.1 → 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.
data/lib/twig/github.rb CHANGED
@@ -1,12 +1,11 @@
1
1
  class Twig
2
2
  class GithubRepo
3
- def self.run(command)
4
- # Duplicated from `Twig.run` for making lightweight subcommands.
5
- `#{command}`.strip
6
- end
7
-
8
3
  def initialize
9
- if origin_url.empty? || username.empty? || repository.empty?
4
+ unless Twig.repo?
5
+ abort 'Current directory is not a git repository.'
6
+ end
7
+
8
+ if origin_url.empty? || !github_repo? || username.empty? || repository.empty?
10
9
  abort_for_non_github_repo
11
10
  end
12
11
 
@@ -14,13 +13,17 @@ class Twig
14
13
  end
15
14
 
16
15
  def origin_url
17
- @origin_url ||= Twig::GithubRepo.run('git config remote.origin.url')
16
+ @origin_url ||= Twig.run('git config remote.origin.url')
18
17
  end
19
18
 
20
19
  def origin_url_parts
21
20
  @origin_url_parts ||= origin_url.split(/[\/:]/)
22
21
  end
23
22
 
23
+ def github_repo?
24
+ origin_url.include?('github.com')
25
+ end
26
+
24
27
  def username
25
28
  @username ||= origin_url_parts[-2] || ''
26
29
  end
data/lib/twig/options.rb CHANGED
@@ -2,29 +2,48 @@ class Twig
2
2
  module Options
3
3
 
4
4
  CONFIG_FILE = '~/.twigrc'
5
+ MIN_PROPERTY_WIDTH = 3
5
6
 
6
7
  def read_config_file!
7
8
  config_file_path = File.expand_path(Twig::CONFIG_FILE)
8
9
  return unless File.readable?(config_file_path)
9
10
 
10
11
  File.open(config_file_path) do |f|
11
- opts = f.read.split("\n").inject({}) do |hsh, opt|
12
- key, value = opt.split(':', 2)
13
- hsh[key.strip] = value.strip if key && value
12
+ opts = f.read.split("\n").inject({}) do |hsh, line|
13
+ line = line.strip
14
+
15
+ if line !~ /^#/
16
+ key, value = line.split(':', 2)
17
+ hsh[key.strip] = value.strip if key && value
18
+ end
19
+
14
20
  hsh
15
21
  end
16
22
 
17
23
  opts.each do |key, value|
18
24
  case key
19
- when 'branch' then set_option(:branch, value)
20
- when 'header-style' then set_option(:header_style, value)
21
- when 'max-days-old' then set_option(:max_days_old, value)
25
+
26
+ # Filtering branches:
27
+ when 'branch'
28
+ set_option(:branch, value)
29
+ when 'max-days-old'
30
+ set_option(:max_days_old, value)
22
31
  when /^except-/
23
32
  property_name = key.sub(/^except-/, '').to_sym
24
33
  set_option(:property_except, property_name => value)
25
34
  when /^only-/
26
35
  property_name = key.sub(/^only-/, '').to_sym
27
36
  set_option(:property_only, property_name => value)
37
+
38
+ # Displaying branches:
39
+ when 'header-style'
40
+ set_option(:header_style, value)
41
+ when 'reverse'
42
+ set_option(:reverse, value)
43
+ when /-width$/
44
+ property_name = key.sub(/-width$/, '').to_sym
45
+ set_option(:property_width, property_name => value)
46
+
28
47
  end
29
48
  end
30
49
  end
@@ -33,7 +52,7 @@ class Twig
33
52
  def set_option(key, value)
34
53
  case key
35
54
  when :branch
36
- if branch_names.include?(value)
55
+ if all_branch_names.include?(value)
37
56
  options[:branch] = value
38
57
  else
39
58
  abort %{The branch "#{value}" could not be found.}
@@ -63,6 +82,12 @@ class Twig
63
82
  options[:property_only] ||= {}
64
83
  options[:property_only].merge!(property_hash)
65
84
 
85
+ when :property_width
86
+ set_property_width_option(value)
87
+
88
+ when :reverse
89
+ options[:reverse] = Twig::Util.truthy?(value)
90
+
66
91
  when :unset_property
67
92
  options[:unset_property] = value
68
93
  end
@@ -89,6 +114,33 @@ class Twig
89
114
  options[:header_weight] = weight if weight
90
115
  end
91
116
 
117
+ def set_property_width_option(value)
118
+ value.each do |property_name, property_value|
119
+ unless Twig::Util.numeric?(property_value)
120
+ abort %{The value `--#{property_name}-width=#{property_value}` is invalid.}
121
+ end
122
+
123
+ property_name_width = property_name.to_s.size
124
+ property_value = property_value.to_i
125
+
126
+ if property_value < [property_name_width, MIN_PROPERTY_WIDTH].max
127
+ error = %{The value `--#{property_name}-width=#{property_value}` } +
128
+ %{is too low. The minimum is }
129
+
130
+ if property_value < property_name_width
131
+ error << %{#{property_name_width} (width of "#{property_name}").}
132
+ elsif property_value < MIN_PROPERTY_WIDTH
133
+ error << %{#{MIN_PROPERTY_WIDTH}.}
134
+ end
135
+
136
+ abort error
137
+ end
138
+
139
+ options[:property_width] ||= {}
140
+ options[:property_width].merge!(property_name => property_value)
141
+ end
142
+ end
143
+
92
144
  def unset_option(key)
93
145
  options.delete(key)
94
146
  end
data/lib/twig/util.rb CHANGED
@@ -5,5 +5,9 @@ class Twig
5
5
  !!Float(value) rescue false
6
6
  end
7
7
 
8
+ def self.truthy?(value)
9
+ %w[true yes y on 1].include?(value.to_s.downcase)
10
+ end
11
+
8
12
  end
9
13
  end
data/lib/twig/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Twig
2
- VERSION = '1.2.1'
2
+ VERSION = '1.3'
3
3
  end
@@ -39,6 +39,25 @@ describe Twig::Cli do
39
39
  end
40
40
  end
41
41
 
42
+ describe '#help_description_for_custom_property' do
43
+ before :each do
44
+ @twig = Twig.new
45
+ end
46
+
47
+ it 'returns a help string for a custom property' do
48
+ option_parser = OptionParser.new
49
+ @twig.should_receive(:help_separator) do |opt_parser, desc, options|
50
+ opt_parser.should == option_parser
51
+ desc.should == " --test-option Test option description\n"
52
+ options.should == { :trailing => "\n" }
53
+ end
54
+
55
+ @twig.help_description_for_custom_property(option_parser, [
56
+ ['--test-option', 'Test option description']
57
+ ])
58
+ end
59
+ end
60
+
42
61
  describe '#help_paragraph' do
43
62
  before :each do
44
63
  @twig = Twig.new
@@ -59,13 +78,79 @@ describe Twig::Cli do
59
78
  end
60
79
  end
61
80
 
81
+ describe '#help_line_for_custom_property?' do
82
+ before :each do
83
+ @twig = Twig.new
84
+ end
85
+
86
+ it 'returns true for `--except-foo`' do
87
+ @twig.help_line_for_custom_property?(' --except-foo ').should be_true
88
+ end
89
+
90
+ it 'returns false for `--except-branch`' do
91
+ @twig.help_line_for_custom_property?(' --except-branch ').should be_false
92
+ end
93
+
94
+ it 'returns false for `--except-PROPERTY`' do
95
+ @twig.help_line_for_custom_property?(' --except-PROPERTY ').should be_false
96
+ end
97
+
98
+ it 'returns true for `--only-foo`' do
99
+ @twig.help_line_for_custom_property?(' --only-foo ').should be_true
100
+ end
101
+
102
+ it 'returns false for `--only-branch`' do
103
+ @twig.help_line_for_custom_property?(' --only-branch ').should be_false
104
+ end
105
+
106
+ it 'returns false for `--only-PROPERTY`' do
107
+ @twig.help_line_for_custom_property?(' --only-PROPERTY ').should be_false
108
+ end
109
+
110
+ it 'returns true for `--foo-width`' do
111
+ @twig.help_line_for_custom_property?(' --foo-width ').should be_true
112
+ end
113
+
114
+ it 'returns false for `--branch-width`' do
115
+ @twig.help_line_for_custom_property?(' --branch-width ').should be_false
116
+ end
117
+
118
+ it 'returns false for `--PROPERTY-width`' do
119
+ @twig.help_line_for_custom_property?(' --PROPERTY-width ').should be_false
120
+ end
121
+ end
122
+
62
123
  describe '#read_cli_options!' do
63
124
  before :each do
64
125
  @twig = Twig.new
65
126
  end
66
127
 
128
+ it 'recognizes `--unset` and sets an `:unset_property` option' do
129
+ @twig.options[:unset_property].should be_nil # Precondition
130
+ @twig.read_cli_options!(%w[--unset test])
131
+ @twig.options[:unset_property].should == 'test'
132
+ end
133
+
134
+ it 'recognizes `--help` and prints the help content' do
135
+ help_lines = []
136
+ @twig.stub(:puts) { |message| help_lines << message.strip }
137
+ @twig.should_receive(:exit)
138
+
139
+ @twig.read_cli_options!(['--help'])
140
+
141
+ help_lines.should include("Twig v#{Twig::VERSION}")
142
+ help_lines.should include('http://rondevera.github.io/twig/')
143
+ end
144
+
145
+ it 'recognizes `--version` and prints the current version' do
146
+ @twig.should_receive(:puts).with(Twig::VERSION)
147
+ @twig.should_receive(:exit)
148
+
149
+ @twig.read_cli_options!(['--version'])
150
+ end
151
+
67
152
  it 'recognizes `-b` and sets a `:branch` option' do
68
- @twig.should_receive(:branch_names).and_return(['test'])
153
+ @twig.should_receive(:all_branch_names).and_return(['test'])
69
154
  @twig.options[:branch].should be_nil # Precondition
70
155
 
71
156
  @twig.read_cli_options!(%w[-b test])
@@ -74,7 +159,7 @@ describe Twig::Cli do
74
159
  end
75
160
 
76
161
  it 'recognizes `--branch` and sets a `:branch` option' do
77
- @twig.should_receive(:branch_names).and_return(['test'])
162
+ @twig.should_receive(:all_branch_names).and_return(['test'])
78
163
  @twig.options[:branch].should be_nil # Precondition
79
164
 
80
165
  @twig.read_cli_options!(%w[--branch test])
@@ -190,17 +275,19 @@ describe Twig::Cli do
190
275
  @twig.options[:property_only].should be_nil
191
276
  end
192
277
 
193
- it 'recognizes `--unset` and sets an `:unset_property` option' do
194
- @twig.options[:unset_property].should be_nil # Precondition
195
- @twig.read_cli_options!(%w[--unset test])
196
- @twig.options[:unset_property].should == 'test'
278
+ it 'recognizes `--branch-width`' do
279
+ @twig.options[:property_width].should be_nil
280
+ @twig.should_receive(:set_option).with(:property_width, :branch => '10')
281
+
282
+ @twig.read_cli_options!(%w[--branch-width 10])
197
283
  end
198
284
 
199
- it 'recognizes `--version` and prints the current version' do
200
- @twig.should_receive(:puts).with(Twig::VERSION)
201
- @twig.should_receive(:exit)
285
+ it 'recognizes `--<property>-width`' do
286
+ Twig::Branch.stub(:all_properties) { %w[foo] }
287
+ @twig.options[:property_width].should be_nil
288
+ @twig.should_receive(:set_option).with(:property_width, :foo => '10')
202
289
 
203
- @twig.read_cli_options!(['--version'])
290
+ @twig.read_cli_options!(%w[--foo-width 10])
204
291
  end
205
292
 
206
293
  it 'recognizes `--header-style`' do
@@ -211,6 +298,12 @@ describe Twig::Cli do
211
298
  @twig.options[:header_weight].should == :bold
212
299
  end
213
300
 
301
+ it 'recognizes `--reverse`' do
302
+ @twig.options[:reverse].should be_nil
303
+ @twig.read_cli_options!(['--reverse'])
304
+ @twig.options[:reverse].should be_true
305
+ end
306
+
214
307
  it 'handles invalid options' do
215
308
  @twig.should_receive(:abort_for_option_exception) do |exception|
216
309
  exception.should be_a(OptionParser::InvalidOption)
@@ -311,7 +404,7 @@ describe Twig::Cli do
311
404
  end
312
405
 
313
406
  it 'gets a property for a specified branch' do
314
- @twig.should_receive(:branch_names).and_return([@branch_name])
407
+ @twig.should_receive(:all_branch_names).and_return([@branch_name])
315
408
  @twig.set_option(:branch, @branch_name)
316
409
  @twig.should_receive(:get_branch_property_for_cli).
317
410
  with(@branch_name, @property_name)
@@ -337,7 +430,7 @@ describe Twig::Cli do
337
430
  end
338
431
 
339
432
  it 'sets a property for a specified branch' do
340
- @twig.should_receive(:branch_names).and_return([@branch_name])
433
+ @twig.should_receive(:all_branch_names).and_return([@branch_name])
341
434
  @twig.set_option(:branch, @branch_name)
342
435
  @twig.should_receive(:set_branch_property_for_cli).
343
436
  with(@branch_name, @property_name, @property_value).
@@ -364,7 +457,7 @@ describe Twig::Cli do
364
457
  end
365
458
 
366
459
  it 'unsets a property for a specified branch' do
367
- @twig.should_receive(:branch_names).and_return([@branch_name])
460
+ @twig.should_receive(:all_branch_names).and_return([@branch_name])
368
461
  @twig.set_option(:branch, @branch_name)
369
462
  @twig.should_receive(:unset_branch_property_for_cli).
370
463
  with(@branch_name, @property_name)
@@ -7,23 +7,15 @@ describe Twig::Display do
7
7
 
8
8
  describe '#column' do
9
9
  it 'returns a string with an exact fixed width' do
10
- @twig.column('foo', 1, :width => 8).should == 'foo' + (' ' * 5)
10
+ @twig.column('foo', :width => 8).should == 'foo' + (' ' * 5)
11
11
  end
12
12
 
13
13
  it 'returns a string that fits a column exactly' do
14
- @twig.column('asdfasdf', 1, :width => 8).should == 'asdf... '
14
+ @twig.column('asdfasdf', :width => 8).should == 'asdfasdf'
15
15
  end
16
16
 
17
17
  it 'truncates a wide string with an ellipsis' do
18
- @twig.column('asdfasdfasdf', 1, :width => 8).should == 'asdf... '
19
- end
20
-
21
- it 'returns a string that spans multiple columns' do
22
- @twig.column('foo', 2, :width => 8).should == 'foo' + (' ' * 13)
23
- end
24
-
25
- it 'returns a string that spans multiple columns and is truncated' do
26
- @twig.column('asdf' * 5, 2, :width => 8).should == 'asdfasdfasdf... '
18
+ @twig.column('asdfasdfasdf', :width => 8).should == 'asdfa...'
27
19
  end
28
20
 
29
21
  it 'passes options through to `format_string`' do
@@ -31,7 +23,52 @@ describe Twig::Display do
31
23
  @twig.should_receive(:format_string).
32
24
  with('foo' + (' ' * 5), format_options)
33
25
 
34
- @twig.column('foo', 1, format_options)
26
+ @twig.column('foo', format_options)
27
+ end
28
+ end
29
+
30
+ describe '#property_column_width' do
31
+ it 'returns a default width if no property name is given' do
32
+ @twig.property_column_width.should ==
33
+ Twig::Display::DEFAULT_PROPERTY_COLUMN_WIDTH
34
+ end
35
+
36
+ context 'with no custom column widths set' do
37
+ before :each do
38
+ @twig.options[:property_width].should be_nil
39
+ end
40
+
41
+ it 'returns a default width if a property name is given' do
42
+ @twig.property_column_width(:foo).should ==
43
+ Twig::Display::DEFAULT_PROPERTY_COLUMN_WIDTH
44
+ end
45
+
46
+ it 'returns a default width if :branch is given' do
47
+ @twig.property_column_width(:branch).should ==
48
+ Twig::Display::DEFAULT_BRANCH_COLUMN_WIDTH
49
+ end
50
+ end
51
+
52
+ context 'with custom column widths set' do
53
+ it 'returns a default width if a property name is given but it has no custom width' do
54
+ @twig.property_column_width(:baz).should ==
55
+ Twig::Display::DEFAULT_PROPERTY_COLUMN_WIDTH
56
+ end
57
+
58
+ it 'returns a custom width if a property name is given and it has a custom width' do
59
+ @twig.set_option(:property_width, :foo => 20)
60
+ @twig.property_column_width(:foo).should == 20
61
+ end
62
+
63
+ it 'returns a default width if :branch is given but it has no custom width' do
64
+ @twig.property_column_width(:branch).should ==
65
+ Twig::Display::DEFAULT_BRANCH_COLUMN_WIDTH
66
+ end
67
+
68
+ it 'returns a custom width if :branch is given but it has no custom width' do
69
+ @twig.set_option(:property_width, :branch => 20)
70
+ @twig.property_column_width(:branch).should == 20
71
+ end
35
72
  end
36
73
  end
37
74
 
@@ -44,17 +81,36 @@ describe Twig::Display do
44
81
  result = @twig.branch_list_headers({})
45
82
  result_lines = result.split("\n")
46
83
 
47
- column_width = 8
48
- columns_for_date_time = 5
49
- first_column_width = column_width * columns_for_date_time
50
- result_lines[0].should == (' ' * first_column_width) +
51
- 'foo ' + (' ' * column_width) +
52
- 'quux ' + (' ' * column_width) +
53
- ' branch' + (' ' * column_width)
54
- result_lines[1].should == (' ' * first_column_width) +
55
- '--- ' + (' ' * column_width) +
56
- '---- ' + (' ' * column_width) +
57
- ' ------' + (' ' * column_width)
84
+ date_time_column_width = 35
85
+ extra_property_column_width = 8
86
+ column_gutter = @twig.column_gutter
87
+ result_lines[0].should == (' ' * date_time_column_width) + column_gutter +
88
+ 'foo ' + (' ' * extra_property_column_width) + column_gutter +
89
+ 'quux ' + (' ' * extra_property_column_width) + column_gutter +
90
+ ' branch'
91
+ result_lines[1].should == (' ' * date_time_column_width) + column_gutter +
92
+ '--- ' + (' ' * extra_property_column_width) + column_gutter +
93
+ '---- ' + (' ' * extra_property_column_width) + column_gutter +
94
+ ' ------'
95
+ end
96
+
97
+ it 'sets a header width' do
98
+ @twig.set_option(:property_width, :foo => 4)
99
+
100
+ result = @twig.branch_list_headers({})
101
+ result_lines = result.split("\n")
102
+
103
+ date_time_column_width = 35
104
+ extra_property_column_width = 8
105
+ column_gutter = @twig.column_gutter
106
+ result_lines[0].should == (' ' * date_time_column_width) + column_gutter +
107
+ 'foo ' + column_gutter +
108
+ 'quux ' + (' ' * extra_property_column_width) + column_gutter +
109
+ ' branch'
110
+ result_lines[1].should == (' ' * date_time_column_width) + column_gutter +
111
+ '--- ' + column_gutter +
112
+ '---- ' + (' ' * extra_property_column_width) + column_gutter +
113
+ ' ------'
58
114
  end
59
115
 
60
116
  it 'sets a header color' do
@@ -146,6 +202,58 @@ describe Twig::Display do
146
202
 
147
203
  result.should include('line breaks')
148
204
  end
205
+
206
+ it 'returns a line with custom column widths' do
207
+ branch = Twig::Branch.new('other-branch')
208
+ branch.should_receive(:last_commit_time).and_return(@commit_time)
209
+ @twig.set_option(:property_width, :foo => 5)
210
+
211
+ result = @twig.branch_list_line(branch)
212
+
213
+ column_gutter = @twig.column_gutter
214
+ result.should ==
215
+ '2000-01-01' + (' ' * 25) + column_gutter +
216
+ 'foo! ' + column_gutter +
217
+ 'bar!' + (' ' * 12) + column_gutter +
218
+ ' ' + branch.name
219
+ end
220
+
221
+ context 'with a custom width for the branch column' do
222
+ before :each do
223
+ @twig.set_option(:property_width, :branch => 8)
224
+ end
225
+
226
+ it 'returns a line for the current branch' do
227
+ indicator = Twig::Display::CURRENT_BRANCH_INDICATOR
228
+ branch = Twig::Branch.new('my-branch')
229
+ branch_regexp = /#{Regexp.escape(indicator)}#{Regexp.escape(branch.name)}/
230
+ branch.should_receive(:last_commit_time).and_return(@commit_time)
231
+
232
+ result = @twig.branch_list_line(branch)
233
+ unformatted_result = @twig.unformat_string(result)
234
+
235
+ column_gutter = @twig.column_gutter
236
+ unformatted_result.should ==
237
+ '2000-01-01' + (' ' * 25) + column_gutter +
238
+ 'foo!' + (' ' * 12) + column_gutter +
239
+ 'bar!' + (' ' * 12) + column_gutter +
240
+ indicator + 'my-br...'
241
+ end
242
+
243
+ it 'returns a line for a branch other than the current branch' do
244
+ branch = Twig::Branch.new('other-branch')
245
+ branch.should_receive(:last_commit_time).and_return(@commit_time)
246
+
247
+ result = @twig.branch_list_line(branch)
248
+
249
+ column_gutter = @twig.column_gutter
250
+ result.should ==
251
+ '2000-01-01' + (' ' * 25) + column_gutter +
252
+ 'foo!' + (' ' * 12) + column_gutter +
253
+ 'bar!' + (' ' * 12) + column_gutter +
254
+ ' ' + 'other...'
255
+ end
256
+ end
149
257
  end
150
258
 
151
259
  describe '#format_string' do