git-contest 0.2.4 → 0.2.5
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 +8 -8
- data/.travis.yml +21 -3
- data/README.md +5 -0
- data/Rakefile +8 -0
- data/appveyor.yml +21 -0
- data/bin/git-contest +4 -33
- data/bin/git-contest-config +4 -241
- data/bin/git-contest-finish +4 -151
- data/bin/git-contest-init +4 -65
- data/bin/git-contest-list +4 -64
- data/bin/git-contest-rebase +4 -64
- data/bin/git-contest-start +4 -57
- data/bin/git-contest-submit +4 -183
- data/git-contest.gemspec +2 -1
- data/lib/contest/driver/base.rb +7 -4
- data/lib/git/contest/command_line.rb +10 -0
- data/lib/git/contest/command_line/command.rb +117 -0
- data/lib/git/contest/command_line/main_command.rb +56 -0
- data/lib/git/contest/command_line/sub_commands.rb +35 -0
- data/lib/git/contest/command_line/sub_commands/config_command.rb +258 -0
- data/lib/git/contest/command_line/sub_commands/finish_command.rb +161 -0
- data/lib/git/contest/command_line/sub_commands/init_command.rb +79 -0
- data/lib/git/contest/command_line/sub_commands/list_command.rb +89 -0
- data/lib/git/contest/command_line/sub_commands/rebase_command.rb +87 -0
- data/lib/git/contest/command_line/sub_commands/start_command.rb +77 -0
- data/lib/git/contest/command_line/sub_commands/submit_command.rb +220 -0
- data/lib/git/contest/common.rb +6 -6
- data/lib/git/contest/git.rb +160 -156
- data/lib/git/contest/version.rb +1 -1
- data/spec/command/t004_git_contest_submit_spec.rb +254 -0
- data/spec/command/t005_git_contest_branching_spec.rb +90 -0
- data/spec/command/t007_git_contest_start_spec.rb +95 -0
- data/spec/command/t008_git_contest_finish_spec.rb +171 -0
- data/spec/command/t009_git_contest_init_spec.rb +85 -0
- data/spec/command/t012_git_contest_list_spec.rb +123 -0
- data/spec/command/t013_git_contest_config_spec.rb +186 -0
- data/spec/{lib/contest/driver → contest_driver}/t001_aizu_online_judge_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t002_codeforces_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t003_uva_online_judge_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t010_kattis_spec.rb +1 -1
- data/spec/{lib/contest/driver → contest_driver}/t011_utils_spec.rb +0 -0
- data/spec/spec_helper.rb +18 -12
- data/spec/t006_config_spec.rb +37 -31
- metadata +57 -33
- data/spec/bin/t004_git_contest_submit_spec.rb +0 -223
- data/spec/bin/t005_git_contest_branching_spec.rb +0 -70
- data/spec/bin/t007_git_contest_start_spec.rb +0 -88
- data/spec/bin/t008_git_contest_finish_spec.rb +0 -162
- data/spec/bin/t009_git_contest_init_spec.rb +0 -55
- data/spec/bin/t012_git_contest_list_spec.rb +0 -99
- data/spec/bin/t013_git_contest_config_spec.rb +0 -149
- data/spec/spec_list.txt +0 -1
@@ -0,0 +1,161 @@
|
|
1
|
+
#
|
2
|
+
# git-contest-finish
|
3
|
+
# https://github.com/sh19910711/git-contest
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2014 Hiroyuki Sano <sh19910711 at gmail.com>
|
6
|
+
# Licensed under the MIT-License.
|
7
|
+
#
|
8
|
+
|
9
|
+
module CommandLine
|
10
|
+
|
11
|
+
module SubCommands
|
12
|
+
|
13
|
+
class FinishCommand < Command
|
14
|
+
|
15
|
+
def initialize(new_args, new_input_stream = STDIN)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def define_options
|
20
|
+
opt_parser.on "--[no-]edit", "Use default commit message." do |v|
|
21
|
+
options[:edit] = v
|
22
|
+
end
|
23
|
+
|
24
|
+
opt_parser.on "-k", "--keep", "Keep contest branch after merge." do
|
25
|
+
options[:keep] = true
|
26
|
+
end
|
27
|
+
|
28
|
+
opt_parser.on "--rebase", "Use rebase instead of merge." do
|
29
|
+
options[:rebase] = true
|
30
|
+
end
|
31
|
+
|
32
|
+
opt_parser.on "--force-delete", "Force delete contest branch after finish." do
|
33
|
+
options[:force_delete] = true
|
34
|
+
end
|
35
|
+
|
36
|
+
opt_parser.on "-s", "--squash", "Use squash during merge." do
|
37
|
+
options[:squash] = true
|
38
|
+
end
|
39
|
+
|
40
|
+
opt_parser.on "--fetch", "Fetch from origin before finish." do
|
41
|
+
options[:fetch]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_default_options
|
46
|
+
options[:edit] = true if options[:edit].nil?
|
47
|
+
options[:keep] = false if options[:keep].nil?
|
48
|
+
options[:rebase] = false if options[:rebase].nil?
|
49
|
+
options[:force_delete] = false if options[:force_delete].nil?
|
50
|
+
options[:squash] = false if options[:squash].nil?
|
51
|
+
options[:fetch] = false if options[:fetch].nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def run
|
55
|
+
expand_contest_branch
|
56
|
+
Git.require_branch $BRANCH
|
57
|
+
|
58
|
+
Git.require_clean_working_tree
|
59
|
+
|
60
|
+
if Git.remote_branches().include?("#{$ORIGIN}/#{$BRANCH}")
|
61
|
+
if options[:fetch]
|
62
|
+
Git.do "fetch -q \"#{$ORIGIN}\" \"#{$BRANCH}\""
|
63
|
+
Git.do "fetch -q \"#{$ORIGIN}\" \"#{$MASTER}\""
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if Git.remote_branches().include?("#{$ORIGIN}/#{$BRANCH}")
|
68
|
+
Git.require_branches_equal $BRANCH, "#{$ORIGIN}/#{$BRANCH}"
|
69
|
+
end
|
70
|
+
|
71
|
+
if Git.remote_branches().include?("#{$ORIGIN}/#{$MASTER}")
|
72
|
+
Git.require_branches_equal $MASTER, "#{$ORIGIN}/#{$MASTER}"
|
73
|
+
end
|
74
|
+
|
75
|
+
merge_options = ""
|
76
|
+
if options[:edit]
|
77
|
+
merge_options += " --no-edit"
|
78
|
+
end
|
79
|
+
|
80
|
+
if options[:rebase]
|
81
|
+
ret = Git.do "contest rebase \"#{$NAME}\" \"#{$MASTER}\""
|
82
|
+
exitcode = $?.to_i
|
83
|
+
if ! $?
|
84
|
+
puts "Finish was aborted due to conflicts during rebase."
|
85
|
+
exit 1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Git.do "checkout #{$MASTER}"
|
90
|
+
if Git.do("rev-list -n2 \"#{$MASTER}..#{$BRANCH}\"").lines.to_a.length == 1
|
91
|
+
Git.do "merge --ff \"#{$BRANCH}\" #{merge_options}"
|
92
|
+
else
|
93
|
+
if options[:squash]
|
94
|
+
Git.do "merge --squash \"#{$BRANCH}\" #{merge_options}"
|
95
|
+
unless options[:edit]
|
96
|
+
Git.do "commit -m \"Squashed commit\""
|
97
|
+
else
|
98
|
+
Git.do "commit"
|
99
|
+
end
|
100
|
+
Git.do "merge \"#{$BRANCH}\" #{merge_options}"
|
101
|
+
else
|
102
|
+
Git.do "merge --no-ff \"#{$BRANCH}\" #{merge_options}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
helper_finish_cleanup
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def use_current_branch
|
112
|
+
current_branch = Git.current_branch
|
113
|
+
if current_branch.start_with? $PREFIX
|
114
|
+
$BRANCH = current_branch.strip
|
115
|
+
$NAME = $BRANCH[$PREFIX.length+1..-1]
|
116
|
+
else
|
117
|
+
puts "The current HEAD is no feature branch."
|
118
|
+
puts "Please spefcify a <name> argument."
|
119
|
+
abort ''
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def expand_contest_branch
|
124
|
+
unless has_next_token?
|
125
|
+
use_current_branch
|
126
|
+
else
|
127
|
+
$NAME = next_token
|
128
|
+
$BRANCH = "#{$PREFIX}/#{$NAME}"
|
129
|
+
Git.require_branch $BRANCH
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def helper_finish_cleanup
|
134
|
+
Git.require_branch $BRANCH
|
135
|
+
Git.require_clean_working_tree
|
136
|
+
|
137
|
+
if options[:fetch]
|
138
|
+
Git.do "push \"#{$ORIGIN}\" \":refs/heads/#{$BRANCH}\""
|
139
|
+
end
|
140
|
+
|
141
|
+
if ! options[:keep]
|
142
|
+
if options[:force_delete]
|
143
|
+
Git.do "branch -D #{$BRANCH}"
|
144
|
+
else
|
145
|
+
Git.do "branch -d #{$BRANCH}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
puts ""
|
150
|
+
puts "Summary of actions:"
|
151
|
+
puts "- The contest branch \"#{$BRANCH}\" was merged into \"#{$MASTER}\""
|
152
|
+
puts "- Contest branch \"#{$BRANCH}\" has been removed"
|
153
|
+
puts "- You are now on branch \"#{$MASTER}\""
|
154
|
+
puts ""
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#
|
2
|
+
# git-contest-init
|
3
|
+
# https://github.com/sh19910711/git-contest
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2014 Hiroyuki Sano <sh19910711 at gmail.com>
|
6
|
+
# Licensed under the MIT-License.
|
7
|
+
#
|
8
|
+
|
9
|
+
module CommandLine
|
10
|
+
|
11
|
+
module SubCommands
|
12
|
+
|
13
|
+
class InitCommand < Command
|
14
|
+
|
15
|
+
def initialize(new_args, new_input_stream = STDIN)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def define_options
|
20
|
+
opt_parser.on "-d", "--defaults", "Use default branch naming conventions." do
|
21
|
+
options[:defaults] = true
|
22
|
+
end
|
23
|
+
|
24
|
+
opt_parser.on "-f", "--force", "force setting of git-contest branches, even if already configured." do
|
25
|
+
options[:force] = true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_default_options
|
30
|
+
options[:defaults] = false if options[:defaults].nil?
|
31
|
+
options[:force] = false if options[:defaults].nil?
|
32
|
+
end
|
33
|
+
|
34
|
+
def run
|
35
|
+
if Git.contest_is_initialized && ! options[:force]
|
36
|
+
puts "Already initialized for git-contest."
|
37
|
+
puts "To force reinitialization, use: git contest init -f"
|
38
|
+
exit 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# run commands
|
42
|
+
if ! Git.do_no_echo 'rev-parse --git-dir'
|
43
|
+
Git.do 'init'
|
44
|
+
end
|
45
|
+
|
46
|
+
# init main
|
47
|
+
if Git.contest_has_master_configured
|
48
|
+
master_branch = Git.do 'config --get git.contest.branch.master'
|
49
|
+
elsif options[:defaults]
|
50
|
+
master_branch = 'master'
|
51
|
+
else
|
52
|
+
master_branch = terminal.ask('Master branch name: ') do |q|
|
53
|
+
q.default = 'master'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if options[:defaults]
|
58
|
+
prefix = 'contest'
|
59
|
+
else
|
60
|
+
prefix = terminal.ask('Prefix of contest branch name: ') do |q|
|
61
|
+
q.default = 'contest'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
if Git.repo_is_headless
|
66
|
+
Git.do 'symbolic-ref', 'HEAD', "\"refs/heads/#{master_branch}\""
|
67
|
+
Git.do 'commit --allow-empty --quiet -m "Initial commit"'
|
68
|
+
end
|
69
|
+
|
70
|
+
# save config
|
71
|
+
Git.do 'config', 'git.contest.branch.master', master_branch
|
72
|
+
Git.do 'config', 'git.contest.branch.prefix', prefix
|
73
|
+
end
|
74
|
+
|
75
|
+
end # InitCommand
|
76
|
+
|
77
|
+
end # SubCommands
|
78
|
+
|
79
|
+
end # CommandLine
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#
|
2
|
+
# git-contest-list
|
3
|
+
# https://github.com/sh19910711/git-contest
|
4
|
+
#
|
5
|
+
# Copyright (c) 2014 Hiroyuki Sano <sh19910711 at gmail.com>
|
6
|
+
# Licensed under the MIT-License.
|
7
|
+
#
|
8
|
+
|
9
|
+
module CommandLine
|
10
|
+
|
11
|
+
module SubCommands
|
12
|
+
|
13
|
+
class ListCommand < Command
|
14
|
+
|
15
|
+
def initialize(new_args, new_input_stream = STDIN)
|
16
|
+
super
|
17
|
+
|
18
|
+
Contest::Driver::Utils.load_plugins
|
19
|
+
|
20
|
+
$config = get_config() || {}
|
21
|
+
$sites = {}
|
22
|
+
if $config.has_key? 'sites'
|
23
|
+
$sites = $config["sites"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def define_options
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_default_options
|
31
|
+
end
|
32
|
+
|
33
|
+
def run
|
34
|
+
sub_commands = %w(sites drivers)
|
35
|
+
|
36
|
+
type = next_token
|
37
|
+
|
38
|
+
case type
|
39
|
+
when "drivers"
|
40
|
+
# show all drivers
|
41
|
+
puts "#"
|
42
|
+
puts "# Available Drivers"
|
43
|
+
puts "#"
|
44
|
+
puts ""
|
45
|
+
drivers = Contest::Driver::Utils.get_all_drivers
|
46
|
+
drivers.each {|driver_info|
|
47
|
+
puts " #{driver_info[:class_name]}"
|
48
|
+
puts " #{driver_info[:site_info][:desc]}"
|
49
|
+
puts ""
|
50
|
+
}
|
51
|
+
when "sites"
|
52
|
+
# show all sites
|
53
|
+
$sites.keys.each do |site_name|
|
54
|
+
puts "# #{site_name}"
|
55
|
+
keys = ["driver", "user"]
|
56
|
+
keys.each {|key| puts " %-8s: %s" % [ key, $sites[site_name][key] ] }
|
57
|
+
puts " \n"
|
58
|
+
end
|
59
|
+
else
|
60
|
+
usage
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
#Show Banner
|
68
|
+
def usage
|
69
|
+
puts get_banner
|
70
|
+
return 0
|
71
|
+
end
|
72
|
+
|
73
|
+
# Get Banner Text
|
74
|
+
def get_banner
|
75
|
+
res = ""
|
76
|
+
res += "usage: git contest list <type>\n"
|
77
|
+
res += "\n"
|
78
|
+
res += "Available types are:\n"
|
79
|
+
res += " %-8s: show sites\n" % "sites"
|
80
|
+
res += " %-8s: show drivers\n" % "drivers"
|
81
|
+
res += " \n"
|
82
|
+
return res
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# git-contest-rebase
|
3
|
+
# https://github.com/sh19910711/git-contest
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2014 Hiroyuki Sano <sh19910711 at gmail.com>
|
6
|
+
# Licensed under the MIT-License.
|
7
|
+
#
|
8
|
+
|
9
|
+
module CommandLine
|
10
|
+
|
11
|
+
module SubCommands
|
12
|
+
|
13
|
+
class RebaseCommand < Command
|
14
|
+
|
15
|
+
def initialize(new_args, new_input_stream = STDIN)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def define_options
|
20
|
+
opt_parser.on "-i", "--interactive", "Do an interactive rebase." do
|
21
|
+
options[:interactive] = true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_default_options
|
26
|
+
options[:interactive] = false if options[:interactive].nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
expand_nameprefix_arg_or_current
|
31
|
+
|
32
|
+
puts "Will try to rebase '#{$NAME}'..."
|
33
|
+
|
34
|
+
Git.require_clean_working_tree
|
35
|
+
Git.require_branch $BRANCH
|
36
|
+
|
37
|
+
Git.do "checkout -q \"#{$BRANCH}\""
|
38
|
+
rebase_options = ""
|
39
|
+
if options[:interactive]
|
40
|
+
rebase_options += " -i"
|
41
|
+
end
|
42
|
+
|
43
|
+
puts Git.do "rebase #{rebase_options} #{$MASTER}"
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def use_current_branch
|
50
|
+
current_branch = Git.current_branch
|
51
|
+
if current_branch.start_with? $PREFIX
|
52
|
+
$BRANCH = current_branch.strip
|
53
|
+
$NAME = $BRANCH[$PREFIX.length+1..-1]
|
54
|
+
else
|
55
|
+
puts "The current HEAD is no feature branch."
|
56
|
+
puts "Please spefcify a <name> argument."
|
57
|
+
abort ''
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def expand_nameprefix_arg name, prefix
|
62
|
+
expanded_name = Git.contest_resolve_nameprefix name, prefix
|
63
|
+
exitcode = $?.to_i
|
64
|
+
if $? == 0
|
65
|
+
$NAME = expanded_name
|
66
|
+
$BRANCH = "#{$PREFIX}/#{$NAME}"
|
67
|
+
else
|
68
|
+
return 1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def expand_nameprefix_arg_or_current
|
73
|
+
if has_next_token?
|
74
|
+
expand_nameprefix_arg tokens.first, $PREFIX
|
75
|
+
Git.require_branch "#{$PREFIX}/#{$NAME}"
|
76
|
+
else
|
77
|
+
use_current_branch
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#
|
2
|
+
# git-contest-start
|
3
|
+
# https://github.com/sh19910711/git-contest
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2014 Hiroyuki Sano <sh19910711 at gmail.com>
|
6
|
+
# Licensed under the MIT-License.
|
7
|
+
#
|
8
|
+
|
9
|
+
module CommandLine
|
10
|
+
|
11
|
+
module SubCommands
|
12
|
+
|
13
|
+
class StartCommand < Command
|
14
|
+
|
15
|
+
def initialize(new_args, new_input_stream = STDIN)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def define_options
|
20
|
+
opt_parser.on "-f", "--fetch", "fetch from origin before performing operation." do
|
21
|
+
options[:fetch] = true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_default_options
|
26
|
+
options[:fetch] = false if options[:fetch].nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
p options
|
31
|
+
|
32
|
+
unless has_next_token?
|
33
|
+
puts "Missing argument <name>"
|
34
|
+
exit 1
|
35
|
+
end
|
36
|
+
|
37
|
+
base_branch_name = $MASTER
|
38
|
+
# specify based branch
|
39
|
+
if tokens.length == 2
|
40
|
+
base_branch_name = tokens[1]
|
41
|
+
end
|
42
|
+
contest_branch_name = "#{tokens[0]}"
|
43
|
+
contest_branch = "#{$PREFIX}/#{contest_branch_name}"
|
44
|
+
Git.require_branch_absent contest_branch
|
45
|
+
|
46
|
+
# fetch origin/master
|
47
|
+
if options[:fetch]
|
48
|
+
Git.do "fetch -q \"#{$ORIGIN}\""
|
49
|
+
end
|
50
|
+
|
51
|
+
# require equal
|
52
|
+
if Git.branch_exists "#{$ORIGIN}/#{$MASTER}"
|
53
|
+
Git.require_branches_equal "#{$MASTER}", "#{$ORIGIN}/#{$MASTER}"
|
54
|
+
end
|
55
|
+
|
56
|
+
# create branch
|
57
|
+
if ! Git.do "checkout -b \"#{contest_branch}\" \"#{base_branch_name}\""
|
58
|
+
abort "Could not create contest branch #{contest_branch}"
|
59
|
+
end
|
60
|
+
|
61
|
+
puts ""
|
62
|
+
puts "Summary of actions:"
|
63
|
+
puts "- A new branch \"#{contest_branch}\" was created, based on \"#{base_branch_name}\""
|
64
|
+
puts "- You are now on branch \"#{contest_branch}\""
|
65
|
+
puts ""
|
66
|
+
puts "Now, start committing on your contest. When done, use:"
|
67
|
+
puts ""
|
68
|
+
puts " git contest finish #{contest_branch_name}"
|
69
|
+
puts ""
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|