pik 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/History.txt +13 -0
  2. data/Manifest.txt +35 -1
  3. data/README.rdoc +99 -39
  4. data/Rakefile +49 -8
  5. data/bin/pik_install +23 -0
  6. data/features/add_command.feature +28 -0
  7. data/features/checkup_command.feature +0 -0
  8. data/features/config_command.feature +12 -0
  9. data/features/default_command.feature +12 -0
  10. data/features/env.rb +52 -0
  11. data/features/gemsync_command.feature +0 -0
  12. data/features/help_command.feature +13 -0
  13. data/features/implode_command.feature +12 -0
  14. data/features/install_command.feature +13 -0
  15. data/features/list_command.feature +18 -0
  16. data/features/remove_command.feature +18 -0
  17. data/features/run_command.feature +22 -0
  18. data/features/step_definitions/pik_commands.rb +140 -0
  19. data/features/switch_command.feature +35 -0
  20. data/features/tag_command.feature +18 -0
  21. data/features/version.feature +9 -0
  22. data/lib/pik.rb +17 -3
  23. data/lib/pik/commands/add_command.rb +6 -6
  24. data/lib/pik/commands/batch_file_editor.rb +22 -8
  25. data/lib/pik/commands/checkup_command.rb +5 -2
  26. data/lib/pik/commands/command.rb +30 -26
  27. data/lib/pik/commands/config_command.rb +54 -2
  28. data/lib/pik/commands/default_command.rb +19 -5
  29. data/lib/pik/commands/help_command.rb +1 -1
  30. data/lib/pik/commands/implode_command.rb +12 -1
  31. data/lib/pik/commands/install_command.rb +182 -0
  32. data/lib/pik/commands/list_command.rb +3 -2
  33. data/lib/pik/commands/remove_command.rb +6 -6
  34. data/lib/pik/commands/run_command.rb +70 -10
  35. data/lib/pik/commands/switch_command.rb +10 -10
  36. data/lib/pik/commands/tag_command.rb +56 -0
  37. data/lib/pik/config_file.rb +26 -2
  38. data/lib/pik/contrib/progressbar.rb +237 -0
  39. data/lib/pik/contrib/unzip.rb +14 -0
  40. data/lib/pik/contrib/uri_ext.rb +296 -0
  41. data/lib/pik/contrib/zip/ioextras.rb +155 -0
  42. data/lib/pik/contrib/zip/stdrubyext.rb +111 -0
  43. data/lib/pik/contrib/zip/tempfile_bugfixed.rb +195 -0
  44. data/lib/pik/contrib/zip/zip.rb +1846 -0
  45. data/lib/pik/contrib/zip/zipfilesystem.rb +609 -0
  46. data/lib/pik/contrib/zip/ziprequire.rb +90 -0
  47. data/lib/pik/core_ext/pathname.rb +20 -7
  48. data/lib/pik/search_path.rb +21 -13
  49. data/lib/pik/which.rb +52 -0
  50. data/lib/pik/windows_env.rb +64 -25
  51. data/spec/add_command_spec.rb +0 -2
  52. data/spec/batch_file_spec.rb +3 -3
  53. data/spec/command_spec.rb +0 -7
  54. data/spec/gemsync_command_spec.rb +1 -1
  55. data/spec/help_command_spec.rb +1 -1
  56. data/spec/list_command_spec.rb +1 -1
  57. data/spec/pathname_spec.rb +30 -0
  58. data/spec/remove_command_spec.rb +6 -6
  59. data/spec/run_command_spec.rb +2 -30
  60. data/spec/search_path_spec.rb +9 -0
  61. data/spec/switch_command_spec.rb +14 -2
  62. data/spec/which_spec.rb +7 -0
  63. data/tools/pik.bat +2 -0
  64. data/tools/pik/pik +45 -0
  65. data/tools/pik/pik.exe +0 -0
  66. data/tools/pik/pik.exy +198 -0
  67. metadata +50 -21
  68. data/bin/pik +0 -33
File without changes
@@ -0,0 +1,13 @@
1
+ Feature: display help information
2
+ In order to know how to use pik
3
+ A developer
4
+ Wants an interface to the program
5
+ So that he can display help information
6
+
7
+ Scenario: Getting help
8
+ When I run "pik help"
9
+ Then I should see "Usage: pik command [options]"
10
+ And I should see "To get help with a command"
11
+ And I should see " pik help (command)"
12
+ And I should see "To list all commands and descriptions:"
13
+ And I should see " pik help commands"
@@ -0,0 +1,12 @@
1
+ Feature: implode command
2
+ In order to delete all pik configuration data
3
+ A developer
4
+ Wants an interface to the program
5
+ So that he can delete all pik configuration data
6
+
7
+
8
+ Scenario: pik implode
9
+ Given I have a directory "C:/temp/.pik"
10
+ And it contains a config.yml
11
+ When I run "pik implode -f"
12
+ Then the directory should be deleted
@@ -0,0 +1,13 @@
1
+ Feature: install command
2
+ In order to keep up to date with multiple ruby implementations
3
+ A developer
4
+ Wants a command line tool
5
+ So that he can download and install them
6
+
7
+ Scenario: install from the intarwebs
8
+ When I run "pik install ruby"
9
+ Then I should see "** Downloading: http://rubyforge.org/frs/download.php/62269/ruby-1.9.1-p243-i386-mingw32.7z"
10
+ And I should see " to: c:\temp\.pik"
11
+ And I should see "** Extracting: c:\temp\.pik\downloads"
12
+ And I should see "** Adding: "
13
+
@@ -0,0 +1,18 @@
1
+ Feature: list command
2
+ In order to list ruby versions that pik is aware of
3
+ A developer
4
+ Wants an interface to the program
5
+ So that he can list configuration information
6
+
7
+ Scenario: list versions
8
+ When I run "pik list"
9
+ Then I should find "^\d+\: .+ruby"
10
+
11
+ Scenario: Determining the current ruby version from the list
12
+ When I run "pik list"
13
+ Then I should find "^\d+\: .+\*$"
14
+
15
+ Scenario: list verbose output
16
+ When I run "pik list -v"
17
+ Then I should find "^\d+\: .+\*$"
18
+ And I should find "path\: C\:[\\\/].+"
@@ -0,0 +1,18 @@
1
+ Feature: remove command
2
+ In order to remove ruby versions from pik
3
+ A developer
4
+ Wants a command line interface
5
+ So that she can remove versions.
6
+
7
+ Scenario: remove a version from the config
8
+ Given I have already added "ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32]"
9
+ When I run "pik remove 186 min -f"
10
+ Then I should see "removed"
11
+ And the version should be removed.
12
+
13
+ Scenario: remove a version from the config and the filesystem
14
+ Given I have already added "ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32]"
15
+ When I run "pik remove 186 min -f "
16
+ Then I should see "removed"
17
+ And the version should be removed.
18
+
@@ -0,0 +1,22 @@
1
+ Feature: run command
2
+ In order to test code against different ruby implementations
3
+ A developer
4
+ Wants an interface to the program
5
+ So that he can run commands against all versions that pik is aware of
6
+
7
+ Scenario: run code
8
+ When I run "pik run "path""
9
+ Then I should find "PATH=" 9 times
10
+ And I should see each version's path listed
11
+ And I should see each version listed.
12
+
13
+ Scenario: ruby command
14
+ When I run "pik ruby -e "puts 'hello world!'" "
15
+ Then I should find "hello world!" 9 times
16
+ And I should see each version listed.
17
+
18
+ Scenario: gem command
19
+ When I run "pik gem -v"
20
+ Then I should find "\n\d\.\d\.\d\n" 9 times
21
+ And I should see each version listed.
22
+
@@ -0,0 +1,140 @@
1
+ require 'yaml'
2
+ require 'pathname'
3
+ require 'fileutils'
4
+
5
+ PIK_LOG = 'log\\output.log'
6
+ PIK_HOME = Pathname.new( ENV['HOME'] || ENV['USERPROFILE'] ) + '.pik'
7
+
8
+ Given /^I have.+added "(.+)"/ do |version|
9
+ @version = version
10
+ @version_reg = Regexp.new(Regexp.escape(version), Regexp::IGNORECASE)
11
+ @config_file = PIK_HOME + 'config.yml'
12
+ @original_config = YAML.load(File.read(@config_file))
13
+ @ver = @original_config.keys.grep(@version_reg){|k| @original_config[k] }
14
+ @ver.size.should eql(1)
15
+ end
16
+
17
+ Given /^I am currently using it\.$/ do
18
+ unless `ruby -v` =~ @version_reg
19
+ k,v = `pik switch #{@version} & path`.split('=')
20
+ ENV[k]=v
21
+ end
22
+ `ruby -v`.should match(@version_reg)
23
+ end
24
+
25
+ Given /^I am currently using "(.+)"$/ do |version|
26
+ Given "I have added \"#{version}\""
27
+ Given "I am currently using it."
28
+ end
29
+
30
+ Given /^I have a directory "(.+)"/ do |directory|
31
+ @dir = directory
32
+ Pathname(@dir).directory?.should be_true
33
+ end
34
+
35
+ Given /^it contains a config\.yml/ do
36
+ config = Pathname(@dir) + 'config.yml'
37
+ config.should exist
38
+ end
39
+
40
+ Given /^I have no \.pik directory/ do
41
+ FileUtils.rm_rf PIK_HOME
42
+ PIK_HOME.should_not exist
43
+ end
44
+
45
+ Given /^I have an empty config\.yml/ do
46
+ File.open(PIK_HOME + 'config.yml','w'){|f| }
47
+ end
48
+
49
+ When /^I run "pik (.+?)" and "pik (.+)",$/ do |args1, args2|
50
+ %x[tools\\pik.bat #{args1} > #{PIK_LOG} 2>&1 && tools\\pik.bat #{args2} > #{PIK_LOG} 2>&1]
51
+ end
52
+
53
+ When /^I run "pik (.+?)"$/ do |args|
54
+ %x[tools\\pik.bat #{args} > #{PIK_LOG} 2>&1 ]
55
+ end
56
+
57
+ When /^I run "pik (.*)" and check the path$/ do |args|
58
+ %x[tools\\pik.bat #{args} > #{PIK_LOG} 2>&1 & PATH >> #{PIK_LOG} ]
59
+ end
60
+
61
+ Then /^I should see "(.*)"$/ do |data|
62
+ stdout = File.read(PIK_LOG)
63
+ stdout.should match(Regexp.new(Regexp.escape(data)))
64
+ end
65
+
66
+ Then /^I should find "(.*)"$/ do |regexp|
67
+ stdout = File.read(PIK_LOG)
68
+ stdout.should match(Regexp.new(regexp))
69
+ end
70
+
71
+
72
+ Then /^I should find "(.*)" (\d+) times$/ do |regexp, count|
73
+ stdout = File.read(PIK_LOG)
74
+ items = stdout.scan(Regexp.new(regexp))
75
+ items.size.should eql(count.to_i)
76
+ end
77
+
78
+ Then /^the path should point to it\.$/ do
79
+ path = @ver[0][:path]
80
+ path = path.to_s.gsub('/','\\')
81
+ Then "the path should point to \"#{path}\""
82
+ end
83
+
84
+ Then /^the path should point to "(.+)"$/ do |path|
85
+ stdout = File.read(PIK_LOG)
86
+ stdout.should match( Regexp.new(Regexp.escape(path)) )
87
+ end
88
+
89
+
90
+ Then /^I should see each version.s path listed$/ do
91
+ stdout = File.read(PIK_LOG)
92
+ config_file = PIK_HOME + 'config.yml'
93
+ config = YAML.load(File.read(config_file))
94
+ config.each{|k,v|
95
+ path = Regexp.new(Regexp.escape(v[:path].to_s.gsub('/','\\')))
96
+ stdout.should match(path)
97
+ }
98
+ end
99
+
100
+ Then /^I should see each version listed\.$/ do
101
+ stdout = File.read(PIK_LOG)
102
+ config_file = PIK_HOME + 'config.yml'
103
+ config = YAML.load(File.read(config_file))
104
+ config.each{|k,v|
105
+ version = Regexp.new(Regexp.escape(k.split(': ')[1..-1].join(': ')))
106
+ stdout.should match(version)
107
+ }
108
+ end
109
+
110
+ Then /^the GEM_HOME might get set\.$/ do
111
+ gem_home = @ver[0][:gem_home]
112
+ if gem_home
113
+ gem_home = gem_home.to_s.gsub('/','\\')
114
+ reg_gem_home = Regexp.new(Regexp.escape(gem_home), Regexp::IGNORECASE)
115
+ stdout = File.read(PIK_LOG)
116
+ stdout.should match(reg_gem_home)
117
+ end
118
+ end
119
+
120
+ Then /^the directory should be deleted$/ do
121
+ Pathname(@dir).should_not exist
122
+ end
123
+
124
+ Then /^nothing should be added to the config file\.$/ do
125
+ @current_config = YAML.load(File.read(@config_file))
126
+ @current_config.size.should eql(@original_config.size)
127
+ end
128
+
129
+ Then /^the version should be removed\.$/ do
130
+ @current_config = YAML.load(File.read(@config_file))
131
+ @current_config.size.should eql(@original_config.size - 1)
132
+ end
133
+
134
+
135
+ Then /^a gem_home option should be added to the config\.$/ do
136
+ @ver[0][:gem_home].should be_nil
137
+ @current_config = YAML.load(File.read(@config_file))
138
+ @ver = @current_config.keys.grep(@version_reg){|k| @current_config[k] }
139
+ @ver[0][:gem_home].should_not be_nil
140
+ end
@@ -0,0 +1,35 @@
1
+ Feature: switch command
2
+ In order to switch from one ruby version to another
3
+ A developer
4
+ Wants an interface to the program
5
+ So that she can easily update the path and other environment variables.
6
+
7
+ Scenario Outline: Switching versions with switch command
8
+ Given I have added "<version>" to pik
9
+ When I run "pik switch <patterns> -v" and check the path
10
+ Then I should see "<version>"
11
+ And the path should point to it.
12
+ And the GEM_HOME might get set.
13
+
14
+ Examples:
15
+ | version | patterns |
16
+ | IronRuby 0.9.1.0 on .NET 2.0.0.0 | Ir 91 |
17
+ | jruby 1.4.0RC1 (ruby 1.8.7 patchlevel 174) | jruby 1.4 |
18
+ | ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32] | 186 ms |
19
+ | ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32] | 186 mi |
20
+ | ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-mingw32] | 191 p2 |
21
+
22
+ Scenario Outline: Switching versions with pattern only
23
+ Given I have added "<version>" to pik
24
+ When I run "pik <patterns>" and check the path
25
+ Then the path should point to it.
26
+ And the GEM_HOME might get set.
27
+
28
+ Examples:
29
+ | version | patterns |
30
+ | IronRuby 0.9.1.0 on .NET 2.0.0.0 | Ir 91 |
31
+ | jruby 1.4.0RC1 (ruby 1.8.7 patchlevel 174) | jruby 1.4 |
32
+ | ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32] | 186 ms |
33
+ | ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32] | 186 mi |
34
+ | ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-mingw32] | 191 p2 |
35
+
@@ -0,0 +1,18 @@
1
+ Feature: tag command
2
+ In order to test code against specific ruby implementations
3
+ A developer
4
+ Wants an interface to the program
5
+ So that he can tag versions that pik is aware of
6
+
7
+ Scenario: tag version
8
+ When I run "pik Ir 91" and "pik tag iron",
9
+ And I run "pik config list"
10
+ Then I should find "tags: \n iron:"
11
+ And I should see " - 091: IronRuby 0.9.1.0 on .NET 2.0.0.0"
12
+
13
+ Scenario: run tagged versions
14
+ When I run "pik Ir 91" and "pik tag iron",
15
+ And I run "pik Ir 90" and "pik tag iron",
16
+ And I run "pik tags iron run echo."
17
+ Then I should find "IronRuby 0.9.1.0 on .NET 2.0.0.0"
18
+ And I should find "IronRuby 0.9.0.0 on .NET 2.0.0.0"
@@ -0,0 +1,9 @@
1
+ Feature: display pik version
2
+ In order to know what version pik is at
3
+ A developer
4
+ Wants an interface to the program
5
+ So that he can display version information
6
+
7
+ Scenario: Listing versions
8
+ When I run "pik -V"
9
+ Then I should find "^pik \d.\d.\d"
data/lib/pik.rb CHANGED
@@ -1,9 +1,11 @@
1
1
  module Pik
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
4
4
 
5
- require 'highline'
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ require 'yaml'
6
7
  require 'pathname'
8
+ require 'fileutils'
7
9
  require 'rbconfig'
8
10
 
9
11
  require 'pik/core_ext/pathname'
@@ -11,6 +13,7 @@ require 'pik/commands'
11
13
  require 'pik/commands/config_file_editor'
12
14
  require 'pik/commands/batch_file_editor'
13
15
  require 'pik/commands/command'
16
+ require 'pik/commands/install_command'
14
17
  require 'pik/commands/list_command'
15
18
  require 'pik/commands/add_command'
16
19
  require 'pik/commands/help_command'
@@ -22,9 +25,20 @@ require 'pik/commands/config_command'
22
25
  require 'pik/commands/gemsync_command'
23
26
  require 'pik/commands/default_command'
24
27
  require 'pik/commands/implode_command'
28
+ require 'pik/commands/tag_command'
25
29
  require 'pik/config_file'
26
30
  require 'pik/windows_env'
31
+ require 'pik/which'
27
32
  require 'pik/batch_file'
28
33
  require 'pik/search_path'
29
34
 
30
- PIK_HOME = Pathname.new( ENV['HOME'] || ENV['USERPROFILE'] ) + '.pik'
35
+ require 'highline'
36
+
37
+ PIK_HOME = Pathname.new( ENV['HOME'] || ENV['USERPROFILE'] ) + '.pik'
38
+
39
+ if defined? ExerbRuntime
40
+ PIK_BATCH = Pathname.new(ARGV.shift).ruby
41
+ else
42
+ pik_exe = Pathname.new($0).expand_path + '..'
43
+ PIK_BATCH = pik_exe.dirname + "#{pik_exe.basename}.bat"
44
+ end
@@ -9,20 +9,20 @@ module Pik
9
9
 
10
10
  def execute(path=nil)
11
11
  return add_interactive if interactive
12
- path = @args.first || ::Config::CONFIG['bindir']
12
+ path = @args.first || Which::Ruby.find
13
13
  add(path)
14
14
  end
15
15
 
16
16
  def add(path)
17
17
  path = Pathname.new(path)
18
18
  path = path.dirname if path.file?
19
- if ruby_exists_at?(path)
20
- if config[get_version(path)]
19
+ if Which::Ruby.exist?(path)
20
+ if find_config_from_path(path)
21
21
  puts "This version has already been added."
22
22
  else
23
23
  version = get_version(path)
24
- path = path.expand_path.to_ruby
25
- puts "Adding: #{version}'\n Located at: #{path}\n"
24
+ path = Pathname(path.expand_path.to_ruby)
25
+ puts "** Adding: #{version}\n Located at: #{path}\n"
26
26
  @config[version] = {}
27
27
  @config[version][:path] = path
28
28
  end
@@ -50,7 +50,7 @@ module Pik
50
50
  }
51
51
  menu.choice('s]earch'){
52
52
  search_dir = @hl.ask("Enter a search path")
53
- files = ruby_glob(search_dir + '**')
53
+ files = Which::Ruby.glob(search_dir + '**')
54
54
  files.each{|file|
55
55
  dir = File.dirname(file)
56
56
  add(dir) if @hl.agree("Add '#{dir}'? [Yn] ")
@@ -24,12 +24,25 @@ module Pik
24
24
  end
25
25
 
26
26
  def switch_path_to(new_ver)
27
- dir = current_ruby_bin_path
27
+ dir = Which::Ruby.find
28
+ current_config = config[ find_config_from_path(dir) ]
29
+
28
30
  new_path = SearchPath.new(ENV['PATH']).replace_or_add(dir, new_ver[:path])
29
- if new_ver[:gem_home]
30
- new_path.replace_or_add(current_gem_bin_path, Pathname.new(new_ver[:gem_home]) + 'bin')
31
+ if new_gem_home = new_ver[:gem_home]
32
+
33
+ new_gem_bin = Pathname.new(new_gem_home) + 'bin'
34
+
35
+ if current_gem_home = current_config[:gem_home]
36
+ current_gem_bin = Pathname.new(current_gem_home) + 'bin'
37
+ new_path.replace(current_gem_bin, new_gem_bin)
38
+ else
39
+ new_path.add(new_gem_bin)
40
+ end
31
41
  else
32
- new_path.remove(current_gem_bin_path)
42
+ if current_gem_home = current_config[:gem_home]
43
+ current_gem_bin = Pathname.new(current_gem_home) + 'bin'
44
+ new_path.remove(current_gem_bin)
45
+ end
33
46
  end
34
47
  @batch.set('PATH' => new_path.join )
35
48
  end
@@ -41,16 +54,17 @@ module Pik
41
54
  @batch.set('GEM_HOME' => gem_path )
42
55
  end
43
56
 
44
- def echo_ruby_version(verb='Using')
45
- @batch.file_data << "for /f \"delims=\" %%a in ('ruby -v') do @echo #{verb} %%a "
57
+ def echo_ruby_version(path, verb='')
58
+ rb = Which::Ruby.exe(path).basename
59
+ @batch.file_data << "for /f \"delims=\" %%a in ('#{rb} -v') do @echo #{verb} %%a "
46
60
  end
47
61
 
48
- def echo_running_with_ruby_version
62
+ def echo_running_with_ruby_version(path)
49
63
  echo_ruby_version('Running with')
50
64
  end
51
65
 
52
66
  def update_gem_batch
53
- BatchFile.open("#{$0}.bat") do |gem_bat|
67
+ BatchFile.open(PIK_BATCH) do |gem_bat|
54
68
  # call new .pik/pik batch
55
69
  gem_bat.call(%Q("#{@batch.path.to_windows}")) if @batch
56
70
  gem_bat.write
@@ -17,7 +17,7 @@ module Pik
17
17
  end
18
18
 
19
19
  def rubyopt
20
- unless WindowsEnv.user['rubyopt'].empty? && WindowsEnv.system['rubyopt'].empty?
20
+ unless WindowsEnv.user['rubyopt'].nil? && WindowsEnv.system['rubyopt'].nil?
21
21
  fail('rubyopt')
22
22
  else
23
23
  pass('rubyopt')
@@ -33,7 +33,9 @@ module Pik
33
33
  end
34
34
 
35
35
  def path
36
- dirs = (WindowsEnv.user['path'] + WindowsEnv.system['path']).split(';')
36
+ user_path = WindowsEnv.user['path'] || ''
37
+ syst_path = WindowsEnv.system['path'] || ''
38
+ dirs = (user_path + syst_path).split(';')
37
39
  dirs = dirs.select{|dir| File.exist?( File.join(dir,'ruby.exe') ) }
38
40
  unless dirs.size == 1
39
41
  fail('path')
@@ -59,6 +61,7 @@ module Pik
59
61
 
60
62
  def fail(test)
61
63
  print 'F'
64
+ $stdout.flush
62
65
  # @output << @text[test][:fail]
63
66
  end
64
67