pik 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,90 @@
1
+ # With ziprequire you can load ruby modules from a zip file. This means
2
+ # ruby's module include path can include zip-files.
3
+ #
4
+ # The following example creates a zip file with a single entry
5
+ # <code>log/simplelog.rb</code> that contains a single function
6
+ # <code>simpleLog</code>:
7
+ #
8
+ # require 'zip/zipfilesystem'
9
+ #
10
+ # Zip::ZipFile.open("my.zip", true) {
11
+ # |zf|
12
+ # zf.file.open("log/simplelog.rb", "w") {
13
+ # |f|
14
+ # f.puts "def simpleLog(v)"
15
+ # f.puts ' Kernel.puts "INFO: #{v}"'
16
+ # f.puts "end"
17
+ # }
18
+ # }
19
+ #
20
+ # To use the ruby module stored in the zip archive simply require
21
+ # <code>zip/ziprequire</code> and include the <code>my.zip</code> zip
22
+ # file in the module search path. The following command shows one
23
+ # way to do this:
24
+ #
25
+ # ruby -rzip/ziprequire -Imy.zip -e " require 'log/simplelog'; simpleLog 'Hello world' "
26
+
27
+ #$: << 'data/rubycode.zip' << 'data/rubycode2.zip'
28
+
29
+
30
+ require 'zip/zip'
31
+
32
+ class ZipList #:nodoc:all
33
+ def initialize(zipFileList)
34
+ @zipFileList = zipFileList
35
+ end
36
+
37
+ def get_input_stream(entry, &aProc)
38
+ @zipFileList.each {
39
+ |zfName|
40
+ Zip::ZipFile.open(zfName) {
41
+ |zf|
42
+ begin
43
+ return zf.get_input_stream(entry, &aProc)
44
+ rescue Errno::ENOENT
45
+ end
46
+ }
47
+ }
48
+ raise Errno::ENOENT,
49
+ "No matching entry found in zip files '#{@zipFileList.join(', ')}' "+
50
+ " for '#{entry}'"
51
+ end
52
+ end
53
+
54
+
55
+ module Kernel #:nodoc:all
56
+ alias :oldRequire :require
57
+
58
+ def require(moduleName)
59
+ zip_require(moduleName) || oldRequire(moduleName)
60
+ end
61
+
62
+ def zip_require(moduleName)
63
+ return false if already_loaded?(moduleName)
64
+ get_resource(ensure_rb_extension(moduleName)) {
65
+ |zis|
66
+ eval(zis.read); $" << moduleName
67
+ }
68
+ return true
69
+ rescue Errno::ENOENT => ex
70
+ return false
71
+ end
72
+
73
+ def get_resource(resourceName, &aProc)
74
+ zl = ZipList.new($:.grep(/\.zip$/))
75
+ zl.get_input_stream(resourceName, &aProc)
76
+ end
77
+
78
+ def already_loaded?(moduleName)
79
+ moduleRE = Regexp.new("^"+moduleName+"(\.rb|\.so|\.dll|\.o)?$")
80
+ $".detect { |e| e =~ moduleRE } != nil
81
+ end
82
+
83
+ def ensure_rb_extension(aString)
84
+ aString.sub(/(\.rb)?$/i, ".rb")
85
+ end
86
+ end
87
+
88
+ # Copyright (C) 2002 Thomas Sondergaard
89
+ # rubyzip is free software; you can redistribute it and/or
90
+ # modify it under the terms of the ruby license.
@@ -1,15 +1,28 @@
1
1
 
2
2
  class Pathname
3
3
 
4
- def to_windows
5
- @path.gsub!('/','\\')
6
- self
4
+ def to_s
5
+ @path.gsub('/','\\')
7
6
  end
7
+ alias to_windows to_s
8
8
 
9
9
  def to_ruby
10
- @path.gsub!('\\','/')
11
- self
10
+ @path.gsub('\\','/')
12
11
  end
13
-
12
+
13
+ def ruby
14
+ Pathname(self.to_ruby)
15
+ end
16
+
17
+ def windows
18
+ Pathname(self.to_s)
19
+ end
20
+
21
+ def ==(other)
22
+ return false unless Pathname === other
23
+ self_ = self.dup.to_ruby.downcase
24
+ other = other.dup.to_ruby.downcase
25
+ self_ == other
26
+ end
27
+
14
28
  end
15
-
@@ -1,38 +1,46 @@
1
1
 
2
2
  class SearchPath
3
3
 
4
+ include Enumerable
5
+
4
6
  def initialize(path)
5
- @path = path.to_s.split(';')
7
+ @path = path.to_s.split(';').reject{|i| i.empty? }
6
8
  end
7
9
 
8
10
  def remove(old_path)
9
- old = Pathname.new(old_path).to_windows
10
- @path.reject!{|dir| dir =~ regex(old.to_s) }
11
+ old = Pathname(old_path).expand_path.to_windows
12
+ @path = @path.reject{|dir| Pathname(dir) == old }
13
+ @path = @path.uniq
11
14
  self
12
15
  end
13
16
 
14
17
  def replace(old_path, new_path)
15
-
16
- old_path = Pathname.new(old_path)
17
- new_path = Pathname.new(new_path)
18
+ old_path = Pathname(old_path)
19
+ new_path = Pathname(new_path)
18
20
  @path.map!{|dir|
19
- case dir
20
- when regex(old_path.to_windows)
21
- new_path.to_windows.to_s
22
- else
23
- dir
21
+ if Pathname(dir) == old_path
22
+ new_path.to_windows.to_s
23
+ else
24
+ dir
24
25
  end
25
- }.uniq.compact
26
+ }
27
+ @path = @path.uniq.compact
26
28
  self
27
29
  end
30
+
31
+ def each
32
+ @path.each{|path| yield path }
33
+ end
28
34
 
29
35
  def add(new_path)
30
- new_path = Pathname.new(new_path)
36
+ new_path = Pathname(new_path)
31
37
  @path << new_path.to_windows.to_s
32
38
  self
33
39
  end
34
40
 
35
41
  def replace_or_add(old_path, new_path)
42
+ old_path = Pathname(old_path)
43
+ new_path = Pathname(new_path)
36
44
  return self if old_path == new_path
37
45
  old_search_path = @path.dup
38
46
  replace(old_path, new_path)
@@ -0,0 +1,52 @@
1
+
2
+ module Which
3
+
4
+ class Base
5
+
6
+ class << self
7
+ def find(search_path=ENV['PATH'])
8
+ path = SearchPath.new(search_path)
9
+ path = path.find{|dir| exist?(dir)}
10
+ Pathname(path) rescue nil
11
+ end
12
+
13
+ def exist?(path)
14
+ !!exe(path)
15
+ end
16
+
17
+ def exe(path=find)
18
+ glob(path).first
19
+ end
20
+ alias :bat :exe
21
+
22
+ def glob(path)
23
+ return [] if path.nil?
24
+ glob = "#{Pathname.new(path).to_ruby}/{#{executables.join(',')}}"
25
+ Pathname.glob(glob)
26
+ end
27
+ end
28
+ end
29
+
30
+ class Ruby < Base
31
+
32
+ def self.executables
33
+ ['ruby.exe', 'ir.exe', 'jruby.exe', 'jruby.bat']
34
+ end
35
+
36
+ end
37
+
38
+ class Gem < Base
39
+
40
+ def self.executables
41
+ ['gem.bat', 'igem.bat']
42
+ end
43
+
44
+ end
45
+
46
+ class SevenZip < Base
47
+ def self.executables
48
+ ['7za.exe']
49
+ end
50
+ end
51
+
52
+ end
@@ -1,17 +1,25 @@
1
- require 'win32ole'
1
+ require 'win32/registry'
2
+ require 'Win32API'
3
+
2
4
 
3
5
  class WindowsEnv
4
6
 
5
7
  def self.system
6
- @system ||= new('SYSTEM', shell)
8
+ key = :HKEY_LOCAL_MACHINE
9
+ subkey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
10
+ new(key, subkey)
7
11
  end
8
12
 
9
13
  def self.user
10
- @user ||= new('User', shell)
14
+ key = :HKEY_CURRENT_USER
15
+ subkey = 'Environment'
16
+ new(key, subkey)
11
17
  end
12
18
 
13
- def initialize(account, shell)
14
- @env = shell.environment(account)
19
+ def initialize(key, subkey)
20
+ @key = key
21
+ @subkey = subkey
22
+ @reg = Reg.new
15
23
  end
16
24
 
17
25
  def set(items)
@@ -19,7 +27,7 @@ class WindowsEnv
19
27
  end
20
28
 
21
29
  def [](name)
22
- @env.item(name)
30
+ @reg.open(@key, @subkey, name)
23
31
  end
24
32
 
25
33
  def []=(name, other)
@@ -34,31 +42,62 @@ class WindowsEnv
34
42
  !!self[key]
35
43
  end
36
44
 
37
- private
38
-
39
- def self.shell
40
- @shell ||= WIN32OLE.new('WScript.Shell')
41
- end
42
-
43
45
  end
44
46
 
45
- # env = WindowsEnv.user
46
-
47
- # home = env['home']
48
- # p home
49
-
50
- # env['home'] = nil
47
+ class Reg
48
+
49
+ def initialize(user=User.new)
50
+ @user = user
51
+ end
51
52
 
52
- # p env['home']
53
+ # reads the registry hive that the installer would write to
54
+ # based on user rights
55
+ def install_hkey(subkey, name='')
56
+ @user.admin? ? hklm(subkey,name) : hkcu(subkey,name)
57
+ end
53
58
 
54
- # env['rubyopt'] = '-rubygems'
59
+ def hklm(subkey, name='')
60
+ open(:HKEY_LOCAL_MACHINE, subkey, name)
61
+ end
62
+
63
+ def hkcu(subkey,name='')
64
+ open(:HKEY_CURRENT_USER, subkey, name)
65
+ end
66
+
67
+ def hkcr(subkey,name='')
68
+ open(:HKEY_CLASSES_ROOT, subkey, name)
69
+ end
70
+
71
+ def open(key, subkey, name)
72
+ key = Win32::Registry.const_get(key)
55
73
 
56
- # env['home'] = home
57
- # p env['home']
74
+ key.open(subkey) do |reg|
75
+ reg_typ, reg_val = reg.read(name) rescue nil
76
+ return reg_val
77
+ end
78
+ end
79
+ end
58
80
 
59
- # p env['path']
81
+ class User
60
82
 
61
- # p env.has_key?('path')
62
- # p env.has_key?('rubyopt')
83
+ IsUserAnAdmin = Win32API.new('shell32', 'IsUserAnAdmin', 'v', 'i')
84
+
85
+ # the logged on user's name
86
+ def name
87
+ ENV['username']
88
+ end
63
89
 
90
+ # the logged on user's domain
91
+ def domain
92
+ ENV['userdomain']
93
+ end
94
+
95
+ # determines if the user has admin rights
96
+ # not if the user is a member of the local admins group
97
+ # (allows for nested groups)
98
+ def admin?
99
+ true if IsUserAnAdmin.call.nonzero?
100
+ end
64
101
 
102
+ end
103
+
@@ -10,6 +10,4 @@ describe Pik::Add do
10
10
  add.interactive.should be_true
11
11
  end
12
12
 
13
- it "should exit with a message if nothing is found"
14
-
15
13
  end
@@ -12,9 +12,9 @@ describe BatchFile do
12
12
  @bf.to_s.should == string
13
13
  end
14
14
 
15
- it "should generate an ftype command for ruby.exe and rubyw.exe" do
16
- @bf.ftype.to_s.should match(/FTYPE rbfile\=ruby\.exe \"%1\" \%\*\n\nFTYPE rbwfile\=rubyw\.exe \"\%1\" \%\*/)
17
- end
15
+ # it "should generate an ftype command for ruby.exe and rubyw.exe" do
16
+ # @bf.ftype.to_s.should match(/FTYPE rbfile\=ruby\.exe \"%1\" \%\*\n\nFTYPE rbwfile\=rubyw\.exe \"\%1\" \%\*/)
17
+ # end
18
18
 
19
19
  it "should generate a path command with the updated ruby path" do
20
20
  @bf.set('PATH' => "C:\\ruby\\191\\bin").to_s.should match(/SET PATH\=C:\\ruby\\191\\bin/)
@@ -24,11 +24,4 @@ describe Pik::Command do
24
24
  end
25
25
  end
26
26
 
27
- describe "current_ruby_bin_path" do
28
- it "should be a Pathname" do
29
- @cmd.current_ruby_bin_path.should be_a(Pathname)
30
- @cmd.current_ruby_bin_path.basename.to_s.should == "bin"
31
- end
32
- end
33
-
34
27
  end
@@ -9,7 +9,7 @@ describe Pik::GemSync do
9
9
  gemsync = Pik::GemSync.new([])
10
10
  gemsync.gem_install(Pathname.new('c:/fake/file.gem'))
11
11
  gemsync.batch.file_data.should include( "ECHO Installing file.gem" )
12
- gemsync.batch.file_data.should include( "CALL gem install -q --no-rdoc --no-ri c:/fake/file.gem\n" )
12
+ gemsync.batch.file_data.should include( "CALL gem install -q --no-rdoc --no-ri c:\\fake\\file.gem\n" )
13
13
  end
14
14
  end
15
15
  end
@@ -2,7 +2,7 @@
2
2
  describe Pik::Help do
3
3
 
4
4
  before do
5
- @cmd = 'bin\\pik.bat'
5
+ @cmd = 'tools\\pik.bat'
6
6
  end
7
7
 
8
8
  it "should have a summary" do
@@ -1,7 +1,7 @@
1
1
  describe Pik::List do
2
2
 
3
3
  before do
4
- @cmd = 'bin\\pik.bat'
4
+ @cmd = 'tools\\pik.bat'
5
5
  Pik::Commands.clear
6
6
  Pik::Commands.add(Pik::List)
7
7
  #Pik::ConfigFile.stub!(:new).and_return({})
@@ -0,0 +1,30 @@
1
+
2
+ describe Pathname do
3
+
4
+ describe '==' do
5
+ it 'should test for equality' do
6
+ path1 = Pathname('Z:/This/is/to/test/EQUALITY')
7
+ path2 = Pathname('Z:\\this\\is\\to\\test\\equality')
8
+ path1.should == path2
9
+ end
10
+ end
11
+
12
+ describe 'to_windows' do
13
+ it 'should change the file separator' do
14
+ path = Pathname('Z:/This/is/to/test/separators')
15
+ result = "Z:\\This\\is\\to\\test\\separators"
16
+ path.to_windows.should eql(result)
17
+ p = "C:\\Doc\\gthiesfeld/.pik/dl/ir.zip"
18
+ Pathname(p).to_windows.should eql("C:\\Doc\\gthiesfeld\\.pik\\dl\\ir.zip")
19
+ end
20
+ end
21
+
22
+ describe 'to_ruby' do
23
+ it 'should change the file separator' do
24
+ path = Pathname("Z:\\This\\is\\to\\test\\separators")
25
+ result = 'Z:/This/is/to/test/separators'
26
+ path.to_ruby.should eql(result)
27
+ end
28
+ end
29
+
30
+ end