pik 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +13 -0
- data/Manifest.txt +35 -1
- data/README.rdoc +99 -39
- data/Rakefile +49 -8
- data/bin/pik_install +23 -0
- data/features/add_command.feature +28 -0
- data/features/checkup_command.feature +0 -0
- data/features/config_command.feature +12 -0
- data/features/default_command.feature +12 -0
- data/features/env.rb +52 -0
- data/features/gemsync_command.feature +0 -0
- data/features/help_command.feature +13 -0
- data/features/implode_command.feature +12 -0
- data/features/install_command.feature +13 -0
- data/features/list_command.feature +18 -0
- data/features/remove_command.feature +18 -0
- data/features/run_command.feature +22 -0
- data/features/step_definitions/pik_commands.rb +140 -0
- data/features/switch_command.feature +35 -0
- data/features/tag_command.feature +18 -0
- data/features/version.feature +9 -0
- data/lib/pik.rb +17 -3
- data/lib/pik/commands/add_command.rb +6 -6
- data/lib/pik/commands/batch_file_editor.rb +22 -8
- data/lib/pik/commands/checkup_command.rb +5 -2
- data/lib/pik/commands/command.rb +30 -26
- data/lib/pik/commands/config_command.rb +54 -2
- data/lib/pik/commands/default_command.rb +19 -5
- data/lib/pik/commands/help_command.rb +1 -1
- data/lib/pik/commands/implode_command.rb +12 -1
- data/lib/pik/commands/install_command.rb +182 -0
- data/lib/pik/commands/list_command.rb +3 -2
- data/lib/pik/commands/remove_command.rb +6 -6
- data/lib/pik/commands/run_command.rb +70 -10
- data/lib/pik/commands/switch_command.rb +10 -10
- data/lib/pik/commands/tag_command.rb +56 -0
- data/lib/pik/config_file.rb +26 -2
- data/lib/pik/contrib/progressbar.rb +237 -0
- data/lib/pik/contrib/unzip.rb +14 -0
- data/lib/pik/contrib/uri_ext.rb +296 -0
- data/lib/pik/contrib/zip/ioextras.rb +155 -0
- data/lib/pik/contrib/zip/stdrubyext.rb +111 -0
- data/lib/pik/contrib/zip/tempfile_bugfixed.rb +195 -0
- data/lib/pik/contrib/zip/zip.rb +1846 -0
- data/lib/pik/contrib/zip/zipfilesystem.rb +609 -0
- data/lib/pik/contrib/zip/ziprequire.rb +90 -0
- data/lib/pik/core_ext/pathname.rb +20 -7
- data/lib/pik/search_path.rb +21 -13
- data/lib/pik/which.rb +52 -0
- data/lib/pik/windows_env.rb +64 -25
- data/spec/add_command_spec.rb +0 -2
- data/spec/batch_file_spec.rb +3 -3
- data/spec/command_spec.rb +0 -7
- data/spec/gemsync_command_spec.rb +1 -1
- data/spec/help_command_spec.rb +1 -1
- data/spec/list_command_spec.rb +1 -1
- data/spec/pathname_spec.rb +30 -0
- data/spec/remove_command_spec.rb +6 -6
- data/spec/run_command_spec.rb +2 -30
- data/spec/search_path_spec.rb +9 -0
- data/spec/switch_command_spec.rb +14 -2
- data/spec/which_spec.rb +7 -0
- data/tools/pik.bat +2 -0
- data/tools/pik/pik +45 -0
- data/tools/pik/pik.exe +0 -0
- data/tools/pik/pik.exy +198 -0
- metadata +50 -21
- 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
|
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
|
-
|
data/lib/pik/search_path.rb
CHANGED
@@ -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
|
10
|
-
|
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
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
dir
|
21
|
+
if Pathname(dir) == old_path
|
22
|
+
new_path.to_windows.to_s
|
23
|
+
else
|
24
|
+
dir
|
24
25
|
end
|
25
|
-
}
|
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
|
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)
|
data/lib/pik/which.rb
ADDED
@@ -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
|
data/lib/pik/windows_env.rb
CHANGED
@@ -1,17 +1,25 @@
|
|
1
|
-
require '
|
1
|
+
require 'win32/registry'
|
2
|
+
require 'Win32API'
|
3
|
+
|
2
4
|
|
3
5
|
class WindowsEnv
|
4
6
|
|
5
7
|
def self.system
|
6
|
-
|
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
|
-
|
14
|
+
key = :HKEY_CURRENT_USER
|
15
|
+
subkey = 'Environment'
|
16
|
+
new(key, subkey)
|
11
17
|
end
|
12
18
|
|
13
|
-
def initialize(
|
14
|
-
@
|
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
|
-
@
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# env['home'] = nil
|
47
|
+
class Reg
|
48
|
+
|
49
|
+
def initialize(user=User.new)
|
50
|
+
@user = user
|
51
|
+
end
|
51
52
|
|
52
|
-
#
|
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
|
-
|
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
|
-
|
57
|
-
|
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
|
-
|
81
|
+
class User
|
60
82
|
|
61
|
-
|
62
|
-
|
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
|
+
|
data/spec/add_command_spec.rb
CHANGED
data/spec/batch_file_spec.rb
CHANGED
@@ -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
|
-
|
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/)
|
data/spec/command_spec.rb
CHANGED
@@ -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
|
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
|
data/spec/help_command_spec.rb
CHANGED
data/spec/list_command_spec.rb
CHANGED
@@ -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
|