geminstaller 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/LICENSE +1 -1
- data/Manifest.txt +6 -2
- data/README.txt +6 -4
- data/TODO.txt +35 -30
- data/ci/README_CI.txt +22 -0
- data/ci/cruise +50 -0
- data/cruise_config.rb +11 -0
- data/focused_spec.sh +2 -0
- data/focused_spec_debug.sh +2 -0
- data/geminstaller.yml +5 -3
- data/lib/geminstaller.rb +1 -1
- data/lib/geminstaller/autogem.rb +2 -2
- data/lib/geminstaller/backward_compatibility.rb +1 -1
- data/lib/geminstaller/dependency_injector.rb +5 -3
- data/lib/geminstaller/enhanced_stream_ui.rb +17 -7
- data/lib/geminstaller/gem_command_manager.rb +15 -12
- data/lib/geminstaller/gem_interaction_handler.rb +8 -0
- data/lib/geminstaller/gem_list_checker.rb +1 -1
- data/lib/geminstaller/gem_runner_proxy.rb +1 -1
- data/lib/geminstaller/gem_spec_manager.rb +25 -13
- data/lib/geminstaller/install_processor.rb +21 -6
- data/lib/geminstaller/missing_dependency_finder.rb +5 -0
- data/lib/geminstaller/requires.rb +16 -6
- data/lib/geminstaller/ruby_gem.rb +7 -2
- data/lib/geminstaller/rubygems_version_checker.rb +11 -5
- data/lib/geminstaller/source_index_search_adapter.rb +41 -0
- data/lib/geminstaller/valid_platform_selector.rb +5 -0
- data/start_local_gem_server.sh +1 -1
- data/test/test_all.rb +15 -10
- data/website/metainfo.yaml +8 -2
- data/website/src/code/index.page +49 -2
- data/website/src/community/index.page +1 -1
- data/website/src/community/links.page +2 -0
- data/website/src/documentation/documentation.page +14 -11
- data/website/src/documentation/tutorials.page +16 -10
- data/website/src/faq.page +15 -0
- data/website/src/index.page +21 -7
- metadata +51 -39
- data/ci/cruisecontrol +0 -50
- data/lib/geminstaller/gem_command_line_proxy.rb +0 -32
@@ -4,6 +4,10 @@ module GemInstaller
|
|
4
4
|
DEPENDENCY_PROMPT = 'Install required dependency'
|
5
5
|
|
6
6
|
def handle_ask_yes_no(question)
|
7
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('>=0.9.5')
|
8
|
+
# gem_interaction_handler is not used for RubyGems >= 0.9.5
|
9
|
+
raise RuntimeError.new("Internal GemInstaller Error: GemInteractionHandler should not be used for RubyGems >= 0.9.5")
|
10
|
+
end
|
7
11
|
return unless question.index(DEPENDENCY_PROMPT)
|
8
12
|
message = "Error: RubyGems is prompting to install a required dependency, and you have not " +
|
9
13
|
"specified the '--install-dependencies' option for the current gem. You must modify your " +
|
@@ -13,6 +17,10 @@ module GemInstaller
|
|
13
17
|
end
|
14
18
|
|
15
19
|
def handle_choose_from_list(question, list, noninteractive_chooser = nil)
|
20
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('>=0.9.5')
|
21
|
+
# gem_interaction_handler is not used for RubyGems >= 0.9.5
|
22
|
+
raise RuntimeError.new("Internal GemInstaller Error: GemInteractionHandler should not be used for RubyGems >= 0.9.5")
|
23
|
+
end
|
16
24
|
noninteractive_chooser ||= @noninteractive_chooser_class.new
|
17
25
|
valid_platforms = nil
|
18
26
|
if dependent_gem_with_platform_specified?(list, noninteractive_chooser) or noninteractive_chooser.uninstall_list_type?(question)
|
@@ -23,7 +23,7 @@ module GemInstaller
|
|
23
23
|
end
|
24
24
|
|
25
25
|
if matched_lines.size == 0
|
26
|
-
error_message = "Error: Could not find remote gem to install. Gem name = '#{gem.name}', install options = '#{gem.install_options}'"
|
26
|
+
error_message = "Error: Could not find remote gem to install. Gem name = '#{gem.name}', Gem version = '#{gem.version}', install options = '#{gem.install_options}'"
|
27
27
|
raise GemInstaller::GemInstallerError.new(error_message)
|
28
28
|
end
|
29
29
|
|
@@ -27,7 +27,7 @@ module GemInstaller
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def create_gem_runner
|
30
|
-
if
|
30
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('< 0.9')
|
31
31
|
@gem_runner_class.new()
|
32
32
|
else
|
33
33
|
@gem_runner_class.new(:command_manager => @gem_cmd_manager_class)
|
@@ -1,18 +1,13 @@
|
|
1
1
|
module GemInstaller
|
2
2
|
class GemSpecManager
|
3
|
-
attr_writer :
|
3
|
+
attr_writer :source_index_search_adapter, :valid_platform_selector, :output_filter
|
4
4
|
|
5
|
-
def search(gem_pattern, version_requirement)
|
6
|
-
@gem_source_index_proxy.refresh!
|
7
|
-
@gem_source_index_proxy.search(gem_pattern, version_requirement)
|
8
|
-
end
|
9
|
-
|
10
5
|
def is_gem_installed?(gem)
|
11
6
|
return local_matching_gems(gem).size > 0
|
12
7
|
end
|
13
8
|
|
14
9
|
def all_local_gems
|
15
|
-
all_local_specs =
|
10
|
+
all_local_specs = @source_index_search_adapter.all_local_specs
|
16
11
|
return [] unless all_local_specs
|
17
12
|
all_local_gems = all_local_specs.collect do |spec|
|
18
13
|
gem = GemInstaller::RubyGem.new(spec.name, :version => spec.version.version)
|
@@ -21,18 +16,35 @@ module GemInstaller
|
|
21
16
|
end
|
22
17
|
|
23
18
|
def local_matching_gems(gem, exact_platform_match = true)
|
24
|
-
|
25
|
-
found_gem_specs = search(gem_name_regexp,gem.version)
|
19
|
+
found_gem_specs = @source_index_search_adapter.search(gem,gem.version)
|
26
20
|
return [] unless found_gem_specs
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
|
22
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<=0.9.4')
|
23
|
+
found_gem_specs = found_gem_specs.select do |gem_spec|
|
24
|
+
valid_platforms = @valid_platform_selector.select(gem.platform, exact_platform_match)
|
25
|
+
valid_platforms.include?(gem_spec.platform)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
# TODO: this is a hack because source_index#search doesn't allow specification of platform
|
29
|
+
if exact_platform_match
|
30
|
+
found_gem_specs = found_gem_specs.delete_if do |spec|
|
31
|
+
!spec_platform_matches?(spec, gem.platform)
|
32
|
+
end
|
33
|
+
end
|
30
34
|
end
|
31
|
-
matching_gems =
|
35
|
+
matching_gems = found_gem_specs.map do |gem_spec|
|
32
36
|
GemInstaller::RubyGem.new(gem_spec.name, {:version => gem_spec.version.version, :platform => gem_spec.platform })
|
33
37
|
end
|
34
38
|
return matching_gems
|
35
39
|
end
|
40
|
+
|
41
|
+
def spec_platform_matches?(spec, platform)
|
42
|
+
spec_platform = Gem::Platform.new(spec.platform)
|
43
|
+
if spec_platform.is_a?(String)
|
44
|
+
return spec_platform == platform
|
45
|
+
end
|
46
|
+
return spec_platform =~ platform
|
47
|
+
end
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
@@ -14,19 +14,34 @@ module GemInstaller
|
|
14
14
|
already_specified = true
|
15
15
|
end
|
16
16
|
gem_is_installed = @gem_spec_manager.is_gem_installed?(gem)
|
17
|
-
if gem_is_installed
|
17
|
+
if gem_is_installed
|
18
18
|
@output_filter.geminstaller_output(:debug,"Gem #{gem.name}, version #{gem.version} is already installed.\n")
|
19
19
|
else
|
20
|
-
|
21
|
-
|
22
|
-
output_lines = @gem_command_manager.install_gem(gem)
|
23
|
-
print_dependency_install_messages(gem, output_lines) unless @options[:silent]
|
20
|
+
perform_install(gem, already_specified)
|
21
|
+
installation_performed = true
|
24
22
|
end
|
25
23
|
if gem.fix_dependencies
|
26
|
-
|
24
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('>=0.9.5')
|
25
|
+
# RubyGems >=0.9.5 automatically handles missing dependencies, so just perform an install
|
26
|
+
unless installation_performed
|
27
|
+
@output_filter.geminstaller_output(:install,"The 'fix_dependencies' option was specified for #{gem.name}, version #{gem.version}, so it will be reinstalled to fix any missing dependencies.\n")
|
28
|
+
perform_install(gem, already_specified, true)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
# RubyGems <=0.9.4 does not automatically handles missing dependencies, so GemInstaller must find them
|
32
|
+
# manually with missing_dependency_finder
|
33
|
+
fix_dependencies(gem)
|
34
|
+
end
|
27
35
|
end
|
28
36
|
end
|
29
37
|
|
38
|
+
def perform_install(gem, already_specified, force_install = false)
|
39
|
+
@gem_list_checker.verify_and_specify_remote_gem!(gem) unless already_specified
|
40
|
+
@output_filter.geminstaller_output(:install,"Invoking gem install for #{gem.name}, version #{gem.version}.\n")
|
41
|
+
output_lines = @gem_command_manager.install_gem(gem, force_install)
|
42
|
+
print_dependency_install_messages(gem, output_lines) unless @options[:silent]
|
43
|
+
end
|
44
|
+
|
30
45
|
def print_dependency_install_messages(gem, output_lines)
|
31
46
|
output_lines.each do |line|
|
32
47
|
line =~ /Successfully installed /
|
@@ -2,6 +2,11 @@ module GemInstaller
|
|
2
2
|
class MissingDependencyFinder
|
3
3
|
attr_writer :gem_command_manager, :gem_spec_manager, :gem_arg_processor, :output_filter
|
4
4
|
def find(dependent_gem)
|
5
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('>=0.9.5')
|
6
|
+
# missing_dependency_finder is not used for RubyGems >= 0.9.5
|
7
|
+
raise RuntimeError.new("Internal GemInstaller Error: MissingDependencyFinder should not be used for RubyGems >= 0.9.5")
|
8
|
+
end
|
9
|
+
|
5
10
|
# NOTE: this doesn't resolve platforms, there's currently no way to know what
|
6
11
|
# platform should be selected for a dependency gem. Best-effort handling
|
7
12
|
# of ambiguous platforms on dependency gems will be handled elsewhere
|
@@ -1,28 +1,38 @@
|
|
1
1
|
dir = File.dirname(__FILE__)
|
2
2
|
|
3
|
-
|
4
3
|
# require for rubygems package
|
5
4
|
require 'rubygems'
|
6
5
|
|
7
6
|
# backward compability and version-checking stuff - must be required before it is used
|
8
|
-
require 'rubygems/rubygems_version'
|
9
7
|
require File.expand_path("#{dir}/rubygems_version_checker")
|
10
8
|
|
9
|
+
unless defined? ALLOW_UNSUPPORTED_RUBYGEMS_VERSION or GemInstaller::RubyGemsVersionChecker.matches?('>=0.9.5')
|
10
|
+
print "\n\n----------------------------------------------------------------\n" +
|
11
|
+
"WARNING: You are using RubyGems version #{Gem::RubyGemsVersion}.\n" +
|
12
|
+
"You should update to RubyGems version 1.0.1 or above,\n" +
|
13
|
+
"because gems created for newer RubyGems versions\n" +
|
14
|
+
"might be incompatible.\n" +
|
15
|
+
"To update rubygems (recommended), use 'gem update --system'.\n" +
|
16
|
+
"----------------------------------------------------------------\n\n"
|
17
|
+
end
|
18
|
+
|
11
19
|
# requires for rubygems internal classes
|
12
20
|
require 'rubygems/doc_manager'
|
13
21
|
require 'rubygems/config_file'
|
14
|
-
if
|
22
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<0.9.3')
|
15
23
|
require 'rubygems/cmd_manager'
|
16
24
|
else
|
17
25
|
require 'rubygems/command_manager'
|
18
26
|
end
|
19
27
|
require 'rubygems/gem_runner'
|
20
|
-
|
28
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<1.0.0')
|
29
|
+
require 'rubygems/remote_installer'
|
30
|
+
end
|
21
31
|
require 'rubygems/installer'
|
22
32
|
require 'rubygems/validator'
|
23
33
|
|
24
34
|
# these are order-dependent. Any better way???
|
25
|
-
unless
|
35
|
+
unless GemInstaller::RubyGemsVersionChecker.matches?('<0.9.3')
|
26
36
|
require 'rubygems/commands/query_command'
|
27
37
|
require 'rubygems/commands/list_command'
|
28
38
|
end
|
@@ -52,7 +62,6 @@ require File.expand_path("#{dir}/enhanced_stream_ui")
|
|
52
62
|
require File.expand_path("#{dir}/exact_match_list_command")
|
53
63
|
require File.expand_path("#{dir}/file_reader")
|
54
64
|
require File.expand_path("#{dir}/gem_arg_processor")
|
55
|
-
require File.expand_path("#{dir}/gem_command_line_proxy")
|
56
65
|
require File.expand_path("#{dir}/gem_command_manager")
|
57
66
|
require File.expand_path("#{dir}/gem_interaction_handler")
|
58
67
|
require File.expand_path("#{dir}/gem_list_checker")
|
@@ -72,6 +81,7 @@ require File.expand_path("#{dir}/output_proxy")
|
|
72
81
|
require File.expand_path("#{dir}/rogue_gem_finder")
|
73
82
|
require File.expand_path("#{dir}/rubygems_exit")
|
74
83
|
require File.expand_path("#{dir}/ruby_gem")
|
84
|
+
require File.expand_path("#{dir}/source_index_search_adapter")
|
75
85
|
require File.expand_path("#{dir}/unexpected_prompt_error")
|
76
86
|
require File.expand_path("#{dir}/unauthorized_dependency_prompt_error")
|
77
87
|
require File.expand_path("#{dir}/valid_platform_selector")
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module GemInstaller
|
2
2
|
class RubyGem
|
3
3
|
include Comparable
|
4
|
-
attr_accessor :name, :version, :platform, :install_options, :check_for_upgrade, :fix_dependencies, :no_autogem, :prefer_binary_platform
|
4
|
+
attr_accessor :name, :version, :platform, :install_options, :check_for_upgrade, :fix_dependencies, :no_autogem, :prefer_binary_platform, :uninstall_options
|
5
5
|
|
6
6
|
def initialize(name, opts={})
|
7
7
|
@name = name
|
@@ -15,10 +15,15 @@ module GemInstaller
|
|
15
15
|
@platform = opts[:platform]
|
16
16
|
end
|
17
17
|
@install_options = opts[:install_options] ||= []
|
18
|
+
@uninstall_options = opts[:uninstall_options] ||= []
|
18
19
|
@check_for_upgrade = opts[:check_for_upgrade] == true ? true : false
|
19
20
|
@fix_dependencies = opts[:fix_dependencies] == true ? true : false
|
20
21
|
@no_autogem = opts[:no_autogem] == true ? true : false
|
21
|
-
|
22
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('>=0.9.5')
|
23
|
+
warn("The 'prefer_binary_platform' option is deprecated on RubyGems >= 0.9.5, and has no effect") unless opts[:prefer_binary_platorm].nil?
|
24
|
+
else
|
25
|
+
@prefer_binary_platform = opts[:prefer_binary_platorm] == false ? false : true
|
26
|
+
end
|
22
27
|
end
|
23
28
|
|
24
29
|
def self.default_version
|
@@ -1,9 +1,15 @@
|
|
1
|
+
require 'rubygems/rubygems_version'
|
2
|
+
|
1
3
|
module GemInstaller
|
2
4
|
class RubyGemsVersionChecker
|
3
|
-
def
|
4
|
-
|
5
|
+
def self.matches?(version_spec, options = {})
|
6
|
+
version_spec = [version_spec] unless version_spec.kind_of?(Array)
|
7
|
+
# TODO: if rubygems has already been initialized before GemInstaller overrides the rubygems version,
|
8
|
+
# (for example, by running rspec), then Gem::RubyGemsVersion could be initialized to the incorrect
|
9
|
+
# system-rubygems version instead of the geminstaller-overridden version. Need to figure out how
|
10
|
+
# to re-parse 'rubygems/rubygems_version' and let it redefine 'Gem::RubyGemsVersion'
|
11
|
+
rubygems_version = options[:rubygems_version] ||= Gem::RubyGemsVersion
|
12
|
+
Gem::Version::Requirement.new(version_spec).satisfied_by?(Gem::Version.new(rubygems_version))
|
5
13
|
end
|
6
14
|
end
|
7
|
-
end
|
8
|
-
|
9
|
-
RUBYGEMS_VERSION_CHECKER = GemInstaller::RubyGemsVersionChecker.new
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module GemInstaller
|
2
|
+
class SourceIndexSearchAdapter
|
3
|
+
attr_writer :gem_source_index_proxy
|
4
|
+
|
5
|
+
def all_local_specs
|
6
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<=0.9.4')
|
7
|
+
search_less_than_or_equal_0_9_4('',GemInstaller::RubyGem.default_version)
|
8
|
+
else
|
9
|
+
dependency = Gem::Dependency.new('', GemInstaller::RubyGem.default_version)
|
10
|
+
@gem_source_index_proxy.refresh!
|
11
|
+
@gem_source_index_proxy.search(dependency, false)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def search(gem, version_requirement, platform_only = false)
|
16
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('<=0.9.4')
|
17
|
+
gem_pattern = /^#{gem.regexp_escaped_name}$/
|
18
|
+
search_less_than_or_equal_0_9_4(gem_pattern, version_requirement)
|
19
|
+
else
|
20
|
+
search_greater_than_0_9_4(gem, version_requirement, platform_only)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def search_less_than_or_equal_0_9_4(gem_pattern, version_requirement)
|
25
|
+
@gem_source_index_proxy.refresh!
|
26
|
+
@gem_source_index_proxy.search(gem_pattern, version_requirement)
|
27
|
+
end
|
28
|
+
|
29
|
+
def search_greater_than_0_9_4(gem, version_requirement, platform_only = false)
|
30
|
+
dependency = Gem::Dependency.new(gem.name, version_requirement)
|
31
|
+
@gem_source_index_proxy.refresh!
|
32
|
+
@gem_source_index_proxy.search(dependency, platform_only)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
@@ -3,6 +3,11 @@ module GemInstaller
|
|
3
3
|
attr_writer :options, :ruby_platform, :output_filter
|
4
4
|
|
5
5
|
def select(gem_platform = nil, exact_platform_match = false)
|
6
|
+
if GemInstaller::RubyGemsVersionChecker.matches?('>=0.9.5')
|
7
|
+
# valid_platform_selector is not used for RubyGems >= 0.9.5
|
8
|
+
raise RuntimeError.new("Internal GemInstaller Error: ValidPlatformSelector should not be used for RubyGems >= 0.9.5")
|
9
|
+
end
|
10
|
+
|
6
11
|
@ruby_platform ||= RUBY_PLATFORM
|
7
12
|
return [@ruby_platform] if gem_platform == Gem::Platform::CURRENT
|
8
13
|
return [gem_platform] if exact_platform_match
|
data/start_local_gem_server.sh
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
gem server --dir=./spec/fixture/gems --port=9909
|
data/test/test_all.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
|
2
|
-
# to Rspec 0.9.3. Need to be back to all specs being runnable via 'rake' or 'test_all'
|
3
|
-
# Are there any good examples of running rspec for a non-rails project, and allowing post-suite hooks?
|
1
|
+
print "\nRunning all GemInstaller Tests, ENV['RUBYGEMS_VERSION'] == '#{ENV['RUBYGEMS_VERSION']}'\n\n"
|
4
2
|
|
5
3
|
dir = File.dirname(__FILE__)
|
6
4
|
specdir = File.expand_path("#{dir}/../spec")
|
7
5
|
require File.expand_path("#{specdir}/helper/spec_helper")
|
8
6
|
|
9
7
|
spec_files = Dir.glob("#{specdir}/**/*_spec.rb")
|
8
|
+
|
10
9
|
# put test_gem_home_spec first so we only have to perform the install once
|
11
|
-
|
10
|
+
test_gem_home_path = Dir.glob("#{specdir}/functional/test_gem_home_spec.rb")[0]
|
11
|
+
spec_files.delete(test_gem_home_path)
|
12
|
+
spec_files.unshift(test_gem_home_path)
|
12
13
|
spec_files.uniq
|
13
14
|
|
14
15
|
args = spec_files
|
@@ -18,14 +19,18 @@ args << "specdoc"
|
|
18
19
|
args << "--diff"
|
19
20
|
args << "unified"
|
20
21
|
|
21
|
-
|
22
|
+
# append generated args to ARGV. THis may break if incompatible args are specified,
|
23
|
+
# but I don't know a better way to invoke Rspec 1.1.1 programatically and check the return value
|
24
|
+
ARGV.concat(args)
|
22
25
|
|
23
|
-
|
26
|
+
success = false
|
24
27
|
begin
|
25
|
-
|
28
|
+
require 'spec'
|
29
|
+
success = ::Spec::Runner::CommandLine.run(rspec_options)
|
26
30
|
ensure
|
27
|
-
$server_was_stopped = GemInstaller::EmbeddedGemServer.stop
|
28
31
|
GemInstaller::TestGemHome.reset
|
29
32
|
end
|
30
|
-
|
31
|
-
raise "
|
33
|
+
# not sure what Spec::Runner::CommandLine.run can return, but fail if it's not boolean as expected
|
34
|
+
raise "unexpected non-boolean return value from Spec::Runner::CommandLine.run(rspec_options)" unless success == true || success == false
|
35
|
+
|
36
|
+
raise "Specs failed" unless success
|
data/website/metainfo.yaml
CHANGED
@@ -57,16 +57,22 @@ community/rubyforge.html:
|
|
57
57
|
title: Rubyforge
|
58
58
|
orderInfo: 40
|
59
59
|
|
60
|
+
code/ci:
|
61
|
+
url: http://ci.thewoolleyweb.com
|
62
|
+
inMenu: true
|
63
|
+
title: CI
|
64
|
+
orderInfo: 20
|
65
|
+
|
60
66
|
code/rdoc:
|
61
67
|
url: rdoc/index.html
|
62
68
|
inMenu: true
|
63
69
|
title: Rdoc
|
64
|
-
orderInfo:
|
70
|
+
orderInfo: 30
|
65
71
|
|
66
72
|
code/coverage:
|
67
73
|
url: coverage/index.html
|
68
74
|
inMenu: true
|
69
75
|
title: Coverage
|
70
|
-
orderInfo:
|
76
|
+
orderInfo: 40
|
71
77
|
|
72
78
|
|
data/website/src/code/index.page
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
---
|
2
2
|
title: Design
|
3
3
|
---
|
4
|
+
<span id="release_process"/>
|
4
5
|
h1. Design Notes
|
5
6
|
|
6
7
|
These are some notes on the underlying design of GemInstaller, and the current state of development:
|
@@ -21,5 +22,51 @@ These are some notes on the underlying design of GemInstaller, and the current s
|
|
21
22
|
*** Functional Specs: These also have a one-to-one relationship with classes for the most part - geminstaller_spec is an exception. Most of these test how groups of classes interact together at various levels. Most of them use the "Test Gem Home" fixture approach. This is effective, but adds several seconds to the startup of each run. There is also overlap between some of them, especially at high levels of the API, which adds some maintenance overhead, but is worth it to me since it helps catch integration bugs.
|
22
23
|
*** Smoke Tests: There are some tests under /spec/smoketests which I run manually. These are really coarse grained scripts, and don't use Rspec or Test::Unit. They hit the live rubygems.org gem repository, and install/uninstall actual gems. They are used as a periodic check to ensure that my "Test Gem Home" fixture approach is not masking any real-life bugs.
|
23
24
|
* I'm a proponent of high code coverage. I check periodically to ensure I maintain close to 100% code coverage, not counting platform- and version-specific code blocks (and I'll get around to those some day). Also, the sudo recursive invocation stuff still needs some tests, but that's a bit tricky to automate.
|
24
|
-
* The tests are
|
25
|
-
*
|
25
|
+
* The tests are "harder" on Windows (but run fine on mac/linux). The app should work fine, but testing is pretty tricky. I have all tests working against the latest rubygems (1.0.1). Here's what does and doesn't work with tests against latest rubygems on windows:
|
26
|
+
* smoketest.rb and autogem_test.rb work
|
27
|
+
* ruby test/test_all.rb works
|
28
|
+
* rake default test task does not work (this seems to be a problem with hoe on windows)
|
29
|
+
* Sometimes test suite still hangs after a while, this is probably some orphaned EmbeddedGemServer process somewhere. A reboot should fix it - this is windows, after all!
|
30
|
+
* One of my motivations for creating GemInstaller was as an exercise to help me learn Ruby better. If you see me doing anything obviously dumb or inefficient in the code or design, please let me know. Some of them I already know about, but haven't fixed, most I'm probably not aware of :)
|
31
|
+
|
32
|
+
<span id="rubygems_compatibility"/>
|
33
|
+
h1. Maintaining forward and backward compatibility with multiple RubyGems versions
|
34
|
+
|
35
|
+
* I've put a lot of effort into ensuring that GemInstaller works with older versions of RubyGems. As of now (2008-01-01) all specs (not smoketests) are green on mac/linux against RubyGems versions 0.8.11, 0.9.4, 0.9.5, 1.0.0, and 1.0.1. On Windows, smoketests and specs are green against 1.0.1. I haven't figured out how to automate testing against older RubyGems versions without a reinstall on Windows, so let me know if something is broken (or just upgrade).
|
36
|
+
|
37
|
+
* This wasn't as hard as it seems. The hardest part was figuring out what was different between versions. Once you understand that, you can add switch statements to perform different logic or tests depending on the version (which is easy if you use rubygems built in Version Requirement support - see GemInstaller::RubygemsVersionChecker).
|
38
|
+
|
39
|
+
* To run against different RubyGems versions, I have a RUBYGEMS_VERSION environment variable which causes the correct version or RubyGems in spec/fixture/rubygems_dist to be put on the load path and used for the test run.
|
40
|
+
|
41
|
+
* RubyGems 0.9.5 was a major upgrade, the preview release for 1.0. It introduced support for platforms, auto-install of missing dependencies, and many other things that GemInstaller already did.
|
42
|
+
|
43
|
+
* Here are the main differences in GemInstaller when running on RubyGems >=0.9.5:
|
44
|
+
** Don't use missing dependency finder (auto-install of missing dependencies is now built in)
|
45
|
+
** Don't use valid platform selector, use --platform option (auto-selection of platform is now built in)
|
46
|
+
** GemInteractionHandler should throw error on any interactive prompt (since dependencies and platforms are now handled automatically by default)
|
47
|
+
** The "<code>prefer_binary_platform</code> config property":../documentation/documentation.html#prefer_binary_platform_config_property no longer applies, and has no effect.
|
48
|
+
|
49
|
+
<span id="release_process"/>
|
50
|
+
h1. Release Process
|
51
|
+
|
52
|
+
Yeah, it's too manual. Notes for improvement below.
|
53
|
+
|
54
|
+
* Add section and entries for new release to History.txt
|
55
|
+
* Add same history info to history section on homepage.
|
56
|
+
* Update version in geminstaller.rb
|
57
|
+
* rake update_manifest
|
58
|
+
* Run tests:
|
59
|
+
* CI should be green for all versions
|
60
|
+
* smoketest.rb and autogem_test.rb should pass for all RubyGems versions on mac/linux
|
61
|
+
* test_all, smoketest.rb and autogem_test.rb should pass for latest RubyGems version on windows
|
62
|
+
* Make sure everything is checked in
|
63
|
+
* Make a tag in svn
|
64
|
+
* rake clean package
|
65
|
+
* Upload gem to rubyforge
|
66
|
+
* rake publish_website
|
67
|
+
|
68
|
+
Here's the improvements I need to make to the release process:
|
69
|
+
|
70
|
+
* Avoid duplication of history file to display on home page
|
71
|
+
* Make CI automatically build and tag a gem/package with next version + revision: x.y.z.<svn revision>
|
72
|
+
* Rake task to automatically tag and release latest build from CI and tag
|