git-contest 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +24 -0
- data/README.md +217 -0
- data/Rakefile +4 -0
- data/bin/git-contest +43 -0
- data/bin/git-contest-finish +163 -0
- data/bin/git-contest-init +77 -0
- data/bin/git-contest-rebase +76 -0
- data/bin/git-contest-start +68 -0
- data/bin/git-contest-submit +188 -0
- data/git-contest.gemspec +34 -0
- data/lib/contest/driver.rb +15 -0
- data/lib/contest/driver/aizu_online_judge.rb +159 -0
- data/lib/contest/driver/base.rb +103 -0
- data/lib/contest/driver/codeforces.rb +196 -0
- data/lib/contest/driver/common.rb +72 -0
- data/lib/contest/driver/driver_event.rb +30 -0
- data/lib/contest/driver/uva_online_judge.rb +131 -0
- data/lib/git/contest.rb +14 -0
- data/lib/git/contest/common.rb +48 -0
- data/lib/git/contest/git.rb +189 -0
- data/lib/git/contest/test.rb +10 -0
- data/lib/git/contest/version.rb +12 -0
- data/spec/bin/t004_git_contest_submit_spec.rb +143 -0
- data/spec/bin/t005_git_contest_branching_spec.rb +83 -0
- data/spec/bin/t007_git_contest_start_spec.rb +121 -0
- data/spec/bin/t008_git_contest_finish_spec.rb +229 -0
- data/spec/bin/t009_git_contest_init_spec.rb +82 -0
- data/spec/lib/contest/driver/t001_aizu_online_judge_spec.rb +177 -0
- data/spec/lib/contest/driver/t002_codeforces_spec.rb +34 -0
- data/spec/lib/contest/driver/t003_uva_online_judge_spec.rb +33 -0
- data/spec/mock/default_config/config.yml +0 -0
- data/spec/mock/default_config/plugins/driver_dummy.rb +113 -0
- data/spec/mock/t001/002.status_log.xml +55 -0
- data/spec/mock/t001/config.yml +5 -0
- data/spec/mock/t001/description.html +48 -0
- data/spec/mock/t001/status.html +49 -0
- data/spec/mock/t001/status_log.xml +29 -0
- data/spec/mock/t002/my_submissions.html +58 -0
- data/spec/mock/t003/after_submit.html +28 -0
- data/spec/mock/t003/my_submissions.compile_error.html +160 -0
- data/spec/mock/t003/my_submissions.sent_to_judge.html +358 -0
- data/spec/mock/t004/config.yml +17 -0
- data/spec/mock/t005/001/config.yml +5 -0
- data/spec/mock/t006/001/001/001/config.yml +8 -0
- data/spec/mock/t006/001/001/002/config.yml +8 -0
- data/spec/mock/t006/001/001/003/config.yml +8 -0
- data/spec/mock/t006/001/002/001/config.yml +8 -0
- data/spec/mock/t006/001/002/002/config.yml +8 -0
- data/spec/mock/t006/001/002/003/config.yml +8 -0
- data/spec/mock/t006/001/003/001/config.yml +9 -0
- data/spec/mock/t006/001/003/002/config.yml +9 -0
- data/spec/mock/t006/001/003/003/config.yml +9 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/spec_list.txt +1 -0
- data/spec/t006_config_spec.rb +168 -0
- metadata +269 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# git-contest-init
|
5
|
+
# https://github.com/sh19910711/git-contest
|
6
|
+
#
|
7
|
+
# Copyright (c) 2013 Hiroyuki Sano <sh19910711 at gmail.com>
|
8
|
+
# Licensed under the MIT-License.
|
9
|
+
#
|
10
|
+
|
11
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
12
|
+
require 'git/contest/common'
|
13
|
+
require 'trollop'
|
14
|
+
require 'highline/import'
|
15
|
+
|
16
|
+
init
|
17
|
+
|
18
|
+
sub_commands = %w()
|
19
|
+
options = Trollop::options do
|
20
|
+
version "git-contest #{Git::Contest::VERSION} (c) 2013 Hiroyuki Sano"
|
21
|
+
opt(
|
22
|
+
:defaults,
|
23
|
+
"Use default branch naming conventions.",
|
24
|
+
:type => :flag,
|
25
|
+
:default => false,
|
26
|
+
:required => false,
|
27
|
+
)
|
28
|
+
opt(
|
29
|
+
:force,
|
30
|
+
"force setting of git-contest branches, even if already configured.",
|
31
|
+
:short => :f,
|
32
|
+
:type => :flag,
|
33
|
+
:default => false,
|
34
|
+
:required => false,
|
35
|
+
)
|
36
|
+
stop_on sub_commands
|
37
|
+
end
|
38
|
+
|
39
|
+
if git_contest_is_initialized && ! options[:force]
|
40
|
+
puts "Already initialized for git-contest."
|
41
|
+
puts "To force reinitialization, use: git contest init -f"
|
42
|
+
exit 0
|
43
|
+
end
|
44
|
+
|
45
|
+
# run commands
|
46
|
+
if ! git_do_no_echo 'rev-parse --git-dir'
|
47
|
+
git_do 'init'
|
48
|
+
end
|
49
|
+
|
50
|
+
# init main
|
51
|
+
if git_contest_has_master_configured
|
52
|
+
master_branch = git_do 'config --get git.contest.branch.master'
|
53
|
+
elsif options[:defaults]
|
54
|
+
master_branch = 'master'
|
55
|
+
else
|
56
|
+
master_branch = ask('Master branch name: ') do |q|
|
57
|
+
q.default = 'master'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if options[:defaults]
|
62
|
+
prefix = 'contest'
|
63
|
+
else
|
64
|
+
prefix = ask('Prefix of contest branch name: ') do |q|
|
65
|
+
q.default = 'contest'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if git_repo_is_headless
|
70
|
+
git_do 'symbolic-ref', 'HEAD', "\"refs/heads/#{master_branch}\""
|
71
|
+
git_do 'commit --allow-empty --quiet -m "Initial commit"'
|
72
|
+
end
|
73
|
+
|
74
|
+
# save config
|
75
|
+
git_do 'config', 'git.contest.branch.master', master_branch
|
76
|
+
git_do 'config', 'git.contest.branch.prefix', prefix
|
77
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# git-contest-rebase
|
5
|
+
# https://github.com/sh19910711/git-contest
|
6
|
+
#
|
7
|
+
# Copyright (c) 2013 Hiroyuki Sano <sh19910711 at gmail.com>
|
8
|
+
# Licensed under the MIT-License.
|
9
|
+
#
|
10
|
+
|
11
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
12
|
+
require 'git/contest/common'
|
13
|
+
require 'trollop'
|
14
|
+
|
15
|
+
def use_current_branch
|
16
|
+
current_branch = git_current_branch
|
17
|
+
if current_branch.start_with? $PREFIX
|
18
|
+
$BRANCH = current_branch.strip
|
19
|
+
$NAME = $BRANCH[$PREFIX.length+1..-1]
|
20
|
+
else
|
21
|
+
puts "The current HEAD is no feature branch."
|
22
|
+
puts "Please spefcify a <name> argument."
|
23
|
+
abort ''
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def expand_nameprefix_arg name, prefix
|
28
|
+
expanded_name = git_contest_resolve_nameprefix name, prefix
|
29
|
+
exitcode = $?.to_i
|
30
|
+
if $? == 0
|
31
|
+
$NAME = expanded_name
|
32
|
+
$BRANCH = "#{$PREFIX}/#{$NAME}"
|
33
|
+
else
|
34
|
+
return 1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def expand_nameprefix_arg_or_current
|
39
|
+
if ARGV.length > 0
|
40
|
+
expand_nameprefix_arg ARGV[0], $PREFIX
|
41
|
+
require_branch "#{$PREFIX}/#{$NAME}"
|
42
|
+
else
|
43
|
+
use_current_branch
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
init
|
48
|
+
|
49
|
+
sub_commands = %w()
|
50
|
+
$options = Trollop::options do
|
51
|
+
version "git-contest #{Git::Contest::VERSION} (c) 2013 Hiroyuki Sano"
|
52
|
+
opt(
|
53
|
+
:interactive,
|
54
|
+
"Do an interactive rebase.",
|
55
|
+
:type => :flag,
|
56
|
+
:default => false,
|
57
|
+
:required => false,
|
58
|
+
)
|
59
|
+
stop_on sub_commands
|
60
|
+
end
|
61
|
+
|
62
|
+
expand_nameprefix_arg_or_current
|
63
|
+
|
64
|
+
puts "Will try to rebase '#{$NAME}'..."
|
65
|
+
|
66
|
+
require_clean_working_tree
|
67
|
+
require_branch $BRANCH
|
68
|
+
|
69
|
+
git_do "checkout -q \"#{$BRANCH}\""
|
70
|
+
rebase_options = ""
|
71
|
+
if $options[:interactive]
|
72
|
+
rebase_options += " -i"
|
73
|
+
end
|
74
|
+
|
75
|
+
puts git_do "rebase #{rebase_options} #{$MASTER}"
|
76
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# git-contest-start
|
5
|
+
# https://github.com/sh19910711/git-contest
|
6
|
+
#
|
7
|
+
# Copyright (c) 2013 Hiroyuki Sano <sh19910711 at gmail.com>
|
8
|
+
# Licensed under the MIT-License.
|
9
|
+
#
|
10
|
+
|
11
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
12
|
+
require 'git/contest/common'
|
13
|
+
require 'trollop'
|
14
|
+
|
15
|
+
init
|
16
|
+
|
17
|
+
sub_commands = %w()
|
18
|
+
options = Trollop::options do
|
19
|
+
version "git-contest #{Git::Contest::VERSION} (c) 2013 Hiroyuki Sano"
|
20
|
+
opt(
|
21
|
+
:fetch,
|
22
|
+
"fetch from origin before performing operation.",
|
23
|
+
:type => :flag,
|
24
|
+
:default => false,
|
25
|
+
:required => false,
|
26
|
+
)
|
27
|
+
stop_on sub_commands
|
28
|
+
end
|
29
|
+
|
30
|
+
if ARGV.length == 0
|
31
|
+
puts "Missing argument <name>"
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
base_branch_name = $MASTER
|
36
|
+
# specify based branch
|
37
|
+
if ARGV.length == 2
|
38
|
+
base_branch_name = ARGV[1]
|
39
|
+
end
|
40
|
+
contest_branch_name = "#{ARGV[0]}"
|
41
|
+
contest_branch = "#{$PREFIX}/#{contest_branch_name}"
|
42
|
+
require_branch_absent contest_branch
|
43
|
+
|
44
|
+
# fetch origin/master
|
45
|
+
if options[:fetch]
|
46
|
+
git_do "fetch -q \"#{$ORIGIN}\""
|
47
|
+
end
|
48
|
+
|
49
|
+
# require equal
|
50
|
+
if git_branch_exists "#{$ORIGIN}/#{$MASTER}"
|
51
|
+
require_branches_equal "#{$MASTER}", "#{$ORIGIN}/#{$MASTER}"
|
52
|
+
end
|
53
|
+
|
54
|
+
# create branch
|
55
|
+
if ! git_do "checkout -b \"#{contest_branch}\" \"#{base_branch_name}\""
|
56
|
+
abort "Could not create contest branch #{contest_branch}"
|
57
|
+
end
|
58
|
+
|
59
|
+
puts ""
|
60
|
+
puts "Summary of actions:"
|
61
|
+
puts "- A new branch \"#{contest_branch}\" was created, based on \"#{base_branch_name}\""
|
62
|
+
puts "- You are now on branch \"#{contest_branch}\""
|
63
|
+
puts ""
|
64
|
+
puts "Now, start committing on your contest. When done, use:"
|
65
|
+
puts ""
|
66
|
+
puts " git contest finish #{contest_branch_name}"
|
67
|
+
puts ""
|
68
|
+
|
@@ -0,0 +1,188 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# git-contest-submit
|
5
|
+
# https://github.com/sh19910711/git-contest
|
6
|
+
#
|
7
|
+
# Copyright (c) 2013 Hiroyuki Sano <sh19910711 at gmail.com>
|
8
|
+
# Licensed under the MIT-License.
|
9
|
+
#
|
10
|
+
|
11
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
12
|
+
require 'git/contest/common'
|
13
|
+
require 'trollop'
|
14
|
+
|
15
|
+
init
|
16
|
+
|
17
|
+
$config = get_config() || {}
|
18
|
+
$sites = {}
|
19
|
+
if $config.has_key? 'sites'
|
20
|
+
$sites = $config["sites"]
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Load Plugins
|
25
|
+
#
|
26
|
+
def load_plugins
|
27
|
+
# load drivers
|
28
|
+
Dir.glob("#{$GIT_CONTEST_HOME}/plugins/**") do |path|
|
29
|
+
require path if /\/driver_.*\.rb$/.match path
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
load_plugins
|
34
|
+
|
35
|
+
#
|
36
|
+
# Load Drivers
|
37
|
+
#
|
38
|
+
def load_drivers
|
39
|
+
driver_names = $sites.keys().map {|key| $sites[key]["driver"] }
|
40
|
+
driver_names.uniq.each do |driver_name|
|
41
|
+
class_name = driver_name.clone
|
42
|
+
class_name.gsub!(/^[a-z]/) {|c| c.upcase }
|
43
|
+
class_name.gsub!(/(_)([a-z])/) {|c, b| $2.upcase }
|
44
|
+
$drivers[driver_name] = Contest::Driver.const_get "#{class_name}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
$drivers = {}
|
49
|
+
load_drivers
|
50
|
+
|
51
|
+
#
|
52
|
+
# Command Utils
|
53
|
+
#
|
54
|
+
def usage
|
55
|
+
puts get_banner
|
56
|
+
return 0
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_banner
|
60
|
+
res = ""
|
61
|
+
res += "usage: git contest submit <site>\n"
|
62
|
+
res += "\n"
|
63
|
+
res += "Available sites are:\n"
|
64
|
+
$sites.keys().each do |site|
|
65
|
+
if $drivers.has_key? $sites[site]["driver"]
|
66
|
+
driver = $drivers[$sites[site]["driver"]].new
|
67
|
+
res += " %-12s\t#{driver.get_desc}\n" % [site]
|
68
|
+
else
|
69
|
+
# TODO: driver not found
|
70
|
+
end
|
71
|
+
end
|
72
|
+
res += "\n"
|
73
|
+
res += "Try 'git contest submit <site> --help' for details.\n"
|
74
|
+
return res
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_git_add_target rule
|
78
|
+
str = rule
|
79
|
+
str = str.gsub('${source}', $submit_info[:source])
|
80
|
+
str
|
81
|
+
end
|
82
|
+
|
83
|
+
# check options
|
84
|
+
sub_commands = $sites.keys
|
85
|
+
global_opts = Trollop::options do
|
86
|
+
version "git-contest #{Git::Contest::VERSION} (c) 2013 Hiroyuki Sano"
|
87
|
+
banner get_banner
|
88
|
+
stop_on sub_commands
|
89
|
+
end
|
90
|
+
|
91
|
+
# detect site
|
92
|
+
site = ARGV.shift.to_s.strip
|
93
|
+
|
94
|
+
unless $sites.has_key?(site)
|
95
|
+
if site != ""
|
96
|
+
puts "site not found"
|
97
|
+
else
|
98
|
+
usage
|
99
|
+
end
|
100
|
+
exit 0
|
101
|
+
end
|
102
|
+
|
103
|
+
# detect driver
|
104
|
+
driver_name = $sites[site]["driver"]
|
105
|
+
|
106
|
+
unless $drivers.has_key?(driver_name)
|
107
|
+
puts "driver not found"
|
108
|
+
exit
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Submit Start
|
113
|
+
#
|
114
|
+
driver = $drivers[driver_name].new
|
115
|
+
|
116
|
+
$submit_info = {}
|
117
|
+
|
118
|
+
# set events
|
119
|
+
driver.on(
|
120
|
+
'start',
|
121
|
+
Proc.new do
|
122
|
+
puts "@start: submit"
|
123
|
+
end
|
124
|
+
)
|
125
|
+
driver.on(
|
126
|
+
'before_login',
|
127
|
+
Proc.new do
|
128
|
+
puts "@submit: logging in..."
|
129
|
+
end
|
130
|
+
)
|
131
|
+
driver.on(
|
132
|
+
'after_login',
|
133
|
+
Proc.new do
|
134
|
+
puts "@submit: login ok"
|
135
|
+
end
|
136
|
+
)
|
137
|
+
driver.on(
|
138
|
+
'before_submit',
|
139
|
+
Proc.new do |submit_info|
|
140
|
+
$submit_info = submit_info
|
141
|
+
puts "@submit: doing..."
|
142
|
+
end
|
143
|
+
)
|
144
|
+
driver.on(
|
145
|
+
'after_submit',
|
146
|
+
Proc.new do
|
147
|
+
puts "@submit: done"
|
148
|
+
end
|
149
|
+
)
|
150
|
+
driver.on(
|
151
|
+
'before_wait',
|
152
|
+
Proc.new do
|
153
|
+
print "@result: waiting..."
|
154
|
+
end
|
155
|
+
)
|
156
|
+
driver.on(
|
157
|
+
'retry',
|
158
|
+
Proc.new do
|
159
|
+
print "."
|
160
|
+
end
|
161
|
+
)
|
162
|
+
driver.on(
|
163
|
+
'after_wait',
|
164
|
+
Proc.new do |submission_info|
|
165
|
+
puts ""
|
166
|
+
next unless submission_info.is_a?(Hash)
|
167
|
+
puts ""
|
168
|
+
puts "@result: Submission Result"
|
169
|
+
puts " %s: %s" % ["submission id", "#{submission_info[:submission_id]}"]
|
170
|
+
puts " %s: %s" % ["status", "#{submission_info[:status]}"]
|
171
|
+
puts ""
|
172
|
+
if git_contest_is_initialized
|
173
|
+
git_do "add #{get_git_add_target($config["submit_rules"]["add"] || ".")}"
|
174
|
+
git_do "commit --allow-empty -m '#{submission_info[:result]}'"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
)
|
178
|
+
driver.on(
|
179
|
+
'finish',
|
180
|
+
Proc.new do
|
181
|
+
puts "@finish"
|
182
|
+
end
|
183
|
+
)
|
184
|
+
|
185
|
+
opts = driver.get_opts()
|
186
|
+
result = driver.submit $sites[site], "main.*", opts
|
187
|
+
|
188
|
+
|
data/git-contest.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'git/contest/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = "git-contest"
|
10
|
+
spec.version = Git::Contest::VERSION
|
11
|
+
spec.authors = ["Hiroyuki Sano"]
|
12
|
+
spec.email = ["sh19910711@gmail.com"]
|
13
|
+
spec.description = %q{the Git Extension for online judge (Codeforces, Google Codejam, ICPC, etc...)}
|
14
|
+
spec.summary = %q{the git extension for online judge}
|
15
|
+
spec.homepage = "https://github.com/sh19910711/git-contest"
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($/)
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_dependency "mechanize"
|
24
|
+
spec.add_dependency "nokogiri"
|
25
|
+
spec.add_dependency "trollop"
|
26
|
+
spec.add_dependency "highline"
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
spec.add_development_dependency "watchr"
|
31
|
+
spec.add_development_dependency "rspec"
|
32
|
+
spec.add_development_dependency "webmock"
|
33
|
+
end
|
34
|
+
|