aboutsummaryrefslogtreecommitdiffstats
path: root/gem_helper.rb
blob: 66615752063fbddd5556a6bca1b655800e7a210a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env ruby
#--
# Copyright 2010 Per Øyvind Karlsen <peroyvind@mandriva.org>
# This program is free software. It may be redistributed and/or modified under
# the terms of the LGPL version 2.1 (or later).
#++

require 'optparse'

if ARGV[0] == "build" or ARGV[0] == "install"
  require 'yaml'
  require 'zlib'

  filter = nil
  opts = nil
  keepcache = false
  fixperms = false
  gemdir = nil
  dry_run = false
  files = []
  argv = ARGV[1..-1]
  # Push this into some environment variables as the modified classes doesn't
  # seem to be able to access our global variables.. </lameworkaround>
  ENV['GEM_MODE'] = ARGV[0]
  if ARGV[0] == "build"
    opts = OptionParser.new("#{$0} <--filter PATTERN>")
    opts.on("-f", "--filter PATTERN", "Filter pattern to use for gem files") do |val|
      filter = val
    end
    opts.on("-j", "--jobs JOBS", "Number  of  jobs to run simultaneously.") do |val|
      ENV['jobs'] = "-j"+val
    end
    opts.on("--dry-run", "Only show the files the gem will include") do
      ARGV.delete("--dry-run")
      dry_run = true
    end
  elsif ARGV[0] == "install"
    opts = OptionParser.new("#{$0} <--keep-cache>")
    opts.on("--keep-cache", "Don't delete gem copy from cache") do
      ARGV.delete("--keep-cache")
      keepcache = true
    end
    opts.on("--fix-permissions", "Force standard permissions for files installed") do
      ARGV.delete("--fix-permissions")
      fixperms = true
    end    
    opts.on("-i", "--install-dir GEMDIR", "Gem repository directory") do |val|
      gemdir = val
    end
  end
  while argv.length > 0
    begin
      opts.parse!(argv)
    rescue OptionParser::InvalidOption => e
      e.recover(argv)
    end
    argv.delete_at(0)
  end

  file_data = Zlib::GzipReader.open("metadata.gz")
  header = YAML::load(file_data)
  file_data.close()
  body = header.instance_variable_get :@ivars

  require 'rubygems'
  spec = Gem::Specification.from_yaml(YAML.dump(header))

  if ARGV[0] == "install"
    system("gem %s %s.gem" % [ARGV.join(' '), spec.full_name])
    if !keepcache
      require 'fileutils'
      FileUtils.rm_rf("%s/cache" % gemdir)
    end
    if fixperms
      chmod = "chmod u+r,u+w,g-w,g+r,o+r -R %s" % gemdir
      print "\nFixing permissions:\n\n%s\n" % chmod
      system("%s" % chmod)
      print "\n"
    end
  end

  if body['extensions'].size > 0
    require 'rubygems/ext'
    module Gem::Ext
      class Builder
	def self.make(dest_path, results)
	  make_program = ENV['make']
	  unless make_program then
	    make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
	  end
	  cmd = make_program
	  if ENV['GEM_MODE'] == "build"
  	    cmd += " %s" % ENV['jobs']
	  elsif ENV['GEM_MODE'] == "install"
	    cmd += " DESTDIR='%s' install" % ENV['DESTDIR']
	  end
	  results << cmd
	  results << `#{cmd} #{redirector}`

	  raise Gem::ExtensionBuildError, "make failed:\n\n#{results}" unless
	  $?.success?
	end
      end
    end

    require 'rubygems/installer'
    module Gem
      class Installer
      	def initialize(spec, options={})
	  @gem_dir = Dir.pwd
      	  @spec = spec
	end
      end
      class ConfigFile
	def really_verbose
	  true
	end
      end
    end

    unless dry_run
      Gem::Installer.new(spec).build_extensions
    else
      for ext in body['extensions']
	files.push(ext[0..ext.rindex("/")-1]+".so")
      end
    end

    body['extensions'].clear()
  end
  if ARGV[0] == "build"
    body['test_files'].clear()

    # We don't want ext/ in require_paths, it will only contain content for
    # building extensions which needs to be installed in sitearchdir anyways..
    idx = 0
    for i in 0..body['require_paths'].size()-1
      if body['require_paths'][idx].match("^ext(/|$)")
	body['require_paths'].delete_at(idx)
      else
	idx += 1
      end
    end

    # We'll get rid of all the files we don't really need to install
    idx = 0
    for i in 0..body['files'].size()-1
      if filter and body['files'][idx].match(filter)
	match = true
      else
	match = false
	for path in body['require_paths']
	  if body['files'][idx].match("^%s/" % path)
	    match = true
	  end
	end
      end
      if !match
	body['files'].delete_at(idx)
      else
	idx += 1
      end
    end

    spec = Gem::Specification.from_yaml(YAML.dump(header))
    unless dry_run
      Gem::Builder.new(spec).build
    else
      files.concat(spec.files)
      print "%s\n" % files.join("\n")
    end
  end
end