pik 0.1.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.
- data/History.txt +36 -0
- data/Manifest.txt +42 -0
- data/README.rdoc +174 -0
- data/Rakefile +37 -0
- data/bin/pik +33 -0
- data/lib/pik.rb +30 -0
- data/lib/pik/batch_file.rb +70 -0
- data/lib/pik/checkup.rb +11 -0
- data/lib/pik/commands.rb +35 -0
- data/lib/pik/commands/add_command.rb +65 -0
- data/lib/pik/commands/batch_file_editor.rb +62 -0
- data/lib/pik/commands/checkup_command.rb +67 -0
- data/lib/pik/commands/command.rb +166 -0
- data/lib/pik/commands/config_command.rb +28 -0
- data/lib/pik/commands/config_file_editor.rb +12 -0
- data/lib/pik/commands/default_command.rb +22 -0
- data/lib/pik/commands/gemsync_command.rb +69 -0
- data/lib/pik/commands/help_command.rb +44 -0
- data/lib/pik/commands/implode_command.rb +16 -0
- data/lib/pik/commands/list_command.rb +34 -0
- data/lib/pik/commands/remove_command.rb +29 -0
- data/lib/pik/commands/run_command.rb +37 -0
- data/lib/pik/commands/switch_command.rb +49 -0
- data/lib/pik/config_file.rb +21 -0
- data/lib/pik/core_ext/pathname.rb +15 -0
- data/lib/pik/options.rb +56 -0
- data/lib/pik/runner.rb +16 -0
- data/lib/pik/search_path.rb +51 -0
- data/lib/pik/windows_env.rb +64 -0
- data/spec/add_command_spec.rb +15 -0
- data/spec/batch_file_spec.rb +31 -0
- data/spec/command_spec.rb +34 -0
- data/spec/commands_spec.rb +44 -0
- data/spec/default_command_spec.rb +6 -0
- data/spec/gemsync_command_spec.rb +15 -0
- data/spec/help_command_spec.rb +30 -0
- data/spec/list_command_spec.rb +33 -0
- data/spec/remove_command_spec.rb +25 -0
- data/spec/run_command_spec.rb +36 -0
- data/spec/search_path_spec.rb +121 -0
- data/spec/spec.opts +3 -0
- data/spec/switch_command_spec.rb +44 -0
- metadata +143 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
module Pik
|
2
|
+
|
3
|
+
class Add < Command
|
4
|
+
|
5
|
+
it 'Adds another ruby location to pik.'
|
6
|
+
include ConfigFileEditor
|
7
|
+
|
8
|
+
attr_reader :interactive
|
9
|
+
|
10
|
+
def execute(path=nil)
|
11
|
+
return add_interactive if interactive
|
12
|
+
path = @args.first || ::Config::CONFIG['bindir']
|
13
|
+
add(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(path)
|
17
|
+
path = Pathname.new(path)
|
18
|
+
path = path.dirname if path.file?
|
19
|
+
if ruby_exists_at?(path)
|
20
|
+
if config[get_version(path)]
|
21
|
+
puts "This version has already been added."
|
22
|
+
else
|
23
|
+
version = get_version(path)
|
24
|
+
path = path.expand_path.to_ruby
|
25
|
+
puts "Adding: #{version}'\n Located at: #{path}\n"
|
26
|
+
@config[version][:path] = path
|
27
|
+
end
|
28
|
+
else
|
29
|
+
puts "Couldn't find a Ruby version at #{path}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def command_options
|
34
|
+
super
|
35
|
+
options.banner += "[path_to_ruby]"
|
36
|
+
options.separator ""
|
37
|
+
options.on("--interactive", "-i", "Add interactively") do |value|
|
38
|
+
@interactive = value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_interactive
|
43
|
+
@hl.choose do |menu|
|
44
|
+
menu.prompt = ""
|
45
|
+
menu.choice('e]nter a path'){
|
46
|
+
dir = @hl.ask("Enter a path to a ruby/bin dir (enter to quit)")
|
47
|
+
execute(dir) unless dir.empty? || !@hl.agree("Add '#{dir}'? [Yn] ")
|
48
|
+
add_interactive
|
49
|
+
}
|
50
|
+
menu.choice('s]earch'){
|
51
|
+
search_dir = @hl.ask("Enter a search path")
|
52
|
+
files = ruby_glob(search_dir + '**')
|
53
|
+
files.each{|file|
|
54
|
+
dir = File.dirname(file)
|
55
|
+
add(dir) if @hl.agree("Add '#{dir}'? [Yn] ")
|
56
|
+
}
|
57
|
+
add_interactive
|
58
|
+
}
|
59
|
+
menu.choice('q]uit'){raise QuitError}
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Pik
|
2
|
+
|
3
|
+
module BatchFileEditor
|
4
|
+
|
5
|
+
attr_reader :batch
|
6
|
+
|
7
|
+
def initialize(args=ARGV,config=nil)
|
8
|
+
super
|
9
|
+
batch_file = File.join(PIK_HOME, "#{File.basename($0)}_#{$$}.bat")
|
10
|
+
@batch = BatchFile.new( batch_file )
|
11
|
+
editors << @batch
|
12
|
+
end
|
13
|
+
|
14
|
+
def close
|
15
|
+
update_gem_batch
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def set(items)
|
20
|
+
items.each do |k, v|
|
21
|
+
@batch.set(k => v)
|
22
|
+
WindowsEnv.user.set(k => v) if global
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def switch_path_to(new_ver)
|
27
|
+
dir = current_ruby_bin_path
|
28
|
+
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
|
+
else
|
32
|
+
new_path.remove(current_gem_bin_path)
|
33
|
+
end
|
34
|
+
@batch.set('PATH' => new_path.join )
|
35
|
+
end
|
36
|
+
|
37
|
+
def switch_gem_home_to(gem_home_dir)
|
38
|
+
gem_home_dir ||= ''
|
39
|
+
gem_path = Pathname.new(gem_home_dir).to_windows
|
40
|
+
@batch.set('GEM_PATH' => gem_path )
|
41
|
+
@batch.set('GEM_HOME' => gem_path )
|
42
|
+
end
|
43
|
+
|
44
|
+
def echo_ruby_version(verb='Using')
|
45
|
+
@batch.file_data << "for /f \"delims=\" %%a in ('ruby -v') do @echo #{verb} %%a "
|
46
|
+
end
|
47
|
+
|
48
|
+
def echo_running_with_ruby_version
|
49
|
+
echo_ruby_version('Running with')
|
50
|
+
end
|
51
|
+
|
52
|
+
def update_gem_batch
|
53
|
+
BatchFile.open("#{$0}.bat") do |gem_bat|
|
54
|
+
# call new .pik/pik batch
|
55
|
+
gem_bat.call(%Q("#{@batch.path.to_windows}")) if @batch
|
56
|
+
gem_bat.write
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Pik
|
2
|
+
|
3
|
+
class Checkup < Command
|
4
|
+
|
5
|
+
aka :cu
|
6
|
+
it "Checks your environment for current Ruby best practices."
|
7
|
+
|
8
|
+
def execute
|
9
|
+
home
|
10
|
+
rubyopt
|
11
|
+
path
|
12
|
+
pathext
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
ERB.new(@output.join("\n\n")).result
|
17
|
+
end
|
18
|
+
|
19
|
+
def rubyopt
|
20
|
+
unless WindowsEnv.user['rubyopt'].empty? && WindowsEnv.system['rubyopt'].empty?
|
21
|
+
fail('rubyopt')
|
22
|
+
else
|
23
|
+
pass('rubyopt')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def home
|
28
|
+
if WindowsEnv.user['home'].empty?
|
29
|
+
fail('home')
|
30
|
+
else
|
31
|
+
pass('home')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def path
|
36
|
+
dirs = (WindowsEnv.user['path'] + WindowsEnv.system['path']).split(';')
|
37
|
+
dirs = dirs.select{|dir| File.exist?( File.join(dir,'ruby.exe') ) }
|
38
|
+
unless dirs.size == 1
|
39
|
+
fail('path')
|
40
|
+
else
|
41
|
+
pass('path')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def pathext
|
46
|
+
p_ext = WindowsEnv.system['pathext'].downcase
|
47
|
+
unless p_ext.include?('.rb') && p_ext.include?('.rbw')
|
48
|
+
fail('pathext')
|
49
|
+
else
|
50
|
+
pass('pathext')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def pass(test)
|
55
|
+
print '.'
|
56
|
+
$stdout.flush
|
57
|
+
# @output << @text[test][:pass]
|
58
|
+
end
|
59
|
+
|
60
|
+
def fail(test)
|
61
|
+
print 'F'
|
62
|
+
# @output << @text[test][:fail]
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Pik
|
4
|
+
|
5
|
+
class QuitError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class Command
|
9
|
+
|
10
|
+
attr_reader :config
|
11
|
+
|
12
|
+
attr_reader :options
|
13
|
+
|
14
|
+
attr_accessor :output
|
15
|
+
|
16
|
+
def self.cmd_name
|
17
|
+
name.split('::').last.downcase.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.description
|
21
|
+
new.options.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.inherited(subclass)
|
25
|
+
Commands.add(subclass)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.it(str)
|
29
|
+
@summary = str
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.summary
|
33
|
+
@summary
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.aka(*aliases)
|
37
|
+
@names = names + aliases
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.names
|
41
|
+
@names ||= [cmd_name]
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.clean_gem_batch
|
45
|
+
BatchFile.open("#{$0}.bat") do |gem_bat|
|
46
|
+
# remove old calls to .pik/pik batches
|
47
|
+
gem_bat.remove_line( /call.+pik.+bat/i )
|
48
|
+
gem_bat.write
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.choose_from(patterns, config)
|
53
|
+
if patterns.empty?
|
54
|
+
possibles = config.keys
|
55
|
+
else
|
56
|
+
possibles = patterns.map{|p| config.keys.grep(Regexp.new(Regexp.escape(p.to_s))) }
|
57
|
+
possibles = possibles.inject{|m,v| m & v }.flatten.uniq
|
58
|
+
end
|
59
|
+
case possibles.size
|
60
|
+
when 0
|
61
|
+
return nil
|
62
|
+
when 1
|
63
|
+
return possibles.first
|
64
|
+
else
|
65
|
+
hl.say('Select which Ruby you want:')
|
66
|
+
ver = hl.choose(*possibles)
|
67
|
+
return ver
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.hl
|
72
|
+
@hl ||= HighLine.new
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(args=ARGV, config_=nil)
|
76
|
+
@args = args
|
77
|
+
@options = OptionParser.new
|
78
|
+
@config = config_ || ConfigFile.new
|
79
|
+
@hl = HighLine.new
|
80
|
+
add_sigint_handler
|
81
|
+
options.program_name = "#{File.basename($0)} #{self.class.names.join('|')}"
|
82
|
+
command_options
|
83
|
+
parse_options
|
84
|
+
create(PIK_HOME) unless PIK_HOME.exist?
|
85
|
+
# Add.new(nil, config).execute if config.empty?
|
86
|
+
delete_old_pik_batches
|
87
|
+
end
|
88
|
+
|
89
|
+
def close
|
90
|
+
editors.each{|e| e.write }
|
91
|
+
end
|
92
|
+
|
93
|
+
def editors
|
94
|
+
@editors ||= []
|
95
|
+
end
|
96
|
+
|
97
|
+
def command_options
|
98
|
+
options.separator ""
|
99
|
+
options.separator self.class.summary
|
100
|
+
options.separator ""
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse_options
|
104
|
+
options.parse! @args
|
105
|
+
end
|
106
|
+
|
107
|
+
def current_version?(string)
|
108
|
+
string == get_version
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_version(path=current_ruby_bin_path)
|
112
|
+
cmd = ruby_exe(path).basename
|
113
|
+
cmd = Pathname.new(path) + cmd
|
114
|
+
ruby_ver = `#{cmd} -v`
|
115
|
+
ruby_ver =~ /ruby (\d\.\d\.\d)/
|
116
|
+
major = $1.gsub('.','')
|
117
|
+
"#{major}: #{ruby_ver.strip}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def current_ruby_bin_path
|
121
|
+
Pathname.new(::RbConfig::CONFIG['bindir'] )
|
122
|
+
end
|
123
|
+
|
124
|
+
def ruby_exists_at?(path)
|
125
|
+
!!ruby_exe(path)
|
126
|
+
end
|
127
|
+
|
128
|
+
def ruby_exe(path)
|
129
|
+
ruby_glob(path).first
|
130
|
+
end
|
131
|
+
|
132
|
+
def ruby_glob(path)
|
133
|
+
glob = "#{Pathname.new(path).to_ruby}/{ruby.exe}"
|
134
|
+
Pathname.glob(glob)
|
135
|
+
end
|
136
|
+
|
137
|
+
def current_gem_bin_path
|
138
|
+
default_gem_home + 'bin'
|
139
|
+
end
|
140
|
+
|
141
|
+
def default_gem_home
|
142
|
+
Pathname.new(Gem.default_path.first).to_windows
|
143
|
+
end
|
144
|
+
|
145
|
+
def create(home)
|
146
|
+
puts "creating #{home}"
|
147
|
+
home.mkpath
|
148
|
+
end
|
149
|
+
|
150
|
+
def delete_old_pik_batches( cutoff=(Time.now - (2 * 60 * 60)) )
|
151
|
+
Dir[(PIK_HOME + "*.bat").to_windows.to_s].each do |f|
|
152
|
+
File.delete(f) if File.ctime(f) < cutoff
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Installs a sigint handler.
|
157
|
+
|
158
|
+
def add_sigint_handler
|
159
|
+
trap 'INT' do
|
160
|
+
raise QuitError
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Pik
|
2
|
+
|
3
|
+
class Config < Command
|
4
|
+
|
5
|
+
it "Adds/modifies configuration options."
|
6
|
+
include BatchFileEditor
|
7
|
+
include ConfigFileEditor
|
8
|
+
|
9
|
+
attr_accessor :global
|
10
|
+
|
11
|
+
def execute
|
12
|
+
item, value = @args.shift.downcase.split('=')
|
13
|
+
case item
|
14
|
+
when 'rubyopt'
|
15
|
+
case value
|
16
|
+
when 'on' then set('RUBYOPT' => '-rubygems')
|
17
|
+
when 'off' then set('RUBYOPT' => nil)
|
18
|
+
end
|
19
|
+
when 'gem_home'
|
20
|
+
config[get_version][:gem_home] = @args.include?('default') ? default_gem_home : value
|
21
|
+
else
|
22
|
+
puts "Unknown configuration option"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
module Pik
|
3
|
+
|
4
|
+
class Default < Command
|
5
|
+
|
6
|
+
it "switches back to the default settings"
|
7
|
+
|
8
|
+
include BatchFileEditor
|
9
|
+
|
10
|
+
def execute
|
11
|
+
sys = WindowsEnv.system
|
12
|
+
usr = WindowsEnv.user
|
13
|
+
|
14
|
+
@batch.set('PATH' => sys['PATH'] + ';' + usr['PATH'] )
|
15
|
+
@batch.set('GEM_PATH' => usr['GEM_PATH'] || sys['GEM_PATH'] )
|
16
|
+
@batch.set('GEM_HOME' => usr['GEM_HOME'] || sys['GEM_HOME'] )
|
17
|
+
echo_ruby_version
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Pik
|
2
|
+
|
3
|
+
class GemSync < Command
|
4
|
+
|
5
|
+
it "Duplicates gems from the current version to the one specified."
|
6
|
+
include BatchFileEditor
|
7
|
+
|
8
|
+
def execute
|
9
|
+
target = self.class.choose_from(@args, config)
|
10
|
+
current = get_version
|
11
|
+
install_gems(current, target) if target
|
12
|
+
end
|
13
|
+
|
14
|
+
def install_gems(current, target)
|
15
|
+
switch_path_to(config[target])
|
16
|
+
switch_gem_home_to(config[target][:gem_home])
|
17
|
+
target_cache = gem_cache(target)
|
18
|
+
|
19
|
+
gem_cache(current).find do |file|
|
20
|
+
if file.file?
|
21
|
+
if (target_cache + file.basename).exist?
|
22
|
+
@batch.echo "Gem #{file.basename} already installed"
|
23
|
+
else
|
24
|
+
gem_install(file)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
switch_path_to(config[current])
|
29
|
+
switch_gem_home_to(config[target][:gem_home])
|
30
|
+
end
|
31
|
+
|
32
|
+
def gem_cache(version)
|
33
|
+
conf = config[version]
|
34
|
+
path = if conf[:gem_home]
|
35
|
+
Pathname.new( conf[:gem_home] )
|
36
|
+
else
|
37
|
+
cmd = ruby_exe(conf[:path]).to_s + " -rubygems -e \"puts Gem.default_path.last\""
|
38
|
+
Pathname.new( `#{cmd}`.chomp )
|
39
|
+
end
|
40
|
+
puts path + "cache"
|
41
|
+
path + "cache"
|
42
|
+
end
|
43
|
+
|
44
|
+
def gem_install(file)
|
45
|
+
@batch.echo "Installing #{file.basename}"
|
46
|
+
@batch.call "gem install -q --no-rdoc --no-ri #{file}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def command_options
|
50
|
+
super
|
51
|
+
sep =<<SEP
|
52
|
+
Examples:
|
53
|
+
|
54
|
+
C:\\>ruby -v
|
55
|
+
ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32]
|
56
|
+
|
57
|
+
C:\\>pik gemsync 191 p2
|
58
|
+
Gem ZenTest-4.1.4.gem already installed
|
59
|
+
Installing xml-simple-1.0.12.gem
|
60
|
+
Successfully installed xml-simple-1.0.12
|
61
|
+
1 gem installed
|
62
|
+
...
|
63
|
+
SEP
|
64
|
+
options.separator sep
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|