twig 1.6 → 1.7
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.
- 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
|