twig 1.6 → 1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/HISTORY.md +27 -0
- data/README.md +41 -22
- data/bin/twig +12 -4
- data/bin/twig-checkout-child +56 -25
- data/bin/twig-checkout-parent +54 -26
- data/bin/twig-create-branch +40 -15
- data/bin/twig-diff +44 -25
- data/bin/twig-gh-open +43 -17
- data/bin/twig-gh-open-issue +51 -23
- data/bin/twig-gh-update +46 -20
- data/bin/twig-help +49 -5
- data/bin/twig-init +46 -13
- data/bin/twig-init-completion +46 -19
- data/bin/twig-init-completion-bash +50 -25
- data/bin/twig-init-config +77 -0
- data/bin/twig-rebase +85 -33
- data/config/twigconfig +47 -0
- data/lib/twig.rb +16 -10
- data/lib/twig/branch.rb +19 -12
- data/lib/twig/cli.rb +118 -183
- data/lib/twig/cli/help.rb +174 -0
- data/lib/twig/commit_time.rb +69 -14
- data/lib/twig/display.rb +19 -6
- data/lib/twig/github.rb +10 -8
- data/lib/twig/options.rb +22 -14
- data/lib/twig/subcommands.rb +13 -1
- data/lib/twig/system.rb +0 -2
- data/lib/twig/util.rb +0 -2
- data/lib/twig/version.rb +1 -1
- data/spec/spec_helper.rb +4 -3
- data/spec/twig/branch_spec.rb +100 -13
- data/spec/twig/cli/help_spec.rb +187 -0
- data/spec/twig/cli_spec.rb +34 -189
- data/spec/twig/commit_time_spec.rb +185 -16
- data/spec/twig/display_spec.rb +69 -48
- data/spec/twig/github_spec.rb +29 -15
- data/spec/twig/options_spec.rb +42 -13
- data/spec/twig/subcommands_spec.rb +35 -2
- data/spec/twig/system_spec.rb +5 -6
- data/spec/twig/util_spec.rb +20 -20
- data/spec/twig_spec.rb +21 -6
- data/twig.gemspec +14 -16
- metadata +23 -27
data/bin/twig-init-completion
CHANGED
@@ -1,24 +1,51 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
3
|
+
def help_content
|
4
|
+
<<-HELP
|
5
|
+
|
6
|
+
twig-init-completion
|
7
|
+
====================
|
8
|
+
|
9
|
+
Initializes tab completion for Twig. Use `twig init` to run all setup.
|
10
|
+
|
11
|
+
Synopsis
|
12
|
+
--------
|
13
|
+
|
14
|
+
twig init-completion [--force]
|
15
|
+
|
16
|
+
Description
|
17
|
+
-----------
|
18
|
+
|
19
|
+
Initializes tab completion for Twig. Instead of running this directly,
|
20
|
+
run `twig init` to run all setup tasks.
|
21
|
+
|
22
|
+
Options
|
23
|
+
-------
|
24
|
+
|
25
|
+
`--force`: By default, `twig init-completion` preserves the existing tab
|
26
|
+
completion script, if any. If this option is used, the command will
|
27
|
+
overwrite any existing tab completion script.
|
28
|
+
|
29
|
+
See also
|
30
|
+
--------
|
31
|
+
|
32
|
+
twig-init
|
33
|
+
twig-init-completion-bash
|
34
|
+
twig-init-config
|
35
|
+
|
36
|
+
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
37
|
+
Author: Ron DeVera <http://rondevera.com>
|
38
|
+
|
39
|
+
HELP
|
40
|
+
end
|
41
|
+
|
42
|
+
args = ARGV.dup
|
43
|
+
|
44
|
+
if args.include?('--help')
|
45
|
+
puts help_content
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
|
22
49
|
debug = args.delete('--debug')
|
23
50
|
bash_version = `bash -c 'echo $BASH_VERSION'`.strip
|
24
51
|
|
@@ -1,21 +1,48 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
# Synopsis:
|
4
|
-
#
|
5
|
-
# twig init-completion-bash
|
6
|
-
#
|
7
|
-
# Description:
|
8
|
-
#
|
9
|
-
# Initializes bash tab completion for Twig. Instead of running this directly,
|
10
|
-
# run `twig init` to run all setup tasks for the current shell. Uses all
|
11
|
-
# options available for `twig init-completion`.
|
12
|
-
#
|
13
|
-
# Subcommand for Twig: <http://rondevera.github.io/twig/>
|
14
|
-
# Author: Ron DeVera <http://rondevera.com>
|
15
|
-
|
16
|
-
require 'fileutils'
|
17
3
|
require 'rubygems'
|
18
4
|
require 'twig'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
def help_content
|
8
|
+
<<-HELP
|
9
|
+
|
10
|
+
twig-init-completion-bash
|
11
|
+
=========================
|
12
|
+
|
13
|
+
Initializes bash tab completion for Twig. Use `twig init` to run all setup.
|
14
|
+
|
15
|
+
Synopsis
|
16
|
+
--------
|
17
|
+
|
18
|
+
twig init-completion-bash
|
19
|
+
|
20
|
+
Description
|
21
|
+
-----------
|
22
|
+
|
23
|
+
Initializes bash tab completion for Twig. Instead of running this directly,
|
24
|
+
run `twig init` to run all setup tasks for the current shell. Uses all
|
25
|
+
options available for `twig init-completion`.
|
26
|
+
|
27
|
+
See also
|
28
|
+
--------
|
29
|
+
|
30
|
+
twig-init
|
31
|
+
twig-init-completion
|
32
|
+
twig-init-config
|
33
|
+
|
34
|
+
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
35
|
+
Author: Ron DeVera <http://rondevera.com>
|
36
|
+
|
37
|
+
HELP
|
38
|
+
end
|
39
|
+
|
40
|
+
args = ARGV.dup
|
41
|
+
|
42
|
+
if args.include?('--help')
|
43
|
+
puts help_content
|
44
|
+
exit
|
45
|
+
end
|
19
46
|
|
20
47
|
script = <<-SCRIPT
|
21
48
|
|
@@ -78,9 +105,6 @@ complete -F __twig twig
|
|
78
105
|
SCRIPT
|
79
106
|
script = script.strip + "\n"
|
80
107
|
|
81
|
-
|
82
|
-
|
83
|
-
args = ARGV.dup
|
84
108
|
force = args.delete('--force')
|
85
109
|
|
86
110
|
twig_dir = '~/.twig'
|
@@ -88,28 +112,29 @@ FileUtils.mkdir_p(File.expand_path(twig_dir))
|
|
88
112
|
|
89
113
|
script_path = File.join(twig_dir, '/twig-completion.bash')
|
90
114
|
full_script_path = File.expand_path(script_path)
|
91
|
-
script_exists = File.
|
115
|
+
script_exists = File.exist?(full_script_path)
|
92
116
|
|
93
117
|
if script_exists && !force
|
94
118
|
twig = Twig.new
|
95
119
|
puts twig.format_string("The file `#{script_path}` already exists.", :color => :red)
|
96
|
-
puts
|
120
|
+
puts 'To overwrite it with a default file, run `twig init-completion --force`.'
|
97
121
|
else
|
98
122
|
File.open(full_script_path, 'w') do |file|
|
99
123
|
file.write script
|
100
124
|
end
|
101
125
|
|
102
126
|
if script_exists
|
103
|
-
puts "Overwrote
|
127
|
+
puts "Overwrote `#{script_path}`."
|
104
128
|
else
|
105
|
-
puts "Created
|
129
|
+
puts "Created `#{script_path}`."
|
106
130
|
end
|
107
131
|
end
|
108
132
|
|
109
133
|
puts
|
110
|
-
puts 'To enable tab completion for Twig, add the following to your `~/.bashrc`'
|
111
|
-
puts 'or equivalent:'
|
134
|
+
puts ' => To enable tab completion for Twig, add the following to your `~/.bashrc`'
|
135
|
+
puts ' or equivalent:'
|
136
|
+
puts
|
137
|
+
puts " [[ -s #{script_path} ]] && source #{script_path}"
|
112
138
|
puts
|
113
|
-
puts
|
139
|
+
puts ' => To finish setup, open a new command-line window or run `source ~/.bashrc`.'
|
114
140
|
puts
|
115
|
-
puts 'To finish setup, open a new command-line window or run `source ~/.bashrc`.'
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'twig'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
def help_content
|
8
|
+
<<-HELP
|
9
|
+
|
10
|
+
twig-init-config
|
11
|
+
================
|
12
|
+
|
13
|
+
Creates a default `~/.twigconfig` file. Use `twig init` to run all setup.
|
14
|
+
|
15
|
+
Synopsis
|
16
|
+
--------
|
17
|
+
|
18
|
+
twig init-config [--force]
|
19
|
+
|
20
|
+
Description
|
21
|
+
-----------
|
22
|
+
|
23
|
+
Creates a default `.twigconfig` file in your home directory. Instead of
|
24
|
+
running this directly, run `twig init` to run all setup tasks.
|
25
|
+
|
26
|
+
Options
|
27
|
+
-------
|
28
|
+
|
29
|
+
`--force`: By default, `twig init-config` preserves the existing
|
30
|
+
`.twigconfig` file, if any. If this option is used, the command will
|
31
|
+
overwrite any existing config file.
|
32
|
+
|
33
|
+
See also
|
34
|
+
--------
|
35
|
+
|
36
|
+
twig-init
|
37
|
+
twig-init-completion
|
38
|
+
|
39
|
+
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
40
|
+
Author: Ron DeVera <http://rondevera.com>
|
41
|
+
|
42
|
+
HELP
|
43
|
+
end
|
44
|
+
|
45
|
+
args = ARGV.dup
|
46
|
+
|
47
|
+
if args.include?('--help')
|
48
|
+
puts help_content
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
|
52
|
+
force = args.delete('--force')
|
53
|
+
|
54
|
+
config_path = Twig::Options::CONFIG_PATH
|
55
|
+
full_config_path = File.expand_path(config_path)
|
56
|
+
config_exists = File.exist?(full_config_path)
|
57
|
+
|
58
|
+
if config_exists && !force
|
59
|
+
twig = Twig.new
|
60
|
+
puts twig.format_string("The file `#{config_path}` already exists.", :color => :red)
|
61
|
+
puts 'To overwrite it with a default file, run `twig init-config --force`.'
|
62
|
+
else
|
63
|
+
config_template_path = File.expand_path(
|
64
|
+
File.join(File.dirname(__FILE__), '..', 'config', 'twigconfig')
|
65
|
+
)
|
66
|
+
FileUtils.cp(config_template_path, full_config_path)
|
67
|
+
|
68
|
+
if config_exists
|
69
|
+
puts "Overwrote `#{config_path}`."
|
70
|
+
else
|
71
|
+
puts "Created `#{config_path}`."
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
puts
|
76
|
+
puts " => You can edit `#{config_path}` to customize Twig's appearance and behavior."
|
77
|
+
puts
|
data/bin/twig-rebase
CHANGED
@@ -1,46 +1,98 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
3
|
+
require 'rubygems'
|
4
|
+
require 'twig'
|
5
|
+
|
6
|
+
def help_content
|
7
|
+
<<-HELP
|
8
|
+
|
9
|
+
twig-rebase
|
10
|
+
===========
|
11
|
+
|
12
|
+
Rebases a branch onto its parent branch (`diff-branch`).
|
13
|
+
|
14
|
+
Synopsis
|
15
|
+
--------
|
16
|
+
|
17
|
+
twig rebase [<branch>] [<options>]
|
18
|
+
|
19
|
+
Description
|
20
|
+
-----------
|
21
|
+
|
22
|
+
Rebases the current branch onto the branch in its `diff-branch` property.
|
23
|
+
All options except `--autoconfirm` are passed through to `git-rebase`.
|
24
|
+
|
25
|
+
Options
|
26
|
+
-------
|
27
|
+
|
28
|
+
`--autoconfirm`: Automatically confirm rebasing the branch onto its parent
|
29
|
+
branch without prompting. To automatically confirm whenever running
|
30
|
+
`twig rebase`, set `twig-rebase-autoconfirm` in `~/.twigconfig`.
|
31
|
+
|
32
|
+
Examples
|
33
|
+
--------
|
34
|
+
|
35
|
+
Rebase the current branch onto its `diff-branch` interactively:
|
36
|
+
|
37
|
+
twig rebase -i
|
38
|
+
|
39
|
+
Rebase the given branch onto its `diff-branch`:
|
40
|
+
|
41
|
+
twig rebase my_branch
|
42
|
+
|
43
|
+
Rebase the given branch onto its `diff-branch` interactively:
|
44
|
+
|
45
|
+
twig rebase my_branch -i
|
46
|
+
|
47
|
+
Skip the prompt when rebasing:
|
48
|
+
|
49
|
+
twig rebase --autoconfirm
|
50
|
+
|
51
|
+
Skip the prompt every time you use `twig-rebase`:
|
52
|
+
|
53
|
+
echo 'twig-rebase-autoconfirm: true' >> ~/.twigconfig
|
54
|
+
|
55
|
+
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
56
|
+
Author: Ron DeVera <http://rondevera.com>
|
57
|
+
|
58
|
+
HELP
|
59
|
+
end
|
28
60
|
|
29
61
|
args = ARGV.dup
|
30
62
|
|
63
|
+
if args.include?('--help')
|
64
|
+
puts help_content
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
|
68
|
+
twig = Twig.new
|
69
|
+
twig.read_config_file!
|
70
|
+
# Only read options from the config file, not from arguments, because most
|
71
|
+
# of the latter is passed through to `git-rebase`.
|
72
|
+
|
31
73
|
branch_given = args.any? && args.first[0, 1] != '-'
|
32
74
|
topic_branch = args.shift.strip if branch_given # Use given branch
|
33
75
|
topic_branch ||= `git rev-parse --abbrev-ref HEAD`.strip # Use current branch
|
34
76
|
|
35
|
-
base_branch
|
36
|
-
rebase_options = args.join(' ') # Pass remaining options to `git-rebase`
|
37
|
-
|
77
|
+
base_branch = `twig diff-branch -b "#{topic_branch}"`.strip
|
38
78
|
abort if base_branch.empty?
|
39
79
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
80
|
+
twig_rebase_options = [args.delete('--autoconfirm')] # Twig-specific options
|
81
|
+
git_rebase_options = args.join(' ') # Pass remaining options to `git-rebase`
|
82
|
+
|
83
|
+
autoconfirm =
|
84
|
+
twig.options[:twig_rebase_autoconfirm] || # Option set via config file
|
85
|
+
twig_rebase_options.include?('--autoconfirm') # Option set via CLI
|
86
|
+
|
87
|
+
if autoconfirm
|
88
|
+
puts %{Rebasing "#{topic_branch}" onto "#{base_branch}"...}
|
89
|
+
else
|
90
|
+
print %{Rebase "#{topic_branch}" onto "#{base_branch}"? (y/n) }
|
91
|
+
input = $stdin.gets.strip.downcase
|
92
|
+
end
|
93
|
+
|
94
|
+
if autoconfirm || input == 'y' || input == 'yes'
|
95
|
+
exec %{git rebase #{git_rebase_options} "#{base_branch}" "#{topic_branch}"}
|
44
96
|
else
|
45
|
-
|
97
|
+
abort 'Cancelled.'
|
46
98
|
end
|
data/config/twigconfig
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# This file belongs at `~/.twigconfig`. You can regenerate it with `twig init`.
|
2
|
+
#
|
3
|
+
# For more info, run `twig help` or visit <http://rondevera.github.io/twig/>.
|
4
|
+
|
5
|
+
|
6
|
+
### Filtering branches ###
|
7
|
+
|
8
|
+
# Limit how many branches you list when running `twig`:
|
9
|
+
# (Temporarily override with `twig --all`)
|
10
|
+
max-days-old: 30
|
11
|
+
|
12
|
+
|
13
|
+
### Displaying branches ###
|
14
|
+
|
15
|
+
# Set the width of the `branch` column:
|
16
|
+
# (Use `<property>-width` to set the width of any property column, e.g.,
|
17
|
+
# `todo-width: 30`)
|
18
|
+
branch-width: 30
|
19
|
+
|
20
|
+
# Customize the headers above each column (e.g., "red", "blue bold"):
|
21
|
+
# header-style: blue bold
|
22
|
+
|
23
|
+
# Set to `true` to list the oldest branches first:
|
24
|
+
# reverse: true
|
25
|
+
|
26
|
+
# Hide branches that have a property value matching a regex:
|
27
|
+
# except-branch: production_release_*
|
28
|
+
# except-status: closed|resolved
|
29
|
+
|
30
|
+
# Hide columns where the property name matches a regex:
|
31
|
+
# (e.g., Hide long todos; hide issue tracker metadata)
|
32
|
+
# except-property: todo
|
33
|
+
|
34
|
+
|
35
|
+
### GitHub integration ###
|
36
|
+
|
37
|
+
# If you're working with GitHub Enterprise repositories, change these to match
|
38
|
+
# your installation. This will let you use `twig gh-update`, `twig gh-open`, and
|
39
|
+
# `twig gh-open-issue`:
|
40
|
+
# github-api-uri-prefix: 'https://api.my-github-enterprise.example.com'
|
41
|
+
# github-uri-prefix: 'https://my-github-enterprise.example.com'
|
42
|
+
|
43
|
+
|
44
|
+
### Subcommands ###
|
45
|
+
|
46
|
+
# Set to `true` to skip prompts when using `twig rebase`:
|
47
|
+
# twig-rebase-autoconfirm: true
|
data/lib/twig.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__)) # For gem development
|
2
|
+
require 'shellwords'
|
2
3
|
require 'twig/branch'
|
3
4
|
require 'twig/cli'
|
4
5
|
require 'twig/commit_time'
|
@@ -24,8 +25,9 @@ class Twig
|
|
24
25
|
DEFAULT_GITHUB_URI_PREFIX = 'https://github.com'
|
25
26
|
DEFAULT_HEADER_COLOR = :blue
|
26
27
|
REF_FORMAT_SEPARATOR = '|'
|
27
|
-
REF_FORMAT = %w[refname:short committerdate
|
28
|
-
map { |field| '%(' + field + ')' }.
|
28
|
+
REF_FORMAT = %w[refname:short committerdate:iso].
|
29
|
+
map { |field| '%(' + field + ')' }.
|
30
|
+
join(REF_FORMAT_SEPARATOR)
|
29
31
|
REF_PREFIX = 'refs/heads/'
|
30
32
|
|
31
33
|
def self.run(command)
|
@@ -61,6 +63,10 @@ class Twig
|
|
61
63
|
options[:branch] || current_branch_name
|
62
64
|
end
|
63
65
|
|
66
|
+
def target_branch
|
67
|
+
Twig::Branch.new(target_branch_name)
|
68
|
+
end
|
69
|
+
|
64
70
|
def branches
|
65
71
|
branches = Twig::Branch.all_branches
|
66
72
|
now = Time.now
|
@@ -123,17 +129,18 @@ class Twig
|
|
123
129
|
end
|
124
130
|
end
|
125
131
|
|
126
|
-
|
127
|
-
|
128
132
|
### Actions ###
|
129
133
|
|
130
134
|
def list_branches
|
131
135
|
if branches.empty?
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
136
|
+
msg =
|
137
|
+
if Twig::Branch.all_branches.any?
|
138
|
+
"There are no branches matching your selected options.\n" \
|
139
|
+
"To list all branches, use `twig --all`."
|
140
|
+
else
|
141
|
+
'This repository has no branches.'
|
142
|
+
end
|
143
|
+
return msg
|
137
144
|
end
|
138
145
|
|
139
146
|
out = "\n" << branch_list_headers(options)
|
@@ -159,5 +166,4 @@ class Twig
|
|
159
166
|
branch = Branch.new(branch_name)
|
160
167
|
branch.unset_property(property_name)
|
161
168
|
end
|
162
|
-
|
163
169
|
end
|