twig 1.0.1 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTING.md +15 -9
- data/HISTORY.md +16 -0
- data/README.md +20 -4
- data/bin/twig +1 -1
- data/bin/twig-gh-open-issue +59 -0
- data/bin/twig-help +3 -0
- data/bin/twig-init-completion +17 -0
- data/bin/twig-init-completion-bash +69 -0
- data/lib/twig.rb +9 -11
- data/lib/twig/branch.rb +30 -8
- data/lib/twig/cli.rb +84 -26
- data/lib/twig/display.rb +18 -3
- data/lib/twig/options.rb +26 -1
- data/lib/twig/version.rb +1 -1
- data/spec/twig/branch_spec.rb +120 -16
- data/spec/twig/cli_spec.rb +90 -2
- data/spec/twig/display_spec.rb +76 -4
- data/spec/twig/options_spec.rb +162 -19
- data/spec/twig_spec.rb +4 -10
- metadata +9 -4
data/CONTRIBUTING.md
CHANGED
@@ -8,18 +8,24 @@ Found a bug or have a suggestion? [Please open an issue][issues] or ping
|
|
8
8
|
|
9
9
|
If you want to hack on some code, even better! Here are the basics:
|
10
10
|
|
11
|
-
1.
|
12
|
-
|
11
|
+
1. If you plan to work on a large feature or bug fix, first
|
12
|
+
[open an issue][issues] first to discuss whether you're on the right track.
|
13
|
+
If you're working on something small, go right ahead.
|
14
|
+
2. Fork the Twig repo.
|
15
|
+
3. Check out the [**`development`** branch][dev branch]; the `master` branch is
|
13
16
|
for stable builds only.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
the latest **Ruby 1.8.7** and **Ruby 1.9.3**, which
|
18
|
-
|
19
|
-
|
17
|
+
4. Run the tests to make sure that they pass on your machine: `bundle && rake`
|
18
|
+
5. Add one or more failing tests for your feature or bug fix.
|
19
|
+
6. Write your feature or bug fix to make the test(s) pass.
|
20
|
+
* Tests should pass in the latest **Ruby 1.8.7** and **Ruby 1.9.3**, which
|
21
|
+
you can do with [rvm][rvm] or [rbenv][rbenv].
|
22
|
+
* Keep the branch focused on a single topic, rather than covering multiple
|
23
|
+
features or bug fixes in a single branch. This makes branches quicker to
|
24
|
+
review and merge.
|
25
|
+
7. Test the change manually:
|
20
26
|
1. `gem build twig.gemspec`
|
21
27
|
2. `gem install twig-x.y.z.gem` (fill in the current version number)
|
22
|
-
|
28
|
+
8. Push to your fork and submit a pull request.
|
23
29
|
|
24
30
|
Thanks for contributing!
|
25
31
|
|
data/HISTORY.md
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
Twig
|
2
2
|
====
|
3
3
|
|
4
|
+
1.1 (2013-03-06)
|
5
|
+
----------------
|
6
|
+
* ENHANCEMENT: Add branch name tab completion for `-b` and `--branch` options.
|
7
|
+
(GH-12)
|
8
|
+
* ENHANCEMENT: Add `--header-style` option for changing the column headers'
|
9
|
+
colors and weights. (GH-11. Thanks [tsujigiri](https://github.com/tsujigiri)!)
|
10
|
+
* ENHANCEMENT: Add `twig gh-open-issue` for opening a branch's GitHub issue, if
|
11
|
+
any, in a browser.
|
12
|
+
* FIX: Make `branch` a reserved property name, along with `merge`, `rebase`, and
|
13
|
+
`remote`.
|
14
|
+
* FIX: Handle line breaks gracefully in `~/.twigrc` config file.
|
15
|
+
* FIX: Exit with a non-zero status when trying to get or unset a branch property
|
16
|
+
that isn't set, or trying to set a branch property to an invalid value.
|
17
|
+
* FIX : Don't allow getting/setting/unsetting a branch property whose name is an
|
18
|
+
empty string.
|
19
|
+
|
4
20
|
1.0.1 (2013-02-13)
|
5
21
|
------------------
|
6
22
|
* ENHANCEMENT: Add Travis CI integration for running tests in multiple versions
|
data/README.md
CHANGED
@@ -43,6 +43,8 @@ chronologically with their properties.
|
|
43
43
|
* `twig <property> -b <branch>`: Get property for any branch
|
44
44
|
* `twig <property> <value> -b <branch>`: Set property for any branch
|
45
45
|
* `twig --unset <property> -b <branch>`: Unset property for any branch
|
46
|
+
* `twig --header-style <format>`: Change the header style, e.g., "red", "green bold"
|
47
|
+
* `twig init-completion`: Set up tab completion for `-b` and `--branch`
|
46
48
|
* `twig --help`: More info
|
47
49
|
|
48
50
|
|
@@ -66,6 +68,7 @@ automatically included when you run `twig`. Example:
|
|
66
68
|
|
67
69
|
# ~/.twigrc:
|
68
70
|
except-branch: staging
|
71
|
+
header-style: green bold
|
69
72
|
max-days-old: 30
|
70
73
|
|
71
74
|
|
@@ -137,8 +140,8 @@ You can set just about any custom property you need to remember for each branch.
|
|
137
140
|
Subcommands
|
138
141
|
===========
|
139
142
|
|
140
|
-
Twig comes with
|
141
|
-
|
143
|
+
Twig comes with a few subcommands that are handy for use with GitHub
|
144
|
+
repositories: `gh-open`, `gh-open-issue`, and `gh-update`.
|
142
145
|
|
143
146
|
While inside a Git repo, run `twig gh-open` to see the repo's GitHub URL, and open
|
144
147
|
a browser window if possible:
|
@@ -149,8 +152,8 @@ a browser window if possible:
|
|
149
152
|
GitHub URL: https://github.com/myname/myproject
|
150
153
|
# Also opens a browser window (OS X only).
|
151
154
|
|
152
|
-
If you're working on an issue for a GitHub repository,
|
153
|
-
|
155
|
+
If you're working on an issue for a GitHub repository, the `gh-update`
|
156
|
+
subcommand syncs issue statuses with GitHub:
|
154
157
|
|
155
158
|
$ git checkout add-feature
|
156
159
|
Switched to branch 'add-feature'.
|
@@ -180,6 +183,18 @@ If you're working on an issue for a GitHub repository, you can also use the
|
|
180
183
|
|
181
184
|
Run `twig gh-update` periodically to keep up with GitHub issues locally.
|
182
185
|
|
186
|
+
For any branch that has an `issue` property, you can use the `gh-open-issue`
|
187
|
+
subcommand to view that issue on GitHub:
|
188
|
+
|
189
|
+
# Current branch:
|
190
|
+
$ twig gh-open-issue
|
191
|
+
GitHub issue URL: https://github.com/myname/myproject/issues/111
|
192
|
+
# Also opens a browser window (OS X only).
|
193
|
+
|
194
|
+
# Any branch:
|
195
|
+
$ twig gh-open-issue -b <branch name>
|
196
|
+
GitHub issue URL: https://github.com/myname/myproject/issues/222
|
197
|
+
|
183
198
|
You can write any Twig subcommand that fits your own Git workflow. To write a
|
184
199
|
Twig subcommand:
|
185
200
|
|
@@ -204,6 +219,7 @@ Some ideas for subcommands:
|
|
204
219
|
they've shipped.
|
205
220
|
* Generate a formatted list of your branches from the past week. Useful for
|
206
221
|
emailing your team about what you're up to.
|
222
|
+
* Create a gem that contains your team's favorite custom Twig subcommands.
|
207
223
|
|
208
224
|
If you write a subcommand that others can appreciate, send a pull request or add
|
209
225
|
it to the [Twig wiki][wiki]!
|
data/bin/twig
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Usage:
|
4
|
+
# - `twig gh-open-issue`:
|
5
|
+
# Opens a browser window for the GitHub issue, if any, for the current branch.
|
6
|
+
# - `twig gh-open-issue -b <branch>`:
|
7
|
+
# Opens the GitHub issue, if any, for the specified branch.
|
8
|
+
#
|
9
|
+
# Author: Ron DeVera <http://rondevera.com>
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'twig'
|
13
|
+
|
14
|
+
class TwigGithubRepo
|
15
|
+
def initialize
|
16
|
+
if origin_url.empty? || username.empty? || repository.empty?
|
17
|
+
abort_for_non_github_repo
|
18
|
+
end
|
19
|
+
|
20
|
+
yield(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def origin_url
|
24
|
+
@origin_url ||= `git config remote.origin.url`.strip
|
25
|
+
end
|
26
|
+
|
27
|
+
def origin_url_parts
|
28
|
+
@origin_url_parts ||= origin_url.split(/[\/:]/)
|
29
|
+
end
|
30
|
+
|
31
|
+
def username
|
32
|
+
@username ||= origin_url_parts[-2] || ''
|
33
|
+
end
|
34
|
+
|
35
|
+
def repository
|
36
|
+
@repo ||= origin_url_parts[-1].sub(/\.git$/, '') || ''
|
37
|
+
end
|
38
|
+
|
39
|
+
def abort_for_non_github_repo
|
40
|
+
abort 'This does not appear to be a GitHub repository.'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
TwigGithubRepo.new do |gh_repo|
|
45
|
+
twig = Twig.new
|
46
|
+
twig.read_cli_options!(ARGV)
|
47
|
+
branch_name = twig.options[:branch] || twig.current_branch_name
|
48
|
+
issue_id = twig.get_branch_property(branch_name, 'issue')
|
49
|
+
|
50
|
+
unless issue_id
|
51
|
+
abort %{The branch "#{branch_name}" doesn't have an "issue" property.}
|
52
|
+
end
|
53
|
+
|
54
|
+
url = "https://github.com/#{gh_repo.username}/#{gh_repo.repository}"
|
55
|
+
url << "/issues/#{issue_id}"
|
56
|
+
|
57
|
+
puts "GitHub issue URL: #{url}"
|
58
|
+
`which open && open #{url}`
|
59
|
+
end
|
data/bin/twig-help
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Initializes tab completion for Twig. To use this, run
|
4
|
+
# `twig init-completion` and follow the instructions.
|
5
|
+
#
|
6
|
+
# Author: Ron DeVera <http://rondevera.com>
|
7
|
+
|
8
|
+
debug = ARGV.include?('--debug')
|
9
|
+
bash_version = `bash -c 'echo $BASH_VERSION'`.strip
|
10
|
+
|
11
|
+
if debug
|
12
|
+
puts "- Ruby version: #{`ruby --version`.strip}"
|
13
|
+
puts "- bash_version: #{bash_version.inspect}"
|
14
|
+
end
|
15
|
+
|
16
|
+
exec('twig-init-completion-bash') if bash_version != ''
|
17
|
+
abort 'Could not initialize Twig tab completion for this shell.'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Initializes bash tab completion for Twig. To use this, run
|
4
|
+
# `twig init-completion` and follow the instructions.
|
5
|
+
#
|
6
|
+
# Author: Ron DeVera <http://rondevera.com>
|
7
|
+
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
version = `twig --version`.strip
|
11
|
+
script = <<-SCRIPT
|
12
|
+
|
13
|
+
#!/usr/bin/env bash
|
14
|
+
|
15
|
+
# AUTO-GENERATED with Twig v#{version}. Regenerate with `twig init-completion`.
|
16
|
+
#
|
17
|
+
# Initializes bash tab completion for Twig. To use this, run
|
18
|
+
# `twig init-completion` and follow the instructions.
|
19
|
+
#
|
20
|
+
# Author: Ron DeVera <http://rondevera.com>
|
21
|
+
|
22
|
+
__twig_branches() {
|
23
|
+
local current words
|
24
|
+
current="${COMP_WORDS[COMP_CWORD]}"
|
25
|
+
words="$(git for-each-ref refs/heads/ --format="%(refname:short)" | tr '\n' ' ')"
|
26
|
+
COMPREPLY=($(compgen -W "$words" -- "$current"))
|
27
|
+
return 0
|
28
|
+
}
|
29
|
+
|
30
|
+
__twig() {
|
31
|
+
if [ -z "$(git rev-parse HEAD 2>/dev/null)" ]; then
|
32
|
+
return 0;
|
33
|
+
fi
|
34
|
+
|
35
|
+
local previous=${COMP_WORDS[COMP_CWORD-1]}
|
36
|
+
|
37
|
+
case "${previous}" in
|
38
|
+
-b|--branch) __twig_branches ;;
|
39
|
+
esac
|
40
|
+
|
41
|
+
return 0
|
42
|
+
}
|
43
|
+
|
44
|
+
complete -F __twig twig
|
45
|
+
|
46
|
+
SCRIPT
|
47
|
+
script = script.strip + "\n"
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
twig_dir = '~/.twig'
|
52
|
+
FileUtils.mkdir_p(File.expand_path(twig_dir))
|
53
|
+
|
54
|
+
script_path = File.join(twig_dir, '/twig-completion.bash')
|
55
|
+
full_script_path = File.expand_path(script_path)
|
56
|
+
unless File.exists?(full_script_path)
|
57
|
+
File.open(full_script_path, 'w') do |file|
|
58
|
+
file.write script
|
59
|
+
end
|
60
|
+
puts "Created #{script_path}."
|
61
|
+
end
|
62
|
+
|
63
|
+
puts
|
64
|
+
puts 'To enable tab completion for Twig, add the following to your `~/.bashrc`'
|
65
|
+
puts 'or equivalent:'
|
66
|
+
puts
|
67
|
+
puts " [[ -s #{script_path} ]] && source #{script_path}"
|
68
|
+
puts
|
69
|
+
puts 'To finish setup, open a new command-line window or run `source ~/.bashrc`.'
|
data/lib/twig.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Dir[File.join(File.dirname(__FILE__), 'twig', '
|
1
|
+
Dir[File.join(File.dirname(__FILE__), 'twig', '*.rb')].each { |file| require file }
|
2
2
|
require 'time'
|
3
3
|
|
4
4
|
class Twig
|
@@ -9,21 +9,20 @@ class Twig
|
|
9
9
|
attr_accessor :options
|
10
10
|
|
11
11
|
REF_FORMAT_SEPARATOR = ','
|
12
|
-
REF_FORMAT = %w[refname committerdate committerdate:relative].
|
12
|
+
REF_FORMAT = %w[refname:short committerdate committerdate:relative].
|
13
13
|
map { |field| '%(' + field + ')' }.join(REF_FORMAT_SEPARATOR)
|
14
14
|
REF_PREFIX = 'refs/heads/'
|
15
|
+
DEFAULT_HEADER_COLOR = :blue
|
15
16
|
|
16
17
|
def self.run(command)
|
17
18
|
`#{command}`.strip
|
18
19
|
end
|
19
20
|
|
20
|
-
def initialize
|
21
|
-
|
22
|
-
# - :branch_except (Regexp)
|
23
|
-
# - :branch_only (Regexp)
|
24
|
-
# - :max_days_old (integer)
|
21
|
+
def initialize
|
22
|
+
self.options = {}
|
25
23
|
|
26
|
-
|
24
|
+
# Set defaults
|
25
|
+
set_option(:header_style, DEFAULT_HEADER_COLOR.to_s)
|
27
26
|
end
|
28
27
|
|
29
28
|
def repo?
|
@@ -44,10 +43,9 @@ class Twig
|
|
44
43
|
|
45
44
|
branch_tuples.inject([]) do |result, branch_tuple|
|
46
45
|
ref, time_string, time_ago = branch_tuple.split(REF_FORMAT_SEPARATOR)
|
47
|
-
name = ref.sub(%r{^#{ REF_PREFIX }}, '')
|
48
46
|
time = Time.parse(time_string)
|
49
47
|
commit_time = Twig::CommitTime.new(time, time_ago)
|
50
|
-
branch = Branch.new(
|
48
|
+
branch = Branch.new(ref, :last_commit_time => commit_time)
|
51
49
|
result << branch
|
52
50
|
end
|
53
51
|
end
|
@@ -88,7 +86,7 @@ class Twig
|
|
88
86
|
end
|
89
87
|
end
|
90
88
|
|
91
|
-
out = "\n" << branch_list_headers
|
89
|
+
out = "\n" << branch_list_headers(options)
|
92
90
|
|
93
91
|
# List most recently modified branches first
|
94
92
|
listable_branches =
|
data/lib/twig/branch.rb
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
class Twig
|
2
2
|
class Branch
|
3
3
|
|
4
|
-
|
4
|
+
EMPTY_PROPERTY_NAME_ERROR = 'Branch property names cannot be empty strings.'
|
5
5
|
PROPERTY_NAME_FROM_GIT_CONFIG = /^branch\.[^.]+\.([^=]+)=.*$/
|
6
|
+
RESERVED_BRANCH_PROPERTIES = %w[branch merge rebase remote]
|
7
|
+
|
8
|
+
class EmptyPropertyNameError < ArgumentError
|
9
|
+
def initialize(message = nil)
|
10
|
+
message ||= EMPTY_PROPERTY_NAME_ERROR
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
class MissingPropertyError < StandardError; end
|
6
15
|
|
7
16
|
attr_accessor :name, :last_commit_time
|
8
17
|
|
@@ -38,35 +47,48 @@ class Twig
|
|
38
47
|
end
|
39
48
|
|
40
49
|
def get_property(property_name)
|
41
|
-
|
50
|
+
property_name = sanitize_property(property_name)
|
51
|
+
raise EmptyPropertyNameError if property_name.empty?
|
52
|
+
|
53
|
+
value = Twig.run("git config branch.#{name}.#{property_name}")
|
54
|
+
value == '' ? nil : value
|
42
55
|
end
|
43
56
|
|
44
57
|
def set_property(property_name, value)
|
45
58
|
property_name = sanitize_property(property_name)
|
46
59
|
value = value.to_s.strip
|
47
60
|
|
48
|
-
if
|
49
|
-
|
61
|
+
if property_name.empty?
|
62
|
+
raise EmptyPropertyNameError
|
63
|
+
elsif RESERVED_BRANCH_PROPERTIES.include?(property_name)
|
64
|
+
raise ArgumentError,
|
65
|
+
%{Can't modify the reserved property "#{property_name}".}
|
50
66
|
elsif value.empty?
|
51
|
-
|
67
|
+
raise ArgumentError,
|
68
|
+
%{Can't set a branch property to an empty string.}
|
52
69
|
else
|
53
70
|
Twig.run(%{git config branch.#{name}.#{property_name} "#{value}"})
|
54
71
|
result_body = %{property "#{property_name}" as "#{value}" for branch "#{name}".}
|
55
72
|
if $?.success?
|
56
73
|
"Saved #{result_body}"
|
57
74
|
else
|
58
|
-
"Could not save #{result_body}"
|
75
|
+
raise RuntimeError, "Could not save #{result_body}"
|
59
76
|
end
|
60
77
|
end
|
61
78
|
end
|
62
79
|
|
63
80
|
def unset_property(property_name)
|
81
|
+
property_name = sanitize_property(property_name)
|
82
|
+
raise EmptyPropertyNameError if property_name.empty?
|
83
|
+
|
64
84
|
value = get_property(property_name)
|
65
|
-
|
85
|
+
|
86
|
+
if value
|
66
87
|
Twig.run(%{git config --unset branch.#{name}.#{property_name}})
|
67
88
|
%{Removed property "#{property_name}" for branch "#{name}".}
|
68
89
|
else
|
69
|
-
|
90
|
+
raise MissingPropertyError,
|
91
|
+
%{The branch "#{name}" does not have the property "#{property_name}".}
|
70
92
|
end
|
71
93
|
end
|
72
94
|
|
data/lib/twig/cli.rb
CHANGED
@@ -6,45 +6,58 @@ class Twig
|
|
6
6
|
def help_intro
|
7
7
|
version_string = "Twig v#{Twig::VERSION}"
|
8
8
|
|
9
|
+
intro = help_paragraph(%{
|
10
|
+
Twig is your personal Git branch assistant. It shows you your most
|
11
|
+
recent branches, and tracks issue tracker ids, tasks, and other metadata
|
12
|
+
for your Git branches.
|
13
|
+
})
|
14
|
+
|
9
15
|
<<-BANNER.gsub(/^[ ]+/, '')
|
10
16
|
|
11
17
|
#{version_string}
|
12
18
|
#{'-' * version_string.size}
|
13
19
|
|
14
|
-
|
15
|
-
recent branches, and tracks issue tracker ids, tasks, and other metadata
|
16
|
-
for your Git branches.
|
20
|
+
#{intro}
|
17
21
|
|
18
22
|
https://rondevera.github.com/twig
|
19
23
|
|
20
24
|
BANNER
|
21
25
|
end
|
22
26
|
|
23
|
-
def help_separator(option_parser, text)
|
24
|
-
|
27
|
+
def help_separator(option_parser, text, options={})
|
28
|
+
options[:trailing] ||= "\n\n"
|
29
|
+
option_parser.separator "\n#{text}#{options[:trailing]}"
|
25
30
|
end
|
26
31
|
|
27
32
|
def help_description(text, options={})
|
28
33
|
width = options[:width] || 40
|
29
|
-
|
30
|
-
|
31
|
-
# Split into lines
|
34
|
+
words = text.gsub(/\n?\s+/, ' ').strip.split(' ')
|
32
35
|
lines = []
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
|
37
|
+
# Split words into lines
|
38
|
+
while words.any?
|
39
|
+
current_word = words.shift
|
40
|
+
current_word_size = formatted_string_display_size(current_word)
|
41
|
+
last_line_size = lines.last && formatted_string_display_size(lines.last)
|
42
|
+
|
43
|
+
if last_line_size && (last_line_size + current_word_size + 1 <= width)
|
44
|
+
lines.last << ' ' << current_word
|
45
|
+
elsif current_word_size >= width
|
46
|
+
lines << current_word[0...width]
|
47
|
+
words.unshift(current_word[width..-1])
|
38
48
|
else
|
39
|
-
lines <<
|
49
|
+
lines << current_word
|
40
50
|
end
|
41
51
|
end
|
42
52
|
|
43
53
|
lines << ' ' if options[:add_separator]
|
44
|
-
|
45
54
|
lines
|
46
55
|
end
|
47
56
|
|
57
|
+
def help_paragraph(text)
|
58
|
+
help_description(text, :width => 80).join("\n")
|
59
|
+
end
|
60
|
+
|
48
61
|
def read_cli_options!(args)
|
49
62
|
option_parser = OptionParser.new do |opts|
|
50
63
|
opts.banner = help_intro
|
@@ -114,13 +127,46 @@ class Twig
|
|
114
127
|
unset_option(:branch_only)
|
115
128
|
end
|
116
129
|
|
130
|
+
|
131
|
+
|
132
|
+
help_separator(opts, 'Listing branches:')
|
133
|
+
|
134
|
+
colors = Twig::Display::COLORS.keys.map do |value|
|
135
|
+
format_string(value, { :color => value })
|
136
|
+
end.join(', ')
|
137
|
+
weights = Twig::Display::WEIGHTS.keys.map do |value|
|
138
|
+
format_string(value, { :weight => value })
|
139
|
+
end.join(' and ')
|
140
|
+
default_color = format_string(
|
141
|
+
Twig::DEFAULT_HEADER_COLOR.to_s,
|
142
|
+
:color => Twig::DEFAULT_HEADER_COLOR
|
143
|
+
)
|
144
|
+
desc = <<-DESC
|
145
|
+
STYLE is a color, weight, or a space-separated pair of one of each.
|
146
|
+
Valid colors are #{colors}. Valid weights are #{weights}.
|
147
|
+
The default is "#{default_color}".
|
148
|
+
DESC
|
149
|
+
opts.on('--header-style "STYLE"', *help_description(desc)) do |style|
|
150
|
+
set_option(:header_style, style)
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
help_separator(opts, help_paragraph(%{
|
156
|
+
You can put your most frequently used options for filtering and
|
157
|
+
listing branches into #{Twig::Options::CONFIG_FILE}. For example:
|
158
|
+
}), :trailing => '')
|
159
|
+
|
117
160
|
help_separator(opts, [
|
118
|
-
'You can put your most frequently used branch filtering options in',
|
119
|
-
"#{Twig::Options::CONFIG_FILE}. For example:",
|
120
|
-
'',
|
121
161
|
' except-branch: staging',
|
162
|
+
' header-style: green bold',
|
122
163
|
' max-days-old: 30'
|
123
|
-
].join("\n"))
|
164
|
+
].join("\n"), :trailing => '')
|
165
|
+
|
166
|
+
help_separator(opts, help_paragraph(%{
|
167
|
+
To enable tab completion for Twig, run `twig init-completion` and
|
168
|
+
follow the instructions.
|
169
|
+
}))
|
124
170
|
end
|
125
171
|
|
126
172
|
option_parser.parse!(args)
|
@@ -154,19 +200,31 @@ class Twig
|
|
154
200
|
# Get/set branch property
|
155
201
|
if property_value
|
156
202
|
# `$ twig <key> <value>`
|
157
|
-
|
203
|
+
begin
|
204
|
+
puts set_branch_property(branch_name, property_name, property_value)
|
205
|
+
rescue ArgumentError, RuntimeError => exception
|
206
|
+
abort exception.message
|
207
|
+
end
|
158
208
|
else
|
159
209
|
# `$ twig <key>`
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
210
|
+
begin
|
211
|
+
value = get_branch_property(branch_name, property_name)
|
212
|
+
if value
|
213
|
+
puts value
|
214
|
+
else
|
215
|
+
abort %{The branch "#{branch_name}" does not have the property "#{property_name}".}
|
216
|
+
end
|
217
|
+
rescue ArgumentError => exception
|
218
|
+
abort exception.message
|
165
219
|
end
|
166
220
|
end
|
167
221
|
elsif property_to_unset
|
168
222
|
# `$ twig --unset <key>`
|
169
|
-
|
223
|
+
begin
|
224
|
+
puts unset_branch_property(branch_name, property_to_unset)
|
225
|
+
rescue ArgumentError, Twig::Branch::MissingPropertyError => exception
|
226
|
+
abort exception.message
|
227
|
+
end
|
170
228
|
else
|
171
229
|
# `$ twig`
|
172
230
|
puts list_branches
|