Module: GemManagement

Includes:
ColorfulMessages
Included in:
Merb::RakeHelper
Defined in:
lib/merb-core/tasks/gem_management.rb

Instance Method Summary collapse

Methods included from ColorfulMessages

#error, #success, #warning

Instance Method Details

#ensure_bin_wrapper_for(gem_dir, bin_dir, *gems) ⇒ Object

Create a modified executable wrapper in the specified bin directory.



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/merb-core/tasks/gem_management.rb', line 185

def ensure_bin_wrapper_for(gem_dir, bin_dir, *gems)
  if bin_dir && File.directory?(bin_dir)
    gems.each do |gem|
      if gemspec_path = Dir[File.join(gem_dir, 'specifications', "#{gem}-*.gemspec")].last
        spec = Gem::Specification.load(gemspec_path)
        spec.executables.each do |exec|
          executable = File.join(bin_dir, exec)
          message "Writing executable wrapper #{executable}"
          File.open(executable, 'w', 0755) do |f|
            f.write(executable_wrapper(spec, exec))
          end
        end
      end
    end
  end
end

#install_gem(gem, options = {}) ⇒ Object

Install a gem - looks remotely and local gem cache; won’t process rdoc or ri options.



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
# File 'lib/merb-core/tasks/gem_management.rb', line 33

def install_gem(gem, options = {})
  from_cache = (options.key?(:cache) && options.delete(:cache))
  if from_cache
    install_gem_from_cache(gem, options)
  else
    version = options.delete(:version)
    Gem.configuration.update_sources = false

    update_source_index(options[:install_dir]) if options[:install_dir]

    installer = Gem::DependencyInstaller.new(options.merge(:user_install => false))
    exception = nil
    begin
      installer.install gem, version
    rescue Gem::InstallError => e
      exception = e
    rescue Gem::GemNotFoundException => e
      if from_cache && gem_file = find_gem_in_cache(gem, version)
        puts "Located #{gem} in gem cache..."
        installer.install gem_file
      else
        exception = e
      end
    rescue => e
      exception = e
    end
    if installer.installed_gems.empty? && exception
      error "Failed to install gem '#{gem} (#{version})' (#{exception.message})"
    end
    installer.installed_gems.each do |spec|
      success "Successfully installed #{spec.full_name}"
    end
    return !installer.installed_gems.empty?
  end
end

#install_gem_from_cache(gem, options = {}) ⇒ Object

Install a gem - looks in the system’s gem cache instead of remotely; won’t process rdoc or ri options.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/merb-core/tasks/gem_management.rb', line 71

def install_gem_from_cache(gem, options = {})
  version = options.delete(:version)
  Gem.configuration.update_sources = false
  installer = Gem::DependencyInstaller.new(options.merge(:user_install => false))
  exception = nil
  begin
    if gem_file = find_gem_in_cache(gem, version)
      puts "Located #{gem} in gem cache..."
      installer.install gem_file
    else
      raise Gem::InstallError, "Unknown gem #{gem}"
    end
  rescue Gem::InstallError => e
    exception = e
  end
  if installer.installed_gems.empty? && exception
    error "Failed to install gem '#{gem}' (#{e.message})"
  end
  installer.installed_gems.each do |spec|
    success "Successfully installed #{spec.full_name}"
  end
end

#install_gem_from_src(gem_src_dir, options = {}) ⇒ Object

Install a gem from source - builds and packages it first then installs.

Raises:

  • (Gem::InstallError)


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
# File 'lib/merb-core/tasks/gem_management.rb', line 95

def install_gem_from_src(gem_src_dir, options = {})
  if !File.directory?(gem_src_dir)
    raise "Missing rubygem source path: #{gem_src_dir}"
  end
  if options[:install_dir] && !File.directory?(options[:install_dir])
    raise "Missing rubygems path: #{options[:install_dir]}"
  end

  gem_name = File.basename(gem_src_dir)
  gem_pkg_dir = File.expand_path(File.join(gem_src_dir, 'pkg'))

  # We need to use local bin executables if available.
  thor = "#{Gem.ruby} -S #{which('thor')}"
  rake = "#{Gem.ruby} -S #{which('rake')}"

  # Handle pure Thor installation instead of Rake
  if File.exists?(File.join(gem_src_dir, 'Thorfile'))
    # Remove any existing packages.
    FileUtils.rm_rf(gem_pkg_dir) if File.directory?(gem_pkg_dir)
    # Create the package.
    FileUtils.cd(gem_src_dir) { system("#{thor} :package") }
    # Install the package using rubygems.
    if package = Dir[File.join(gem_pkg_dir, "#{gem_name}-*.gem")].last
      FileUtils.cd(File.dirname(package)) do
        install_gem(File.basename(package), options.dup)
        return true
      end
    else
      raise Gem::InstallError, "No package found for #{gem_name}"
    end
  # Handle elaborate installation through Rake
  else
    # Clean and regenerate any subgems for meta gems.
    Dir[File.join(gem_src_dir, '*', 'Rakefile')].each do |rakefile|
      FileUtils.cd(File.dirname(rakefile)) do 
        system("#{rake} clobber_package; #{rake} package")
      end
    end

    # Handle the main gem install.
    if File.exists?(File.join(gem_src_dir, 'Rakefile'))
      # Remove any existing packages.
      FileUtils.cd(gem_src_dir) { system("#{rake} clobber_package") }
      # Create the main gem pkg dir if it doesn't exist.
      FileUtils.mkdir_p(gem_pkg_dir) unless File.directory?(gem_pkg_dir)
      # Copy any subgems to the main gem pkg dir.
      Dir[File.join(gem_src_dir, '*', 'pkg', '*.gem')].each do |subgem_pkg|
        dest = File.join(gem_pkg_dir, File.basename(subgem_pkg))
        FileUtils.copy_entry(subgem_pkg, dest, true, false, true)          
      end

      # Finally generate the main package and install it; subgems
      # (dependencies) are local to the main package.
      FileUtils.cd(gem_src_dir) do         
        system("#{rake} package")
        FileUtils.cd(gem_pkg_dir) do
          if package = Dir[File.join(gem_pkg_dir, "#{gem_name}-*.gem")].last
            # If the (meta) gem has it's own package, install it.
            install_gem(File.basename(package), options.dup)
          else
            # Otherwise install each package seperately.
            Dir["*.gem"].each { |gem| install_gem(gem, options.dup) }
          end
        end
        return true
      end
    end
  end
  raise Gem::InstallError, "No Rakefile found for #{gem_name}"
end

#uninstall_gem(gem, options = {}) ⇒ Object

Uninstall a gem.



167
168
169
170
171
172
173
# File 'lib/merb-core/tasks/gem_management.rb', line 167

def uninstall_gem(gem, options = {})
  if options[:version] && !options[:version].is_a?(Gem::Requirement)
    options[:version] = Gem::Requirement.new ["= #{options[:version]}"]
  end
  update_source_index(options[:install_dir]) if options[:install_dir]
  Gem::Uninstaller.new(gem, options).uninstall
end

#which(executable) ⇒ Object

Use the local bin/* executables if available.



176
177
178
179
180
181
182
# File 'lib/merb-core/tasks/gem_management.rb', line 176

def which(executable)
  if File.executable?(exec = File.join(Dir.pwd, 'bin', executable))
    exec
  else
    executable
  end
end