jwhitmire-geminstaller 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +1 -0
- data/History.txt +82 -0
- data/LICENSE +21 -0
- data/Manifest.txt +78 -0
- data/README.txt +77 -0
- data/Rakefile +210 -0
- data/TODO.txt +138 -0
- data/authors +2 -0
- data/bin/geminstaller +30 -0
- data/cruise_config.rb +23 -0
- data/focused_spec.sh +2 -0
- data/focused_spec_debug.sh +2 -0
- data/geminstaller.yml +47 -0
- data/lib/geminstaller/application.rb +112 -0
- data/lib/geminstaller/arg_parser.rb +177 -0
- data/lib/geminstaller/autogem.rb +48 -0
- data/lib/geminstaller/backward_compatibility.rb +17 -0
- data/lib/geminstaller/bundler_exporter.rb +19 -0
- data/lib/geminstaller/config.rb +68 -0
- data/lib/geminstaller/config_builder.rb +65 -0
- data/lib/geminstaller/enhanced_stream_ui.rb +71 -0
- data/lib/geminstaller/exact_match_list_command.rb +16 -0
- data/lib/geminstaller/file_reader.rb +31 -0
- data/lib/geminstaller/gem_arg_processor.rb +44 -0
- data/lib/geminstaller/gem_command_manager.rb +71 -0
- data/lib/geminstaller/gem_interaction_handler.rb +41 -0
- data/lib/geminstaller/gem_list_checker.rb +55 -0
- data/lib/geminstaller/gem_runner_proxy.rb +65 -0
- data/lib/geminstaller/gem_source_index_proxy.rb +21 -0
- data/lib/geminstaller/gem_spec_manager.rb +53 -0
- data/lib/geminstaller/geminstaller_access_error.rb +4 -0
- data/lib/geminstaller/geminstaller_error.rb +13 -0
- data/lib/geminstaller/hoe_extensions.rb +9 -0
- data/lib/geminstaller/install_processor.rb +71 -0
- data/lib/geminstaller/missing_dependency_finder.rb +46 -0
- data/lib/geminstaller/missing_file_error.rb +4 -0
- data/lib/geminstaller/noninteractive_chooser.rb +114 -0
- data/lib/geminstaller/outdated_gem_finder.rb +46 -0
- data/lib/geminstaller/output_filter.rb +49 -0
- data/lib/geminstaller/output_listener.rb +33 -0
- data/lib/geminstaller/output_observer.rb +36 -0
- data/lib/geminstaller/output_proxy.rb +36 -0
- data/lib/geminstaller/registry.rb +137 -0
- data/lib/geminstaller/requires.rb +83 -0
- data/lib/geminstaller/rogue_gem_finder.rb +195 -0
- data/lib/geminstaller/ruby_gem.rb +58 -0
- data/lib/geminstaller/rubygems_exit.rb +5 -0
- data/lib/geminstaller/rubygems_extensions.rb +9 -0
- data/lib/geminstaller/rubygems_version_checker.rb +21 -0
- data/lib/geminstaller/rubygems_version_warnings.rb +38 -0
- data/lib/geminstaller/source_index_search_adapter.rb +41 -0
- data/lib/geminstaller/unauthorized_dependency_prompt_error.rb +4 -0
- data/lib/geminstaller/unexpected_prompt_error.rb +4 -0
- data/lib/geminstaller/valid_platform_selector.rb +49 -0
- data/lib/geminstaller/version_specifier.rb +24 -0
- data/lib/geminstaller/yaml_loader.rb +22 -0
- data/lib/geminstaller.rb +103 -0
- data/lib/geminstaller_rails_preinitializer.rb +54 -0
- data/start_local_gem_server.sh +1 -0
- data/website/config.yaml +11 -0
- data/website/src/analytics.page +6 -0
- data/website/src/code/ci.virtual +5 -0
- data/website/src/code/coverage/index.virtual +5 -0
- data/website/src/code/index.page +92 -0
- data/website/src/code/rdoc/index.virtual +6 -0
- data/website/src/community/index.page +14 -0
- data/website/src/community/links.page +11 -0
- data/website/src/community/rubyforge.virtual +4 -0
- data/website/src/default.css +175 -0
- data/website/src/default.template +42 -0
- data/website/src/documentation/documentation.page +477 -0
- data/website/src/documentation/index.page +53 -0
- data/website/src/documentation/tutorials.page +337 -0
- data/website/src/download.page +12 -0
- data/website/src/faq.page +36 -0
- data/website/src/index.page +103 -0
- data/website/src/metainfo +54 -0
- data/website/src/webgen.css +112 -0
- metadata +139 -0
data/cruise_config.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Project-specific configuration for CruiseControl.rb
|
2
|
+
require 'fileutils'
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
Project.configure do |project|
|
6
|
+
triggers = []
|
7
|
+
if File.exists?(File.expand_path(File.dirname(project.path)) + '/../../RubyGems')
|
8
|
+
triggers << :RubyGems
|
9
|
+
end
|
10
|
+
if File.exists?(File.expand_path(File.dirname(project.path)) + '/../../dummyrepo')
|
11
|
+
triggers << :dummyrepo
|
12
|
+
end
|
13
|
+
project.triggered_by *triggers
|
14
|
+
project.email_notifier.emails = ['thewoolleyman@gmail.com'] if Socket.gethostname =~ /(thewoolleyweb.com|ci.pivotallabs.com)/
|
15
|
+
if project.name =~ /rubygems[_-](.*)$/ # geminstaller_using_rubygems_0-9-4
|
16
|
+
rubygems_version = $1
|
17
|
+
rubygems_version.gsub!('-','.')
|
18
|
+
ENV['RUBYGEMS_VERSION'] = rubygems_version
|
19
|
+
end
|
20
|
+
if project.name =~ /smoketest/i # smoketest project
|
21
|
+
project.rake_task = project.name
|
22
|
+
end
|
23
|
+
end
|
data/focused_spec.sh
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
# warning - experimental
|
2
|
+
ruby -I spec/lib/ruby-debug-0.10.0/cli:spec/lib/ruby-debug-0.10.0/bin:spec/lib/ruby-debug-base-0.10.0/lib:spec/lib/ruby-debug-0.10.0/bin/rdebug:spec/lib/rspec-1.1.1/lib spec/lib/ruby-debug-0.10.0/bin/rdebug spec/lib/rspec-1.1.1/bin/spec -- $1 --line=$2
|
data/geminstaller.yml
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
# GemInstaller config file which specifies the actual build, test, and doc dependencies for GemInstaller itself.
|
3
|
+
defaults:
|
4
|
+
install_options: --no-ri --no-rdoc
|
5
|
+
#fix_dependencies: true
|
6
|
+
gems:
|
7
|
+
- name: diff-lcs
|
8
|
+
version: '>= 1.1.2'
|
9
|
+
- name: hoe
|
10
|
+
version: '>= 2.3.2'
|
11
|
+
- name: hoe-seattlerb
|
12
|
+
version: '>= 1.2.0'
|
13
|
+
- name: open4
|
14
|
+
version: '>= 0.9.6'
|
15
|
+
- name: rake
|
16
|
+
version: '>= 0.7.1'
|
17
|
+
- name: rcov
|
18
|
+
version: '>= 0.7.0.1'
|
19
|
+
platform: <%= RUBY_PLATFORM =~ /mswin/ ? 'mswin32' : 'ruby'%>
|
20
|
+
- name: RedCloth
|
21
|
+
# version: '= 3.0.4'
|
22
|
+
version: '= 4.0.4'
|
23
|
+
- name: rspec
|
24
|
+
version: '>= 1.2.8'
|
25
|
+
# install dev dependencies for rspec, or else regression tests on older versions of rubygems with the dev dependencies
|
26
|
+
# bug (1.0, 1.1) fail - and currently Hoe swallows Rspec load error silently
|
27
|
+
install_options: --no-ri --no-rdoc --development
|
28
|
+
- name: cmdparse
|
29
|
+
version: '>= 2.0.2'
|
30
|
+
- name: ruby-debug
|
31
|
+
version: '>= 0.9.3'
|
32
|
+
- name: webgen
|
33
|
+
version: '= 0.5.5'
|
34
|
+
# - name: gettalong-webgen
|
35
|
+
# version: '>= 0.5.5.20081001'
|
36
|
+
<% if RUBY_PLATFORM =~ /mswin/ %>
|
37
|
+
- name: win32-process
|
38
|
+
version: '>= 0.5.5'
|
39
|
+
platform: 'mswin32'
|
40
|
+
- name: win32console
|
41
|
+
version: '>= 1.0.8'
|
42
|
+
platform: 'mswin32'
|
43
|
+
- name: win32-open3
|
44
|
+
version: '>= 0.2.5'
|
45
|
+
platform: 'mswin32'
|
46
|
+
<% end %>
|
47
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class Application
|
3
|
+
# we have accessors instead of just writers so that we can ensure it is assembled correctly in the dependency injector test
|
4
|
+
attr_accessor :config_builder, :install_processor, :output_filter, :arg_parser, :args, :options, :rogue_gem_finder, :bundler_exporter, :outdated_gem_finder
|
5
|
+
attr_writer :autogem
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@args = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def install
|
12
|
+
begin
|
13
|
+
exit_flag_and_return_code = handle_args
|
14
|
+
if exit_flag_and_return_code[0]
|
15
|
+
return exit_flag_and_return_code[1]
|
16
|
+
end
|
17
|
+
if @options[:bundler_export]
|
18
|
+
@bundler_exporter.output(@config_builder.build_config)
|
19
|
+
return 0
|
20
|
+
end
|
21
|
+
gems = create_gems_from_config
|
22
|
+
if @options[:print_rogue_gems]
|
23
|
+
@rogue_gem_finder.print_rogue_gems(gems, @config_builder.config_file_paths_array)
|
24
|
+
return 0
|
25
|
+
elsif @options[:print_outdated_gems]
|
26
|
+
@outdated_gem_finder.print_outdated_gems(gems, @config_builder.config_file_paths_array)
|
27
|
+
return 0
|
28
|
+
end
|
29
|
+
if gems.size == 0
|
30
|
+
message = "No gems found in config file. Try the --print-rogue-gems option to help populate your config file."
|
31
|
+
@output_filter.geminstaller_output(:info,message + "\n")
|
32
|
+
else
|
33
|
+
process_gems(gems)
|
34
|
+
end
|
35
|
+
rescue Exception => e
|
36
|
+
handle_exception(e)
|
37
|
+
return 1
|
38
|
+
end
|
39
|
+
return 0
|
40
|
+
end
|
41
|
+
|
42
|
+
def autogem
|
43
|
+
begin
|
44
|
+
# TODO: do some validation that args only contains --config option, especially not print_rogue_gems since this would mask a missing file error
|
45
|
+
exit_flag_and_return_code = handle_args
|
46
|
+
if exit_flag_and_return_code[0]
|
47
|
+
return exit_flag_and_return_code[1]
|
48
|
+
end
|
49
|
+
gems = create_gems_from_config
|
50
|
+
message = "GemInstaller is automatically requiring gems: "
|
51
|
+
print_startup_message(gems, message)
|
52
|
+
return @autogem.autogem(gems)
|
53
|
+
rescue Exception => e
|
54
|
+
handle_exception(e)
|
55
|
+
return 1
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def handle_exception(e)
|
60
|
+
message = e.message
|
61
|
+
message += "\n"
|
62
|
+
@output_filter.geminstaller_output(:error,message)
|
63
|
+
backtrace_as_string = e.backtrace.join("\n")
|
64
|
+
@output_filter.geminstaller_output(:debug,"#{backtrace_as_string}\n")
|
65
|
+
raise e if @options[:exceptions]
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_gems_from_config
|
69
|
+
begin
|
70
|
+
config = @config_builder.build_config
|
71
|
+
rescue GemInstaller::MissingFileError => e
|
72
|
+
# if user wants to print rogue gems and they have no config at all, don't show an error
|
73
|
+
return [] if @options[:print_rogue_gems] && (@config_builder.config_file_paths_array.size == 1)
|
74
|
+
missing_path = e.message
|
75
|
+
error_message = "Error: A GemInstaller config file is missing at #{missing_path}. You can generate one with the --print-rogue-gems option. See the GemInstaller docs at http://geminstaller.rubyforge.org for more info."
|
76
|
+
raise GemInstaller::MissingFileError.new(error_message)
|
77
|
+
end
|
78
|
+
config.gems
|
79
|
+
end
|
80
|
+
|
81
|
+
def process_gems(gems)
|
82
|
+
message = "GemInstaller is verifying gem installation: "
|
83
|
+
print_startup_message(gems, message)
|
84
|
+
@install_processor.process(gems)
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_args
|
88
|
+
return_code = @arg_parser.parse(@args)
|
89
|
+
arg_parser_output = @arg_parser.output
|
90
|
+
if (arg_parser_output && arg_parser_output != '')
|
91
|
+
if return_code == 0
|
92
|
+
@output_filter.geminstaller_output(:info,arg_parser_output)
|
93
|
+
else
|
94
|
+
@output_filter.geminstaller_output(:error,arg_parser_output)
|
95
|
+
end
|
96
|
+
return [true, return_code]
|
97
|
+
end
|
98
|
+
config_file_paths = @options[:config_paths]
|
99
|
+
@config_builder.config_file_paths = config_file_paths if config_file_paths
|
100
|
+
return [false, 0]
|
101
|
+
end
|
102
|
+
|
103
|
+
def print_startup_message(gems, message)
|
104
|
+
gems.each_with_index do |gem, index|
|
105
|
+
gem_info = "#{gem.name} #{gem.version}"
|
106
|
+
message += gem_info
|
107
|
+
message += ", " if index + 1 < gems.size
|
108
|
+
end
|
109
|
+
@output_filter.geminstaller_output(:debug,message + "\n")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class ArgParser
|
3
|
+
attr_reader :output
|
4
|
+
attr_writer :options
|
5
|
+
|
6
|
+
VALID_GEMINSTALLER_OUTPUT_FLAGS = [:none,:error,:install,:info,:commandecho,:debug,:all]
|
7
|
+
VALID_RUBYGEMS_OUTPUT_FLAGS = [:none,:stdout,:stderr,:all]
|
8
|
+
|
9
|
+
def parse(args = [])
|
10
|
+
raise GemInstaller::GemInstallerError.new("Args must be passed as an array.") unless args.nil? or args.respond_to? :shift
|
11
|
+
args = ARGV if args.nil? || args == []
|
12
|
+
# check to see if args is an array of (nothing but) gems here... if so, set args as [@options[:gems] and return
|
13
|
+
|
14
|
+
raise GemInstaller::GemInstallerError.new("Error: An array of options to be populated must be injected prior to calling GemInstaller::ArgParser.parse") unless @options
|
15
|
+
@options[:exceptions] = false
|
16
|
+
@options[:redirect_stderr_to_stdout] = false
|
17
|
+
@options[:silent] = false
|
18
|
+
@options[:sudo] = false
|
19
|
+
@options[:geminstaller_output] = [:error,:install,:info]
|
20
|
+
@options[:rubygems_output] = [:stderr]
|
21
|
+
@output = ""
|
22
|
+
@unparsed_geminstaller_output_flags = nil
|
23
|
+
@unparsed_rubygems_output_flags = nil
|
24
|
+
opts = OptionParser.new do |opts|
|
25
|
+
opts.banner = "Usage: geminstaller [options]"
|
26
|
+
|
27
|
+
opts.separator ""
|
28
|
+
|
29
|
+
config_msg = "Comma-delimited path(s) to GemInstaller config file(s)."
|
30
|
+
exceptions_msg = "Raise any exceptions, rather than just printing them and exiting\n" +
|
31
|
+
" with a non-zero return code."
|
32
|
+
redirect_stderr_to_stdout_msg = "Redirect all STDERR output to STDOUT. Useful to get all output when\n" +
|
33
|
+
" invoking GemInstaller via system()."
|
34
|
+
geminstaller_output_msg = "Comma-delimited list of output types to show from GemInstaller.\n" +
|
35
|
+
" Examples:\n" +
|
36
|
+
" --gall\n" +
|
37
|
+
" --geminstaller-output=error,install,commandecho\n" +
|
38
|
+
" Default: error,install,info\n" +
|
39
|
+
" Valid types:\n" +
|
40
|
+
" - none: print only fatal errors\n" +
|
41
|
+
" - error: print error messages\n" +
|
42
|
+
" - install: print install messages\n" +
|
43
|
+
" - info: print informational messages\n" +
|
44
|
+
" - commandecho: print rubygems commands as they are invoked\n" +
|
45
|
+
" - debug: print debug messages\n" +
|
46
|
+
" - all: print all messages"
|
47
|
+
help_msg = "Show this message."
|
48
|
+
print_outdated_gems_msg = "Print a report of all locally installed gems which have a later\n" +
|
49
|
+
" version installed than is specified in the geminstaller config file."
|
50
|
+
print_rogue_gems_msg = "Print a report of all locally installed gems which are not specified\n" +
|
51
|
+
" in the geminstaller config file."
|
52
|
+
bundler_export_msg = "Export a Bundler manifest Gemfile based on the geminstaller config"
|
53
|
+
rubygems_output_msg = "Comma-delimited list of output types to show from internal:\n" +
|
54
|
+
" RubyGems command invocation.\n" +
|
55
|
+
" Examples:\n" +
|
56
|
+
" --rall\n" +
|
57
|
+
" --rubygems-output=stderr\n" +
|
58
|
+
" Default: stderr\n" +
|
59
|
+
" Valid types:\n" +
|
60
|
+
" - none: print no output\n" +
|
61
|
+
" - stdout: print standard output stream\n" +
|
62
|
+
" - stderr: print standard error stream\n" +
|
63
|
+
" - all: print all output"
|
64
|
+
sudo_msg = "Perform all gem operations under sudo (as root). Will only work on\n" +
|
65
|
+
" correctly configured, supported systems. See docs for more info."
|
66
|
+
silent_msg = "Suppress all output except fatal exceptions, and output from\n" +
|
67
|
+
" rogue-gems and outdated-gems options."
|
68
|
+
version_msg = "Show GemInstaller version and exit."
|
69
|
+
|
70
|
+
opts.on("-cCONFIGPATHS", "--config=CONFIGPATHS", String, config_msg) do |config_paths|
|
71
|
+
@options[:config_paths] = config_paths
|
72
|
+
end
|
73
|
+
|
74
|
+
opts.on("-e", "--exceptions", exceptions_msg) do
|
75
|
+
@options[:exceptions] = true
|
76
|
+
end
|
77
|
+
|
78
|
+
opts.on("-d", "--redirect-stderr-to-stdout", redirect_stderr_to_stdout_msg) do
|
79
|
+
@options[:redirect_stderr_to_stdout] = true
|
80
|
+
end
|
81
|
+
|
82
|
+
opts.on("-gTYPES", "--geminstaller-output=TYPES", String, geminstaller_output_msg) do |geminstaller_output_flags|
|
83
|
+
@unparsed_geminstaller_output_flags = geminstaller_output_flags
|
84
|
+
end
|
85
|
+
|
86
|
+
opts.on("-h", "--help", help_msg) do
|
87
|
+
@output = opts.to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
opts.on("-o", "--print-outdated-gems", print_outdated_gems_msg) do
|
91
|
+
@options[:print_outdated_gems] = true
|
92
|
+
end
|
93
|
+
|
94
|
+
opts.on("-p", "--print-rogue-gems", print_rogue_gems_msg) do
|
95
|
+
@options[:print_rogue_gems] = true
|
96
|
+
end
|
97
|
+
|
98
|
+
opts.on("-b", "--bundler-export", bundler_export_msg) do
|
99
|
+
@options[:bundler_export] = true
|
100
|
+
end
|
101
|
+
|
102
|
+
opts.on("-rTYPES", "--rubygems-output=TYPES", String, rubygems_output_msg) do |rubygems_output_flags|
|
103
|
+
@unparsed_rubygems_output_flags = rubygems_output_flags
|
104
|
+
end
|
105
|
+
|
106
|
+
opts.on("-s", "--sudo", sudo_msg) do
|
107
|
+
@options[:sudo] = true
|
108
|
+
end
|
109
|
+
|
110
|
+
opts.on("-t", "--silent", silent_msg) do
|
111
|
+
@options[:silent] = true
|
112
|
+
end
|
113
|
+
|
114
|
+
opts.on("-v", "--version", version_msg) do
|
115
|
+
@output = "#{GemInstaller::version}\n"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
begin
|
120
|
+
opts.parse!(args)
|
121
|
+
rescue(OptionParser::InvalidOption)
|
122
|
+
@output << opts.to_s
|
123
|
+
return 1
|
124
|
+
end
|
125
|
+
|
126
|
+
if @options[:silent] and (@unparsed_geminstaller_output_flags or @unparsed_rubygems_output_flags)
|
127
|
+
@output = "The rubygems-output or geminstaller-output option cannot be specified if the silent option is true."
|
128
|
+
return 1
|
129
|
+
end
|
130
|
+
|
131
|
+
if (@options[:sudo])
|
132
|
+
@output = "The sudo option is not (yet) supported when invoking GemInstaller programatically. It is only supported when using the command line 'geminstaller' executable. See the docs for more info."
|
133
|
+
return 1
|
134
|
+
end
|
135
|
+
|
136
|
+
# TODO: remove duplication
|
137
|
+
if @unparsed_geminstaller_output_flags
|
138
|
+
flags = @unparsed_geminstaller_output_flags.split(',')
|
139
|
+
flags.delete_if {|flag| flag == nil or flag == ''}
|
140
|
+
flags.map! {|flag| flag.downcase}
|
141
|
+
flags.sort!
|
142
|
+
flags.uniq!
|
143
|
+
flags.map! {|flag| flag.to_sym}
|
144
|
+
geminstaller_output_valid = true
|
145
|
+
flags.each do |flag|
|
146
|
+
unless VALID_GEMINSTALLER_OUTPUT_FLAGS.include?(flag)
|
147
|
+
@output = "Invalid geminstaller-output flag: #{flag}\n"
|
148
|
+
geminstaller_output_valid = false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
@options[:geminstaller_output] = flags if geminstaller_output_valid
|
152
|
+
end
|
153
|
+
|
154
|
+
if @unparsed_rubygems_output_flags
|
155
|
+
flags = @unparsed_rubygems_output_flags.split(',')
|
156
|
+
flags.delete_if {|flag| flag == nil or flag == ''}
|
157
|
+
flags.map! {|flag| flag.downcase}
|
158
|
+
flags.sort!
|
159
|
+
flags.uniq!
|
160
|
+
flags.map! {|flag| flag.to_sym}
|
161
|
+
rubygems_output_valid = true
|
162
|
+
flags.each do |flag|
|
163
|
+
unless VALID_RUBYGEMS_OUTPUT_FLAGS.include?(flag)
|
164
|
+
@output = "Invalid rubygems-output flag: #{flag}\n"
|
165
|
+
rubygems_output_valid = false
|
166
|
+
end
|
167
|
+
end
|
168
|
+
@options[:rubygems_output] = flags if rubygems_output_valid
|
169
|
+
end
|
170
|
+
|
171
|
+
# nil out @output if there was no output
|
172
|
+
@output = nil if @output == ""
|
173
|
+
return 0
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class Autogem
|
3
|
+
attr_writer :gem_command_manager, :gem_source_index_proxy
|
4
|
+
def autogem(gems)
|
5
|
+
@gem_source_index_proxy.refresh!
|
6
|
+
# REALLY refresh - refreshing the source_index directly isn't enough.
|
7
|
+
Gem.refresh
|
8
|
+
@completed_names = []
|
9
|
+
@completed_gems = []
|
10
|
+
gems.each do |gem|
|
11
|
+
process_gem(gem)
|
12
|
+
end
|
13
|
+
@completed_gems
|
14
|
+
end
|
15
|
+
|
16
|
+
def process_gem(gem)
|
17
|
+
name = gem.name
|
18
|
+
version = gem.version
|
19
|
+
unless @completed_names.index(name) or gem.no_autogem
|
20
|
+
begin
|
21
|
+
invoke_require_gem_command(name, version)
|
22
|
+
rescue Gem::LoadError => load_error
|
23
|
+
load_error_message = load_error.message
|
24
|
+
load_error_message.strip!
|
25
|
+
error_message = "Error: GemInstaller attempted to load gem '#{name}', version '#{version}', but that version is not installed. Use GemInstaller to install the gem. Original Gem::LoadError was: '#{load_error_message}'"
|
26
|
+
raise GemInstaller::GemInstallerError.new(error_message)
|
27
|
+
end
|
28
|
+
@completed_names << name
|
29
|
+
@completed_gems << gem
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def invoke_require_gem_command(name, version)
|
34
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('< 0.9')
|
35
|
+
require_gem(name, version)
|
36
|
+
else
|
37
|
+
begin
|
38
|
+
result = gem(name, version)
|
39
|
+
rescue Gem::Exception => e
|
40
|
+
exception_message = e.message
|
41
|
+
exception_message.strip!
|
42
|
+
error_message = "Error: GemInstaller failed to activate gem '#{name}', version '#{version}'. This may be because GemInstaller processes gems in order (was alphabetical prior to 0.5.0), and an earlier gem in your geminstaller.yml config already activated another version. Use the 'gem dependency [-R]' command to track this down, and reorder/edit your config as necessary. Original Gem::Exception was: '#{exception_message}'"
|
43
|
+
raise GemInstaller::GemInstallerError.new(error_message)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# this file supports backward compatibility for prior versions of RubyGems
|
2
|
+
|
3
|
+
# 0.9.3 reorganized commands to Gem::Commands:: module from Gem::
|
4
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<0.9.3')
|
5
|
+
LIST_COMMAND_CLASS = Gem::ListCommand
|
6
|
+
QUERY_COMMAND_CLASS = Gem::QueryCommand
|
7
|
+
else
|
8
|
+
LIST_COMMAND_CLASS = Gem::Commands::ListCommand
|
9
|
+
QUERY_COMMAND_CLASS = Gem::Commands::QueryCommand
|
10
|
+
end
|
11
|
+
|
12
|
+
# >1.3.5 changed Gem::Version::Requirement to Gem::Requirement
|
13
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('>1.3.5')
|
14
|
+
GemInstaller::REQUIREMENT_CLASS = Gem::Requirement
|
15
|
+
else
|
16
|
+
GemInstaller::REQUIREMENT_CLASS = Gem::Version::Requirement
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class BundlerExporter
|
3
|
+
attr_writer :output_proxy
|
4
|
+
|
5
|
+
def output(config)
|
6
|
+
output_string = convert(config)
|
7
|
+
@output_proxy.sysout output_string
|
8
|
+
output_string
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert(config)
|
12
|
+
manifest = ""
|
13
|
+
config.gems.each do |gem|
|
14
|
+
manifest += %Q{gem "#{gem.name}", "#{gem.version}"\n}
|
15
|
+
end
|
16
|
+
manifest
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class Config
|
3
|
+
def initialize(yaml)
|
4
|
+
@yaml = yaml
|
5
|
+
@default_install_options_string = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def gems
|
9
|
+
parse_defaults
|
10
|
+
gem_defs = @yaml["gems"]
|
11
|
+
gems = []
|
12
|
+
gem_defs.each do |gem_def|
|
13
|
+
name = gem_def['name']
|
14
|
+
version = gem_def['version'].to_s
|
15
|
+
platform = gem_def['platform'].to_s
|
16
|
+
# get install_options for specific gem, if specified
|
17
|
+
install_options_string = gem_def['install_options'].to_s
|
18
|
+
# if no install_options were specified for specific gem, and default install_options were specified...
|
19
|
+
if install_options_string.empty? &&
|
20
|
+
!@default_install_options_string.nil? &&
|
21
|
+
!@default_install_options_string.empty? then
|
22
|
+
# then use the default install_options
|
23
|
+
install_options_string = @default_install_options_string
|
24
|
+
end
|
25
|
+
install_options_array = []
|
26
|
+
# if there was an install options string specified, default or gem-specific, parse it to an array
|
27
|
+
install_options_array = install_options_string.split(" ") unless install_options_string.empty?
|
28
|
+
|
29
|
+
check_for_upgrade = gem_def['check_for_upgrade']
|
30
|
+
if check_for_upgrade.nil? && defined? @default_check_for_upgrade then
|
31
|
+
check_for_upgrade = @default_check_for_upgrade
|
32
|
+
end
|
33
|
+
|
34
|
+
fix_dependencies = gem_def['fix_dependencies']
|
35
|
+
if fix_dependencies.nil? && defined? @default_fix_dependencies then
|
36
|
+
fix_dependencies = @default_fix_dependencies
|
37
|
+
end
|
38
|
+
|
39
|
+
no_autogem = gem_def['no_autogem']
|
40
|
+
if no_autogem.nil? && defined? @default_no_autogem then
|
41
|
+
no_autogem = @default_no_autogem
|
42
|
+
end
|
43
|
+
|
44
|
+
gem = GemInstaller::RubyGem.new(
|
45
|
+
name,
|
46
|
+
:version => version,
|
47
|
+
:platform => platform,
|
48
|
+
:install_options => install_options_array,
|
49
|
+
:check_for_upgrade => check_for_upgrade,
|
50
|
+
:no_autogem => no_autogem,
|
51
|
+
:fix_dependencies => fix_dependencies)
|
52
|
+
gems << gem
|
53
|
+
end
|
54
|
+
return gems
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def parse_defaults
|
60
|
+
defaults = @yaml["defaults"]
|
61
|
+
return if defaults.nil?
|
62
|
+
@default_install_options_string = defaults['install_options']
|
63
|
+
@default_check_for_upgrade = defaults['check_for_upgrade']
|
64
|
+
@default_fix_dependencies = defaults['fix_dependencies']
|
65
|
+
@default_no_autogem = defaults['no_autogem']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
dir = File.dirname(__FILE__)
|
2
|
+
require File.expand_path("#{dir}/requires.rb")
|
3
|
+
|
4
|
+
module GemInstaller
|
5
|
+
class ConfigBuilder
|
6
|
+
attr_reader :config_file_paths_array
|
7
|
+
attr_writer :file_reader, :yaml_loader, :config_file_paths, :output_filter
|
8
|
+
|
9
|
+
def initialize(default_config_file_paths_array = ['geminstaller.yml','config/geminstaller.yml','ci/geminstaller.yml'])
|
10
|
+
@default_config_file_paths_array = default_config_file_paths_array
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_config
|
14
|
+
@config_file_paths_array = @config_file_paths ? @config_file_paths.split(",") : @default_config_file_paths_array
|
15
|
+
merged_defaults = {}
|
16
|
+
merged_gems_in_order = []
|
17
|
+
merged_gems_by_key = {}
|
18
|
+
file_found = false
|
19
|
+
@config_file_paths_array.reverse.each do |path| # reverse because last config files win
|
20
|
+
if File.exists?(path)
|
21
|
+
file_found = true
|
22
|
+
else
|
23
|
+
next
|
24
|
+
end
|
25
|
+
file_contents = @file_reader.read(path)
|
26
|
+
next unless file_contents
|
27
|
+
next if file_contents.empty?
|
28
|
+
expanded_path = File.expand_path(path)
|
29
|
+
@output_filter.geminstaller_output(:debug,"Found GemInstaller config file at: #{expanded_path}\n")
|
30
|
+
erb = ERB.new(%{#{file_contents}})
|
31
|
+
erb_result = nil
|
32
|
+
Dir.chdir(File.dirname(expanded_path)) do |yaml_file_dir|
|
33
|
+
erb_result = erb.result(include_config_binding)
|
34
|
+
end
|
35
|
+
yaml = @yaml_loader.load(erb_result)
|
36
|
+
merged_defaults.merge!(yaml['defaults']) unless yaml['defaults'].nil?
|
37
|
+
next unless yaml['gems']
|
38
|
+
yaml['gems'].each do |new_gem|
|
39
|
+
gem_key = [new_gem['name'],new_gem['version'],new_gem['platform']].join('-')
|
40
|
+
existing_gem = merged_gems_by_key[gem_key]
|
41
|
+
unless existing_gem
|
42
|
+
merged_gems_in_order << new_gem
|
43
|
+
merged_gems_by_key[gem_key] = new_gem
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
raise GemInstaller::MissingFileError.new("No config files found at any of these paths: #{@config_file_paths_array.join(', ')}") unless file_found
|
48
|
+
merged_yaml = {}
|
49
|
+
merged_yaml['defaults'] = merged_defaults
|
50
|
+
merged_yaml['gems'] = merged_gems_in_order
|
51
|
+
config = GemInstaller::Config.new(merged_yaml)
|
52
|
+
config
|
53
|
+
end
|
54
|
+
|
55
|
+
def include_config_binding
|
56
|
+
def include_config(config_file)
|
57
|
+
Dir.chdir(File.dirname(config_file)) do |yaml_file_dir|
|
58
|
+
erb = File.open(config_file) { |io| ERB.new(io.read) }
|
59
|
+
erb.result(include_config_binding)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
binding
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class EnhancedStreamUI < Gem::StreamUI
|
3
|
+
attr_writer :outs, :errs
|
4
|
+
attr_writer :gem_interaction_handler if GemInstaller::RubyGemsVersionChecker.matches?('<=0.9.4')
|
5
|
+
|
6
|
+
def initialize()
|
7
|
+
# override default constructor to have no args
|
8
|
+
end
|
9
|
+
|
10
|
+
def ask_yes_no(question, default=nil)
|
11
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<=0.9.4')
|
12
|
+
# Using defaults, we expect no interactive prompts RubyGems >= 0.9.5
|
13
|
+
begin
|
14
|
+
@gem_interaction_handler.handle_ask_yes_no(question)
|
15
|
+
rescue Exception => e
|
16
|
+
@outs.print(question)
|
17
|
+
@outs.flush
|
18
|
+
raise e
|
19
|
+
end
|
20
|
+
end
|
21
|
+
raise_unexpected_prompt_error(question)
|
22
|
+
end
|
23
|
+
|
24
|
+
def ask(question)
|
25
|
+
raise_unexpected_prompt_error(question)
|
26
|
+
end
|
27
|
+
|
28
|
+
def choose_from_list(question, list)
|
29
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<=0.9.4')
|
30
|
+
# Using defaults, we expect no interactive prompts RubyGems >= 0.9.5
|
31
|
+
@gem_interaction_handler.handle_choose_from_list(question, list)
|
32
|
+
else
|
33
|
+
list_string = list.join("\n")
|
34
|
+
question_and_list = "#{question}\n#{list_string}"
|
35
|
+
raise_unexpected_prompt_error(question_and_list)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<=1.0.1')
|
40
|
+
# explicit exit in terminate_interation was removed after 1.0.1
|
41
|
+
def terminate_interaction!(status=-1)
|
42
|
+
raise_error(status)
|
43
|
+
end
|
44
|
+
|
45
|
+
def terminate_interaction(status=0)
|
46
|
+
raise_error(status) unless status == 0
|
47
|
+
raise GemInstaller::RubyGemsExit.new(status)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def alert_error(statement, question=nil)
|
52
|
+
# if alert_error got called due to a GemInstaller::UnexpectedPromptError, re-throw it
|
53
|
+
last_exception = $!
|
54
|
+
if last_exception.class == GemInstaller::UnauthorizedDependencyPromptError || last_exception.class == GemInstaller::RubyGemsExit
|
55
|
+
raise last_exception
|
56
|
+
end
|
57
|
+
# otherwise let alert_error continue normally...
|
58
|
+
super(statement, question)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
def raise_error(status)
|
63
|
+
raise GemInstaller::GemInstallerError.new("RubyGems exited abnormally. Status: #{status}\n")
|
64
|
+
end
|
65
|
+
|
66
|
+
def raise_unexpected_prompt_error(question)
|
67
|
+
raise GemInstaller::UnexpectedPromptError.new("GemInstaller Internal Error - Unexpected prompt received from RubyGems: '#{question}'.")
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class ExactMatchListCommand < LIST_COMMAND_CLASS
|
3
|
+
def execute
|
4
|
+
string = get_one_optional_argument || ''
|
5
|
+
# This overrides the default RubyGems ListCommand behavior of doing a wildcard match. This caused problems
|
6
|
+
# when some gems (ActiveRecord-JDBC) caused exceptions during a remote list, causing a remote list
|
7
|
+
# of other gems (activerecord) to fail as well
|
8
|
+
options[:name] = /^#{string}$/
|
9
|
+
# Do a little metaprogramming magic to avoid calling the problematic execute method on the ListCommand
|
10
|
+
# superclass, and instead directly call the method on the QueryCommand grandparent 'supersuperclass'
|
11
|
+
unbound_execute_method = QUERY_COMMAND_CLASS.instance_method(:execute)
|
12
|
+
bound_execute_method = unbound_execute_method.bind(self)
|
13
|
+
bound_execute_method.call
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|