bcpm 0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bcpm}
5
+ s.version = "0.11"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Victor Costan"]
9
+ s.date = %q{2011-01-26}
10
+ s.default_executable = %q{bcpm}
11
+ s.description = %q{Battlecode (MIT 6.370) package manager.}
12
+ s.email = %q{victor@costan.us}
13
+ s.executables = ["bcpm"]
14
+ s.extra_rdoc_files = ["CHANGELOG", "README", "bin/bcpm", "lib/bcpm.rb", "lib/bcpm/cleanup.rb", "lib/bcpm/cli.rb", "lib/bcpm/config.rb", "lib/bcpm/dist.rb", "lib/bcpm/duel.rb", "lib/bcpm/git.rb", "lib/bcpm/match.rb", "lib/bcpm/player.rb", "lib/bcpm/regen.rb", "lib/bcpm/socket.rb", "lib/bcpm/tests/assertion_error.rb", "lib/bcpm/tests/assertions.rb", "lib/bcpm/tests/case_base.rb", "lib/bcpm/tests/environment.rb", "lib/bcpm/tests/suite.rb", "lib/bcpm/tests/test_match.rb", "lib/bcpm/update.rb"]
15
+ s.files = ["CHANGELOG", "Manifest", "README", "Rakefile", "bin/bcpm", "lib/bcpm.rb", "lib/bcpm/cleanup.rb", "lib/bcpm/cli.rb", "lib/bcpm/config.rb", "lib/bcpm/dist.rb", "lib/bcpm/duel.rb", "lib/bcpm/git.rb", "lib/bcpm/match.rb", "lib/bcpm/player.rb", "lib/bcpm/regen.rb", "lib/bcpm/socket.rb", "lib/bcpm/tests/assertion_error.rb", "lib/bcpm/tests/assertions.rb", "lib/bcpm/tests/case_base.rb", "lib/bcpm/tests/environment.rb", "lib/bcpm/tests/suite.rb", "lib/bcpm/tests/test_match.rb", "lib/bcpm/update.rb", "bcpm.gemspec"]
16
+ s.homepage = %q{http://git.pwnb.us/six370}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bcpm", "--main", "README"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{bcpm}
20
+ s.rubygems_version = %q{1.3.7}
21
+ s.summary = %q{Battlecode (MIT 6.370) package manager.}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
+ s.add_development_dependency(%q<echoe>, [">= 3.2"])
29
+ else
30
+ s.add_dependency(%q<echoe>, [">= 3.2"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<echoe>, [">= 3.2"])
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'bcpm'
4
+
5
+ Bcpm::CLI.run ARGV
@@ -0,0 +1,23 @@
1
+ # Battlecode package manager.
2
+ #
3
+ # See the README for a reference on the command-line interface.
4
+ module Bcpm
5
+ end
6
+
7
+ require 'bcpm/cleanup.rb'
8
+ require 'bcpm/cli.rb'
9
+ require 'bcpm/config.rb'
10
+ require 'bcpm/dist.rb'
11
+ require 'bcpm/duel.rb'
12
+ require 'bcpm/git.rb'
13
+ require 'bcpm/match.rb'
14
+ require 'bcpm/player.rb'
15
+ require 'bcpm/regen.rb'
16
+ require 'bcpm/socket.rb'
17
+ require 'bcpm/tests/assertions.rb'
18
+ require 'bcpm/tests/assertion_error.rb'
19
+ require 'bcpm/tests/case_base.rb'
20
+ require 'bcpm/tests/environment.rb'
21
+ require 'bcpm/tests/suite.rb'
22
+ require 'bcpm/tests/test_match.rb'
23
+ require 'bcpm/update.rb'
@@ -0,0 +1,24 @@
1
+ require 'tmpdir'
2
+
3
+ # :nodoc: namespace
4
+ module Bcpm
5
+
6
+ # Cleans up all the messes left behind by bcpm crashes.
7
+ module Cleanup
8
+ # Cleans up all the messes left behind by bcpm crashes.
9
+ def self.run
10
+ Bcpm::Player.list.each do |player|
11
+ Bcpm::Player.uninstall player if /^bcpmtest/ =~ player
12
+ end
13
+
14
+ temp_path = File.join(Dir.tmpdir, 'bcpm')
15
+ return unless File.exist?(temp_path)
16
+ Dir.entries(temp_path).each do |entry|
17
+ next if ['.', '..'].include? entry
18
+ path = File.join temp_path, entry
19
+ FileUtils.rm_rf path if File.directory? path
20
+ end
21
+ end
22
+ end # module Bcpm::Cleanup
23
+
24
+ end # namespace Bcpm
@@ -0,0 +1,262 @@
1
+ require 'fileutils'
2
+
3
+ # :nodoc: namespace
4
+ module Bcpm
5
+
6
+ # Command-line interface.
7
+ module CLI
8
+ # Entry point for commands.
9
+ def self.run(args)
10
+ if args.length < 1
11
+ help
12
+ exit 1
13
+ end
14
+
15
+ case args.first
16
+ when 'self', 'gem' # Upgrade bcpm.
17
+ Bcpm::Update.upgrade
18
+ when 'dist' # Install or upgrade the battlecode distribution.
19
+ Bcpm::Dist.upgrade
20
+ when 'reset' # Uninstalls the distribution and players, and removes the config file.
21
+ Bcpm::Cleanup.run
22
+ Bcpm::Player.uninstall_all
23
+ Bcpm::Dist.uninstall
24
+ Bcpm::Config.reset
25
+ when 'install' # Add a player project to the workspace, from a git repository.
26
+ unless Bcpm::Dist.installed?
27
+ puts "Please install a battlecode distribution first!"
28
+ exit 1
29
+ end
30
+
31
+ if args.length < 2
32
+ puts "Please supply the path to the player repository!"
33
+ exit 1
34
+ end
35
+ exit 1 unless Bcpm::Player.install(args[1], args[2] || 'master')
36
+ when 'copy', 'copyplayer' # Create a new player project using an existing project as a template.
37
+ unless Bcpm::Dist.installed?
38
+ puts "Please install a battlecode distribution first!"
39
+ exit 1
40
+ end
41
+
42
+ if args.length < 3
43
+ puts "Please supply the new player name, and the path to the template player repository!"
44
+ exit 1
45
+ end
46
+ exit 1 unless Bcpm::Player.checkpoint(args[2], args[3] || 'master', args[1])
47
+ when 'new', 'newplayer' # Create a new player project from the built-in template.
48
+ unless Bcpm::Dist.installed?
49
+ puts "Please install a battlecode distribution first!"
50
+ exit 1
51
+ end
52
+
53
+ if args.length < 2
54
+ puts "Please supply the new player name!"
55
+ exit 1
56
+ end
57
+ exit 1 unless Bcpm::Player.create(args[1])
58
+ when 'uninstall', 'remove' # Remove a player project from the workspace.
59
+ unless Bcpm::Dist.installed?
60
+ puts "Please install a battlecode distribution first!"
61
+ exit 1
62
+ end
63
+
64
+ if args.length < 2
65
+ puts "Please supply the player name!"
66
+ exit 1
67
+ end
68
+ Bcpm::Player.uninstall args[1]
69
+ when 'rewire' # Re-write a player project's configuration files.
70
+ unless Bcpm::Dist.installed?
71
+ puts "Please install a battlecode distribution first!"
72
+ exit 1
73
+ end
74
+
75
+ if args.length == 1
76
+ # Try using the current dir as the player name.
77
+ args[1, 0] = [File.basename(Dir.pwd)]
78
+ end
79
+
80
+ if args.length < 2
81
+ puts "Please supply the player name!"
82
+ exit 1
83
+ end
84
+ Bcpm::Player.reconfigure args[1]
85
+ when 'list', 'ls' # Displays the installed players.
86
+ unless Bcpm::Dist.installed?
87
+ puts "Please install a battlecode distribution first!"
88
+ exit 1
89
+ end
90
+ puts Bcpm::Player.list_active.sort.join("\n")
91
+ when 'match', 'livematch', 'debugmatch', 'debug' # Run a match in live or headless mode.
92
+ unless Bcpm::Dist.installed?
93
+ puts "Please install a battlecode distribution first!"
94
+ exit 1
95
+ end
96
+
97
+ if args.length == 3
98
+ # Try using the current dir as a player name.
99
+ args[1, 0] = [File.basename(Dir.pwd)]
100
+ end
101
+
102
+ if args.length < 4
103
+ puts "Please supply the player names and the map name!"
104
+ exit 1
105
+ end
106
+ mode = if args[0][0, 4] == 'live'
107
+ :live
108
+ elsif args[0][0, 5] == 'debug'
109
+ :debug
110
+ else
111
+ :file
112
+ end
113
+ puts Bcpm::Match.run(args[1], args[2], args[3], mode)
114
+ when 'duel' # Have two players fight it out on all maps.
115
+ if args.length < 3
116
+ puts "Pleas supply the player names!"
117
+ exit 1
118
+ end
119
+ if args.length >= 4
120
+ maps = args[3..-1]
121
+ else
122
+ maps = nil
123
+ end
124
+ outcome = Bcpm::Duel.duel_pair args[1], args[2], true, maps
125
+ puts "#{'%+3d' % outcome[:score]} points, " +
126
+ "#{'%3d' % outcome[:wins].length} wins, " +
127
+ " #{'%3d' % outcome[:losses].length} losses, " +
128
+ "#{'%3d' % outcome[:errors].length} errors"
129
+ when 'rank' # Ranks all the players.
130
+ if args.length < 2
131
+ players = Bcpm::Player.list_active.sort
132
+ else
133
+ players = args[1..-1]
134
+ end
135
+ outcome = Bcpm::Duel.rank_players players, true
136
+ outcome.each { |score, player| print "%+4d %s\n" % [score, player] }
137
+ when 'pit' # Pits one player against all the other players.
138
+ if args.length < 2
139
+ puts "Please supply a player name!"
140
+ end
141
+ player = args[1]
142
+ if args.length >= 3
143
+ enemies = args[2..-1]
144
+ else
145
+ enemies = Bcpm::Player.list_active.sort - [player]
146
+ end
147
+ outcome = Bcpm::Duel.score_player player, enemies, true
148
+ puts "#{'%+4d' % outcome[:points]} points"
149
+ outcome[:scores].each do |score, player|
150
+ print "%+4d vs %s\n" % [score, player]
151
+ end
152
+ when 'replay' # Replay a match using its binlog (.rms file).
153
+ unless Bcpm::Dist.installed?
154
+ puts "Please install a battlecode distribution first!"
155
+ exit 1
156
+ end
157
+
158
+ if args.length == 1
159
+ # Replay the last game.
160
+ replays = Bcpm::Tests::TestMatch.stashed_replays
161
+ args[1, 0] = [replays.max] unless replays.empty?
162
+ end
163
+
164
+ if args.length < 2
165
+ puts "Please supply the path to the match binlog (.rms file)!"
166
+ exit 1
167
+ end
168
+ Bcpm::Match.replay args[1]
169
+ when 'test' # Run the entire test suite against a player.
170
+ unless Bcpm::Dist.installed?
171
+ puts "Please install a battlecode distribution first!"
172
+ exit 1
173
+ end
174
+
175
+ if args.length == 1
176
+ # Try using the current dir as the player name.
177
+ args[1, 0] = [File.basename(Dir.pwd)]
178
+ end
179
+
180
+ if args.length < 2
181
+ puts "Please supply the player name!"
182
+ exit 1
183
+ end
184
+ Bcpm::Player.run_suite args[1]
185
+ when 'case', 'testcase', 'livecase', 'live' # Run a single testcase against a player.
186
+ unless Bcpm::Dist.installed?
187
+ puts "Please install a battlecode distribution first!"
188
+ exit 1
189
+ end
190
+
191
+ if args.length == 2
192
+ # Try using the current dir as the player name.
193
+ args[1, 0] = [File.basename(Dir.pwd)]
194
+ end
195
+
196
+ if args.length < 3
197
+ puts "Please supply the player name and the testcase name!"
198
+ exit 1
199
+ end
200
+ Bcpm::Player.run_case args[2], args[0][0, 4] == 'live', args[1]
201
+
202
+ when 'clean', 'cleanup' # Removes all temporaries left behind by crashes.
203
+ Bcpm::Cleanup.run
204
+
205
+ when 'config', 'set'
206
+ if args.length < 2
207
+ Bcpm::Config.print_config
208
+ else
209
+ Bcpm::Config.ui_set(args[1], args[2])
210
+ end
211
+
212
+ when 'regen' # Regenerates automatically generated source code.
213
+ if args.length < 2
214
+ puts "Please supply the source file(s)."
215
+ exit 1
216
+ end
217
+ Bcpm::Regen.run args[1..-1]
218
+
219
+ when 'lsmaps', 'lsmap', 'maps', 'map' # Lists the maps in the distribution.
220
+ unless Bcpm::Dist.installed?
221
+ puts "Please install a battlecode distribution first!"
222
+ exit 1
223
+ end
224
+ puts Bcpm::Dist.maps.sort.join("\n")
225
+ when 'copymap', 'cpmap' # Clones a distribution map for testing.
226
+ unless Bcpm::Dist.installed?
227
+ puts "Please install a battlecode distribution first!"
228
+ exit 1
229
+ end
230
+ if args.length < 2
231
+ puts "Please supply the map name and destination"
232
+ exit 1
233
+ end
234
+ if args.length < 3
235
+ # Default destination.
236
+ if File.exist?('suite') && File.directory?('suite')
237
+ FileUtils.mkdir_p 'maps'
238
+ args[2] = 'suite/maps'
239
+ else
240
+ puts "Please supply map destination or cd into a player directory"
241
+ exit 1
242
+ end
243
+ end
244
+ Bcpm::Dist.copy_map args[1], args[2]
245
+ else
246
+ help
247
+ exit 1
248
+ end
249
+ end
250
+
251
+ # Prints the CLI help.
252
+ def self.help
253
+ print <<END_HELP
254
+ Battlecode (MIT 6.470) package manager.
255
+
256
+ See the README file for usage instructions.
257
+
258
+ END_HELP
259
+ end
260
+ end # module Bcpm::CLI
261
+
262
+ end # namespace Bcpm
@@ -0,0 +1,100 @@
1
+ require 'yaml'
2
+
3
+ # :nodoc: namespace
4
+ module Bcpm
5
+
6
+ # Persistent, per-user bcpm configuration information.
7
+ module Config
8
+ # Hash-style access to the configuration dictionary.
9
+ def self.[](key)
10
+ config[key.to_sym]
11
+ end
12
+
13
+ # Hash-style access to configuration dictionary.
14
+ def self.[]=(key, new_value)
15
+ if new_value.nil?
16
+ config.delete key.to_sym
17
+ else
18
+ config[key.to_sym] = new_value
19
+ end
20
+ write_config
21
+ end
22
+
23
+ # The configuration dictionary.
24
+ def self.config
25
+ @config ||= read_config
26
+ end
27
+
28
+ # Reads the YAML configuration file.
29
+ def self.read_config
30
+ if File.exists? config_file
31
+ @config = File.open(config_file) { |f| YAML.load f }
32
+ else
33
+ @config = {}
34
+ end
35
+ end
36
+
37
+ # Writes the configuration to the YAML file.
38
+ def self.write_config
39
+ File.open(config_file, 'wb') { |f| YAML.dump config, f }
40
+ end
41
+
42
+ # Path to the configuration YAML file.
43
+ def self.config_file
44
+ File.expand_path '~/.bcpm_config'
45
+ end
46
+
47
+ # Removes the configuration YAML file and resets the configuration hash.
48
+ def self.reset
49
+ File.unlink config_file if File.exist?(config_file)
50
+ @config = nil
51
+ end
52
+
53
+ # Outputs the configuration.
54
+ def self.print_config
55
+ config.keys.sort_by(&:to_s).each do |key|
56
+ print "#{key}: #{config[key]}\n"
57
+ end
58
+ end
59
+
60
+ # Executes a config command from the UI.
61
+ def self.ui_set(key, value)
62
+ # Normalize values.
63
+ case value && value.downcase
64
+ when 'on', 'true'
65
+ value = true
66
+ when 'off', 'false'
67
+ value = false
68
+ end
69
+
70
+ # Process keys that include values.
71
+ prefix = key[0]
72
+
73
+ toggle = false
74
+ if [?+, ?-, ?^].include? prefix
75
+ key = key[1..-1]
76
+ case prefix
77
+ when ?+
78
+ value = true
79
+ when ?-
80
+ value = false
81
+ when ?^
82
+ toggle = true
83
+ end
84
+ self[key]
85
+ end
86
+
87
+ # Normalize keys.
88
+ key = key.downcase
89
+
90
+ # Execute the configuration change.
91
+ if toggle
92
+ self[key] = !self[key]
93
+ else
94
+ self[key] = value
95
+ end
96
+ print "#{key} set to #{value}\n"
97
+ end
98
+ end # module Bcpm::Config
99
+
100
+ end # namespace Bcpm