p4ruby 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README +113 -0
  2. data/Rakefile +83 -0
  3. data/install.rb +385 -0
  4. data/p4ruby.gemspec +32 -0
  5. metadata +64 -0
data/README ADDED
@@ -0,0 +1,113 @@
1
+
2
+ = P4Ruby -- Ruby interface to the Perforce API
3
+
4
+ This is only an installer for the P4Ruby package by Perforce Software.
5
+
6
+ P4Ruby was recently included as an official package supported by
7
+ Perforce, with minor changes. Tony Smith's original P4Ruby public
8
+ depot is here
9
+ http://public.perforce.com/guest/tony_smith/perforce/API/Ruby/index.html
10
+ with documentation
11
+ http://public.perforce.com/guest/tony_smith/perforce/API/Ruby/main/doc/index.html.
12
+ Changes in the new package are described here
13
+ http://perforce.com/perforce/doc.081/user/p4rubynotes.txt.
14
+
15
+ <b>Note:</b> For Windows platforms, the only available Perforce API
16
+ libraries are Cygwin ones (as of version 2008.1). Therefore
17
+ Cygwin-ruby is currently required under Windows. After launching the
18
+ the Cygwin installer (http://cygwin.com), select the ruby package
19
+ along with g++ (in the Devel category).
20
+
21
+ Users may be interested in a simplified interface to Perforce at
22
+ http://perforce.rubyforge.org (shameless plug, sorry).
23
+
24
+ === Install
25
+
26
+ % gem install p4ruby
27
+
28
+ Or if you are installing from the regular (non-gem) package,
29
+
30
+ % ruby install.rb
31
+
32
+ This downloads P4Ruby and the Perforce API, compiles P4Ruby, and
33
+ installs it. Some options are available,
34
+
35
+ % ruby install.rb --help
36
+
37
+ Usage: ruby install.rb [options]
38
+ --version NN.N Version to download, e.g. 08.1. Default finds latest.
39
+ --list-versions List available versions.
40
+ --platform PLATFORM Perforce-named platform to download. Default guesses.
41
+ --list-platforms List available platforms for the given version.
42
+ --gem Gem configuration (for the gem installer).
43
+ --uninstall Uninstall.
44
+
45
+ === Note
46
+
47
+ If you are on a case-sensitive filesystem, be aware that 'P4' must be
48
+ capitalized in the <em>require</em> line,
49
+
50
+ require 'P4'
51
+
52
+ === Download (this installer only)
53
+
54
+ * http://rubyforge.org/frs/?group_id=6957
55
+
56
+ === Repository (this installer only)
57
+
58
+ * http://github.com/quix/p4ruby
59
+
60
+ === Credits
61
+
62
+ ==== P4Ruby
63
+
64
+ Copyright (c) 1997-2007, Perforce Software, Inc. All rights reserved.
65
+
66
+ Redistribution and use in source and binary forms, with or without
67
+ modification, are permitted provided that the following conditions
68
+ are met:
69
+
70
+ 1. Redistributions of source code must retain the above copyright
71
+ notice, this list of conditions and the following disclaimer.
72
+
73
+ 2. Redistributions in binary form must reproduce the above copyright
74
+ notice, this list of conditions and the following disclaimer in the
75
+ documentation and/or other materials provided with the distribution.
76
+
77
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
78
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
79
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
80
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE
81
+ SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
82
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
83
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
84
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
85
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
86
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
87
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88
+
89
+ ==== Installer and Gem
90
+
91
+ This ruby package (install.rb and associated files) was written by
92
+ James M. Lawrence, Copyright (c) 2008 ImaginEngine, Inc. Distributed
93
+ under the MIT license.
94
+
95
+ Permission is hereby granted, free of charge, to any person obtaining
96
+ a copy of this software and associated documentation files (the
97
+ "Software"), to deal in the Software without restriction, including
98
+ without limitation the rights to use, copy, modify, merge, publish,
99
+ distribute, sublicense, and/or sell copies of the Software, and to
100
+ permit persons to whom the Software is furnished to do so, subject to
101
+ the following conditions:
102
+
103
+ The above copyright notice and this permission notice shall be
104
+ included in all copies or substantial portions of the Software.
105
+
106
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
107
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
108
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
109
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
110
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
111
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
112
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
113
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,83 @@
1
+
2
+ require 'rake/gempackagetask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/contrib/rubyforgepublisher'
5
+
6
+ require 'rbconfig'
7
+
8
+ gemspec = eval(File.read("p4ruby.gemspec"))
9
+ installer = './install.rb'
10
+ readme = "README"
11
+
12
+ ruby = File.join(
13
+ Config::CONFIG["bindir"],
14
+ Config::CONFIG["RUBY_INSTALL_NAME"])
15
+
16
+ #
17
+ # default task compiles for the gem
18
+ #
19
+ task :default do
20
+ sh(ruby, installer, "--gem")
21
+ end
22
+
23
+ task :clean => :clobber do
24
+ rm_rf ["work", "lib/P4.rb", "ext", "html"]
25
+ end
26
+
27
+ task :update_docs do
28
+ help = "--help"
29
+ command = "ruby #{File.basename(installer)} #{help}"
30
+ output = `#{ruby} #{installer} #{help}`
31
+
32
+ # insert help output into README
33
+ replace_file(readme) { |contents|
34
+ contents.sub(%r!#{command}.*?==!m) {
35
+ command + "\n\n " +
36
+ output + "\n=="
37
+ }
38
+ }
39
+ end
40
+
41
+ task :doc => :update_docs
42
+ task :doc => :rdoc
43
+
44
+ task :package => [:clean, :doc]
45
+ task :gem => :clean
46
+
47
+ Rake::RDocTask.new { |t|
48
+ t.main = readme
49
+ t.rdoc_files.include([readme])
50
+ t.rdoc_dir = "html"
51
+ t.title = "P4Ruby: #{gemspec.summary}"
52
+ }
53
+
54
+ Rake::GemPackageTask.new(gemspec) { |t|
55
+ t.need_tar = true
56
+ }
57
+
58
+ task :publish => :doc do
59
+ Rake::RubyForgePublisher.new('p4ruby', 'quix').upload
60
+ end
61
+
62
+ task :release => [:package, :publish]
63
+
64
+ ##################################################
65
+ # util
66
+
67
+ unless respond_to? :tap
68
+ module Kernel
69
+ def tap
70
+ yield self
71
+ self
72
+ end
73
+ end
74
+ end
75
+
76
+ def replace_file(file)
77
+ old_contents = File.read(file)
78
+ yield(old_contents).tap { |new_contents|
79
+ File.open(file, "w") { |output|
80
+ output.print(new_contents)
81
+ }
82
+ }
83
+ end
data/install.rb ADDED
@@ -0,0 +1,385 @@
1
+ #
2
+ # Author: James M. Lawrence <quixoticsycophant@gmail.com>.
3
+ #
4
+
5
+ require 'net/ftp'
6
+ require 'rbconfig'
7
+ require 'ostruct'
8
+ require 'fileutils'
9
+ require 'optparse'
10
+
11
+ class Installer
12
+ include FileUtils
13
+
14
+ def parse_command_line
15
+ OptionParser.new("Usage: ruby install.rb [options]", 24, "") { |parser|
16
+ parser.on("--version NN.N",
17
+ "Version to download, e.g. 08.1. Default finds latest.") {
18
+ |version|
19
+ @s.version = version
20
+ }
21
+ parser.on("--list-versions", "List available versions.") {
22
+ @s.list_versions = true
23
+ }
24
+ parser.on(
25
+ "--platform PLATFORM",
26
+ "Perforce-named platform to download. Default guesses.") {
27
+ |platform|
28
+ @s.platform = platform
29
+ }
30
+ parser.on("--list-platforms",
31
+ "List available platforms for the given version.") {
32
+ @s.list_platforms = true
33
+ }
34
+ parser.on("--gem", "Gem configuration (for the gem installer).") {
35
+ @s.gem = true
36
+ }
37
+ parser.on("--uninstall", "Uninstall.") {
38
+ @s.uninstall = true
39
+ }
40
+ parser.parse(ARGV)
41
+ }
42
+ end
43
+
44
+ def run
45
+ @s = LazyStruct.new
46
+ parse_command_line
47
+ config
48
+ if @s.uninstall
49
+ uninstall
50
+ elsif @s.list_platforms
51
+ list_platforms
52
+ elsif @s.list_versions
53
+ list_versions
54
+ elsif @s.platform
55
+ rm_rf(@s.work_dir)
56
+ fetch
57
+ build
58
+ install
59
+ else
60
+ platform_fail
61
+ end
62
+ end
63
+
64
+ def config
65
+ @s.server = "ftp.perforce.com"
66
+ @s.server_top_dir = "perforce"
67
+
68
+ @s.work_dir = "work"
69
+ @s.distfiles_dir = "#{@s.work_dir}/distfiles"
70
+ @s.build_dir = "#{@s.work_dir}/build"
71
+
72
+ @s.p4api = LazyStruct.new.tap { |t| t.file = "p4api.tgz" }
73
+ @s.p4ruby = LazyStruct.new.tap { |t| t.file = "p4ruby.tgz" }
74
+ @s.specs = [ @s.p4ruby, @s.p4api ]
75
+ @s.specs.each { |spec|
76
+ spec.local = "#{@s.distfiles_dir}/#{spec.file}"
77
+ }
78
+
79
+ unless @s.platform
80
+ @s.attribute(:platform) {
81
+ guess_platform
82
+ }
83
+ end
84
+
85
+ unless @s.version
86
+ @s.attribute(:version) {
87
+ latest_version
88
+ }
89
+ end
90
+
91
+ @s.attribute(:version_dir) {
92
+ "#{@s.server_top_dir}/r#{@s.version}"
93
+ }
94
+ @s.p4api.attribute(:remote) {
95
+ "#{@s.version_dir}/bin.#{@s.platform}/#{@s.p4api.file}"
96
+ }
97
+ @s.p4ruby.attribute(:remote) {
98
+ "#{@s.version_dir}/tools/#{@s.p4ruby.file}"
99
+ }
100
+ @s.attribute(:ftp) {
101
+ Net::FTP.new(@s.server).tap { |t| t.passive = true ; t.login }
102
+ }
103
+ end
104
+
105
+ def guess_platform
106
+ case RUBY_PLATFORM
107
+ when %r!cygwin!i
108
+ "cygwinx86"
109
+ when %r!darwin!i
110
+ case RUBY_PLATFORM
111
+ when %r!ppc!i
112
+ "darwin80ppc"
113
+ when %r!64!
114
+ "darwin80x86_64"
115
+ else
116
+ "darwin80x86"
117
+ end
118
+ when %r!linux!i
119
+ case RUBY_PLATFORM
120
+ when %r!2\.6!
121
+ case RUBY_PLATFORM
122
+ when %r!ia!i
123
+ "linux26xia64"
124
+ when %r!64!
125
+ "linux26x86_64"
126
+ else
127
+ "linux26x86"
128
+ end
129
+ else
130
+ "linux24x86"
131
+ end
132
+ when %r!freebsd!i
133
+ case RUBY_PLATFORM
134
+ when %r!5\.4!
135
+ case RUBY_PLATFORM
136
+ when %r!64!
137
+ "freebsd54x86_64"
138
+ else
139
+ "freebsd54x86"
140
+ end
141
+ else
142
+ case RUBY_PLATFORM
143
+ when %r!64!
144
+ "freebsd60x86_64"
145
+ else
146
+ "freebsd60x86"
147
+ end
148
+ end
149
+ else
150
+ nil
151
+ end
152
+ end
153
+
154
+ def platform_fail
155
+ @s.version = "<VERSION>"
156
+ @s.platform = "<PLATFORM>"
157
+ message = %Q{
158
+ Auto-fetch not yet handled for this platform. Run:
159
+
160
+ \truby install.rb --list-platforms
161
+
162
+ to see the available platforms, then run
163
+
164
+ \truby install.rb --platform PLATFORM
165
+
166
+ with your platform.
167
+
168
+ If all of the above fails, manually fetch
169
+
170
+ \tftp://#{@s.server}/#{@s.p4api.remote}
171
+
172
+ Copy it to #{@s.p4api.local} and run install.rb again.
173
+ }.gsub(%r!^ +(?=\S)!, "")
174
+
175
+ mkdir_p(@s.distfiles_dir)
176
+ puts message
177
+ end
178
+
179
+ def sys(*args)
180
+ system(*args).tap { |result|
181
+ unless result
182
+ raise "system() failed: #{args.join(" ")}"
183
+ end
184
+ }
185
+ end
186
+
187
+ def unpack(distfile, target_dir)
188
+ sys("tar", "zxvf", distfile, "-C", target_dir)
189
+ end
190
+
191
+ def fetch
192
+ @s.specs.each { |spec|
193
+ mkdir_p(File.dirname(spec.local))
194
+ puts "downloading ftp://#{@s.server}/#{spec.remote} ..."
195
+ @s.ftp.getbinaryfile(spec.remote, spec.local)
196
+ }
197
+ end
198
+
199
+ def remote_files_matching(dir, regex)
200
+ @s.ftp.ls(dir).map { |entry|
201
+ if match = entry.match(regex)
202
+ yield match
203
+ else
204
+ nil
205
+ end
206
+ }.reject { |entry|
207
+ entry.nil?
208
+ }
209
+ end
210
+
211
+ def platforms
212
+ remote_files_matching(@s.version_dir, %r!bin\.(\w+)!) { |match|
213
+ match.captures.first
214
+ }.reject { |platform|
215
+ platform =~ %r!java!
216
+ }.sort
217
+ end
218
+
219
+ def versions
220
+ remote_files_matching(@s.server_top_dir, %r!r([0-8]\d\.\d)!) { |match|
221
+ match.captures.first
222
+ }.sort
223
+ end
224
+
225
+ def list_platforms
226
+ platforms.each { |platform|
227
+ puts platform
228
+ }
229
+ end
230
+
231
+ def list_versions
232
+ versions.each { |version|
233
+ puts version
234
+ }
235
+ end
236
+
237
+ def latest_version
238
+ versions.last
239
+ end
240
+
241
+ def fix_makefile
242
+ replace_file("Makefile") { |contents|
243
+ contents.sub(%r!^LIBS = .*?$!) { |match|
244
+ match + " -lruby"
245
+ }
246
+ }
247
+ end
248
+
249
+ def build
250
+ ruby = File.join(
251
+ Config::CONFIG["bindir"],
252
+ Config::CONFIG["RUBY_INSTALL_NAME"])
253
+
254
+ mkdir_p(@s.build_dir)
255
+
256
+ @s.specs.each { |spec|
257
+ unpack(spec.local, @s.build_dir)
258
+ }
259
+
260
+ Dir.chdir(@s.build_dir) {
261
+ api_dir = Dir["p4api*"].last
262
+ p4ruby_dir = Dir["p4ruby*"].last
263
+ Dir.chdir(p4ruby_dir) {
264
+ sys(ruby, "p4conf.rb", "--apidir", "../#{api_dir}")
265
+ fix_makefile
266
+ make
267
+ }
268
+ @s.p4ruby_build_dir = "#{@s.build_dir}/#{p4ruby_dir}"
269
+ }
270
+ end
271
+
272
+ def make(*args)
273
+ exe =
274
+ if RUBY_PLATFORM =~ %r!mswin!i
275
+ "nmake"
276
+ else
277
+ "make"
278
+ end
279
+ sys(exe, *args)
280
+ end
281
+
282
+ def install
283
+ if @s.gem
284
+ rb_file = "lib/P4.rb"
285
+ rm_f(rb_file)
286
+ mkdir_p(File.dirname(rb_file))
287
+ cp("#{@s.p4ruby_build_dir}/#{rb_file}", rb_file)
288
+
289
+ dlext = Config::CONFIG["DLEXT"]
290
+ so_file = "ext/P4.#{dlext}"
291
+ rm_f(so_file)
292
+ mkdir_p(File.dirname(so_file))
293
+ cp("#{@s.p4ruby_build_dir}/#{File.basename(so_file)}", so_file)
294
+ else
295
+ Dir.chdir(@s.p4ruby_build_dir) {
296
+ make "install"
297
+ }
298
+ end
299
+ end
300
+
301
+ def installed_p4ruby_files
302
+ [ File.join(Config::CONFIG["sitelibdir"], "P4.rb") ] +
303
+ Dir[File.join(Config::CONFIG["sitearchdir"], "P4.*")]
304
+ end
305
+
306
+ def uninstall
307
+ installed_p4ruby_files.each { |file|
308
+ if File.exist? file
309
+ puts "delete #{file}"
310
+ rm_f(file)
311
+ end
312
+ }
313
+ end
314
+ end
315
+
316
+ # version < 1.8.7 compatibility
317
+ module Kernel
318
+ unless respond_to? :tap
319
+ def tap
320
+ yield self
321
+ self
322
+ end
323
+ end
324
+ end
325
+
326
+ #
327
+ # An OpenStruct with optional lazy-evaluated fields.
328
+ #
329
+ class LazyStruct < OpenStruct
330
+ #
331
+ # For mixing into an existing OpenStruct instance singleton class.
332
+ #
333
+ module Mixin
334
+ #
335
+ # &block is evaluated when this attribute is requested. The
336
+ # same result is returned for subsquent calls, until the field
337
+ # is assigned a different value.
338
+ #
339
+ def attribute(reader, &block)
340
+ singleton = (class << self ; self ; end)
341
+ singleton.instance_eval {
342
+ #
343
+ # Define a special reader method in the singleton class.
344
+ #
345
+ define_method(reader) {
346
+ block.call.tap { |value|
347
+ #
348
+ # The value has been computed. Replace this method with a
349
+ # one-liner giving the value.
350
+ #
351
+ singleton.instance_eval {
352
+ remove_method(reader)
353
+ define_method(reader) { value }
354
+ }
355
+ }
356
+ }
357
+
358
+ #
359
+ # Revert to the old OpenStruct behavior when the writer is called.
360
+ #
361
+ writer = "#{reader}=".to_sym
362
+ define_method(writer) { |value|
363
+ singleton.instance_eval {
364
+ remove_method(reader)
365
+ remove_method(writer)
366
+ }
367
+ method_missing(writer, value)
368
+ }
369
+ }
370
+ end
371
+ end
372
+
373
+ include Mixin
374
+ end
375
+
376
+ def replace_file(file)
377
+ old_contents = File.read(file)
378
+ yield(old_contents).tap { |new_contents|
379
+ File.open(file, "w") { |output|
380
+ output.print(new_contents)
381
+ }
382
+ }
383
+ end
384
+
385
+ Installer.new.run
data/p4ruby.gemspec ADDED
@@ -0,0 +1,32 @@
1
+
2
+ Gem::Specification.new { |t|
3
+ t.name = "p4ruby"
4
+ t.version = "0.5.0"
5
+ t.summary = "Ruby interface to the Perforce API"
6
+ t.author = "Perforce Software (ruby gem by James M. Lawrence)"
7
+ t.email = "quixoticsycophant@gmail.com"
8
+ t.homepage = "p4ruby.rubyforge.org"
9
+ t.rubyforge_project = "p4ruby"
10
+ t.extensions << "Rakefile"
11
+ t.require_paths << "ext"
12
+
13
+ t.files = %w{
14
+ README
15
+ Rakefile
16
+ install.rb
17
+ p4ruby.gemspec
18
+ }
19
+
20
+ rdoc_exclude = %w{
21
+ P4.rb
22
+ install\.rb
23
+ }
24
+ t.has_rdoc = true
25
+ t.extra_rdoc_files = ["README"]
26
+ t.rdoc_options += ["--title", "P4Ruby: #{t.summary}"] +
27
+ %w{--main README} +
28
+ rdoc_exclude.inject(Array.new) { |acc, pattern|
29
+ acc + ["--exclude", pattern]
30
+ }
31
+ }
32
+
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: p4ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Perforce Software (ruby gem by James M. Lawrence)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-09-07 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: quixoticsycophant@gmail.com
18
+ executables: []
19
+
20
+ extensions:
21
+ - Rakefile
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - README
26
+ - Rakefile
27
+ - install.rb
28
+ - p4ruby.gemspec
29
+ has_rdoc: true
30
+ homepage: p4ruby.rubyforge.org
31
+ post_install_message:
32
+ rdoc_options:
33
+ - --title
34
+ - "P4Ruby: Ruby interface to the Perforce API"
35
+ - --main
36
+ - README
37
+ - --exclude
38
+ - P4.rb
39
+ - --exclude
40
+ - install\.rb
41
+ require_paths:
42
+ - lib
43
+ - ext
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project: p4ruby
59
+ rubygems_version: 1.2.0
60
+ signing_key:
61
+ specification_version: 2
62
+ summary: Ruby interface to the Perforce API
63
+ test_files: []
64
+