git-contest 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +15 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +24 -0
  7. data/README.md +217 -0
  8. data/Rakefile +4 -0
  9. data/bin/git-contest +43 -0
  10. data/bin/git-contest-finish +163 -0
  11. data/bin/git-contest-init +77 -0
  12. data/bin/git-contest-rebase +76 -0
  13. data/bin/git-contest-start +68 -0
  14. data/bin/git-contest-submit +188 -0
  15. data/git-contest.gemspec +34 -0
  16. data/lib/contest/driver.rb +15 -0
  17. data/lib/contest/driver/aizu_online_judge.rb +159 -0
  18. data/lib/contest/driver/base.rb +103 -0
  19. data/lib/contest/driver/codeforces.rb +196 -0
  20. data/lib/contest/driver/common.rb +72 -0
  21. data/lib/contest/driver/driver_event.rb +30 -0
  22. data/lib/contest/driver/uva_online_judge.rb +131 -0
  23. data/lib/git/contest.rb +14 -0
  24. data/lib/git/contest/common.rb +48 -0
  25. data/lib/git/contest/git.rb +189 -0
  26. data/lib/git/contest/test.rb +10 -0
  27. data/lib/git/contest/version.rb +12 -0
  28. data/spec/bin/t004_git_contest_submit_spec.rb +143 -0
  29. data/spec/bin/t005_git_contest_branching_spec.rb +83 -0
  30. data/spec/bin/t007_git_contest_start_spec.rb +121 -0
  31. data/spec/bin/t008_git_contest_finish_spec.rb +229 -0
  32. data/spec/bin/t009_git_contest_init_spec.rb +82 -0
  33. data/spec/lib/contest/driver/t001_aizu_online_judge_spec.rb +177 -0
  34. data/spec/lib/contest/driver/t002_codeforces_spec.rb +34 -0
  35. data/spec/lib/contest/driver/t003_uva_online_judge_spec.rb +33 -0
  36. data/spec/mock/default_config/config.yml +0 -0
  37. data/spec/mock/default_config/plugins/driver_dummy.rb +113 -0
  38. data/spec/mock/t001/002.status_log.xml +55 -0
  39. data/spec/mock/t001/config.yml +5 -0
  40. data/spec/mock/t001/description.html +48 -0
  41. data/spec/mock/t001/status.html +49 -0
  42. data/spec/mock/t001/status_log.xml +29 -0
  43. data/spec/mock/t002/my_submissions.html +58 -0
  44. data/spec/mock/t003/after_submit.html +28 -0
  45. data/spec/mock/t003/my_submissions.compile_error.html +160 -0
  46. data/spec/mock/t003/my_submissions.sent_to_judge.html +358 -0
  47. data/spec/mock/t004/config.yml +17 -0
  48. data/spec/mock/t005/001/config.yml +5 -0
  49. data/spec/mock/t006/001/001/001/config.yml +8 -0
  50. data/spec/mock/t006/001/001/002/config.yml +8 -0
  51. data/spec/mock/t006/001/001/003/config.yml +8 -0
  52. data/spec/mock/t006/001/002/001/config.yml +8 -0
  53. data/spec/mock/t006/001/002/002/config.yml +8 -0
  54. data/spec/mock/t006/001/002/003/config.yml +8 -0
  55. data/spec/mock/t006/001/003/001/config.yml +9 -0
  56. data/spec/mock/t006/001/003/002/config.yml +9 -0
  57. data/spec/mock/t006/001/003/003/config.yml +9 -0
  58. data/spec/spec_helper.rb +45 -0
  59. data/spec/spec_list.txt +1 -0
  60. data/spec/t006_config_spec.rb +168 -0
  61. 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
+
@@ -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
+