p4ruby 0.5.0

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.
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
+