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.
- 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
@@ -6,24 +6,24 @@ module Pik
|
|
6
6
|
it "Removes a ruby location from pik."
|
7
7
|
include ConfigFileEditor
|
8
8
|
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :force
|
10
10
|
|
11
11
|
def execute
|
12
12
|
to_remove = self.class.choose_from(@args, @config)
|
13
13
|
raise QuitError unless to_remove
|
14
|
-
if
|
14
|
+
if force || @hl.agree("Are you sure you'd like to remove '#{to_remove}'? [Yn] ")
|
15
15
|
@config.delete(to_remove)
|
16
|
-
@hl.say("#{to_remove} removed")
|
16
|
+
@hl.say("#{to_remove} removed")
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def command_options
|
21
21
|
super
|
22
|
-
options.on("--
|
23
|
-
@
|
22
|
+
options.on("--force", "-f", "Remove without prompting") do |value|
|
23
|
+
@force = value
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
28
28
|
|
29
|
-
end
|
29
|
+
end
|
@@ -2,21 +2,21 @@ module Pik
|
|
2
2
|
|
3
3
|
class Run < Command
|
4
4
|
|
5
|
-
it "Runs command with all
|
6
|
-
include BatchFileEditor
|
5
|
+
it "Runs command with all versions of ruby that pik is aware of."
|
7
6
|
|
8
7
|
def execute
|
9
|
-
command = @args.join(' ')
|
10
|
-
current_ruby = @config[get_version]
|
11
8
|
@config.sort.each do |version,hash|
|
12
9
|
switch_path_to(hash)
|
13
10
|
switch_gem_home_to(hash[:gem_home])
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
echo_ruby_version(hash[:path])
|
12
|
+
puts `#{command}`
|
13
|
+
puts
|
17
14
|
end
|
18
|
-
|
19
|
-
|
15
|
+
end
|
16
|
+
|
17
|
+
def command(cmd='CALL')
|
18
|
+
args = @args.map{|a| a.sub(/.*\s.*/m, '"\&"')}.join(' ')
|
19
|
+
"#{cmd} #{args}"
|
20
20
|
end
|
21
21
|
|
22
22
|
def command_options
|
@@ -31,7 +31,67 @@ module Pik
|
|
31
31
|
SEP
|
32
32
|
options.separator sep
|
33
33
|
end
|
34
|
+
|
35
|
+
def parse_options
|
36
|
+
end
|
37
|
+
|
38
|
+
def switch_path_to(new_ver)
|
39
|
+
dir = Which::Ruby.find
|
40
|
+
current_config = config[ find_config_from_path(dir) ]
|
41
|
+
|
42
|
+
new_path = SearchPath.new(ENV['PATH']).replace_or_add(dir, new_ver[:path])
|
43
|
+
if new_gem_home = new_ver[:gem_home]
|
44
|
+
|
45
|
+
new_gem_bin = Pathname.new(new_gem_home) + 'bin'
|
46
|
+
|
47
|
+
if current_config && (current_gem_home = current_config[:gem_home])
|
48
|
+
current_gem_bin = Pathname.new(current_gem_home) + 'bin'
|
49
|
+
new_path.replace(current_gem_bin, new_gem_bin)
|
50
|
+
else
|
51
|
+
new_path.add(new_gem_bin)
|
52
|
+
end
|
53
|
+
else
|
54
|
+
if current_config && (current_gem_home = current_config[:gem_home])
|
55
|
+
current_gem_bin = Pathname.new(current_gem_home) + 'bin'
|
56
|
+
new_path.remove(current_gem_bin)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
ENV['PATH'] = new_path.join
|
60
|
+
end
|
61
|
+
|
62
|
+
def switch_gem_home_to(gem_home)
|
63
|
+
gem_home = Pathname(gem_home).to_windows rescue nil
|
64
|
+
ENV['GEM_PATH'] = gem_home
|
65
|
+
ENV['GEM_HOME'] = gem_home
|
66
|
+
end
|
67
|
+
|
68
|
+
def echo_ruby_version(path)
|
69
|
+
rb = Which::Ruby.exe(path)
|
70
|
+
puts `#{rb} -v `
|
71
|
+
end
|
34
72
|
|
35
73
|
end
|
74
|
+
|
75
|
+
class Ruby < Run
|
36
76
|
|
37
|
-
|
77
|
+
aka :rb
|
78
|
+
it "Runs ruby with all versions that pik is aware of."
|
79
|
+
|
80
|
+
def command(cmd=Which::Ruby.exe.basename)
|
81
|
+
super(cmd)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
class Gem < Run
|
87
|
+
|
88
|
+
it "Runs the gem command with all versions that pik is aware of."
|
89
|
+
|
90
|
+
def command(cmd=Which::Gem.bat.basename)
|
91
|
+
super(cmd)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
@@ -8,24 +8,24 @@ module Pik
|
|
8
8
|
|
9
9
|
attr_accessor :global
|
10
10
|
attr_accessor :gem_home
|
11
|
+
attr_accessor :verbose
|
11
12
|
|
12
13
|
def execute
|
13
14
|
abort('Nothing matches:') unless new_ver = self.class.choose_from(@args, @config)
|
14
15
|
switch_path_to(@config[new_ver])
|
15
|
-
switch_gem_home_to(@config[new_ver][:gem_home])
|
16
|
-
echo_ruby_version
|
16
|
+
switch_gem_home_to(@config[new_ver][:gem_home])
|
17
|
+
echo_ruby_version(@config[new_ver][:path]) if verbose
|
17
18
|
end
|
18
19
|
|
19
20
|
def command_options
|
20
|
-
# options.on("--global", "-g", "Make changes globally") do |value|
|
21
|
-
# @global = value
|
22
|
-
# end
|
23
|
-
|
24
|
-
# options.on("-m name", "specify gem_home (Named gem sets)") do |value|
|
25
|
-
# @gem_home = value
|
26
|
-
# end
|
27
|
-
|
28
21
|
super
|
22
|
+
|
23
|
+
options.on("--verbose", "-v",
|
24
|
+
"Display verbose output"
|
25
|
+
) do |value|
|
26
|
+
@verbose = true
|
27
|
+
end
|
28
|
+
|
29
29
|
sep =<<SEP
|
30
30
|
Examples:
|
31
31
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Pik
|
2
|
+
|
3
|
+
class Tags < Command
|
4
|
+
|
5
|
+
it 'Runs the pik command against the given tags.'
|
6
|
+
|
7
|
+
def execute
|
8
|
+
config.global[:tags] ||= Hash.new{|h,k| h[k] = [] }
|
9
|
+
@tag_config = config.dup
|
10
|
+
@tag_config.clear
|
11
|
+
tags = @args.shift.split(',')
|
12
|
+
tags.each do |tag|
|
13
|
+
versions = config.global[:tags][tag]
|
14
|
+
raise "Tag '#{tag}' unknown" unless versions
|
15
|
+
versions.each{|version| @tag_config[version] = config[version] }
|
16
|
+
end
|
17
|
+
command = Commands.find(@args.shift)
|
18
|
+
raise "The command '#{args.join(' ')}' is unknown." unless command
|
19
|
+
|
20
|
+
cmd = command.new(@args, @tag_config)
|
21
|
+
cmd.execute
|
22
|
+
|
23
|
+
rescue QuitError
|
24
|
+
puts "\nQuitting..."
|
25
|
+
rescue => e
|
26
|
+
puts "\nThere was an error"
|
27
|
+
puts " Error: #{e.message}\n\n"
|
28
|
+
puts e.backtrace.map{|m| " in: #{m}" }
|
29
|
+
ensure
|
30
|
+
cmd.close if cmd
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_options
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
class Tag < Command
|
39
|
+
|
40
|
+
it 'Adds the given tag to the current version.'
|
41
|
+
|
42
|
+
include ConfigFileEditor
|
43
|
+
|
44
|
+
def execute
|
45
|
+
config.global[:tags] ||= Hash.new
|
46
|
+
@args.each do |arg|
|
47
|
+
tags = config.global[:tags]
|
48
|
+
tags[arg] ||= []
|
49
|
+
tags[arg] << find_config_from_path
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
data/lib/pik/config_file.rb
CHANGED
@@ -3,19 +3,43 @@ require 'yaml'
|
|
3
3
|
module Pik
|
4
4
|
|
5
5
|
class ConfigFile < Hash
|
6
|
+
|
7
|
+
attr_reader :global
|
6
8
|
|
7
9
|
def initialize
|
8
10
|
@file = File.join(PIK_HOME, 'config.yml')
|
9
11
|
super
|
10
12
|
if File.exists? @file
|
11
|
-
|
13
|
+
contents = File.read( @file )
|
14
|
+
unless contents.empty?
|
15
|
+
documents = YAML.load_stream( contents )
|
16
|
+
self.update( documents[0] )
|
17
|
+
@global = documents[1] || {}
|
18
|
+
end
|
12
19
|
end
|
13
20
|
end
|
14
21
|
|
15
22
|
def write
|
16
|
-
File.open(@file, 'w')
|
23
|
+
File.open(@file, 'w')do |f|
|
24
|
+
f.puts YAML::dump_stream( Hash[self]), YAML.dump(global)
|
25
|
+
end
|
17
26
|
end
|
18
27
|
|
19
28
|
end
|
20
29
|
|
21
30
|
end
|
31
|
+
|
32
|
+
class Hash
|
33
|
+
# Replacing the to_yaml function so it'll serialize hashes sorted (by their keys)
|
34
|
+
#
|
35
|
+
# Original function is in /usr/lib/ruby/1.8/yaml/rubytypes.rb
|
36
|
+
def to_yaml( opts = {} )
|
37
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
38
|
+
out.map( taguri, to_yaml_style ) do |map|
|
39
|
+
sort_by{|s| s[0].to_s}.each do |k, v| # <-- here's my addition (the 'sort')
|
40
|
+
map.add( k, v )
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
# = progressbar.rb
|
2
|
+
#
|
3
|
+
# == Copyright (C) 2001 Satoru Takabayashi
|
4
|
+
#
|
5
|
+
# Ruby License
|
6
|
+
#
|
7
|
+
# This module is free software. You may use, modify, and/or redistribute this
|
8
|
+
# software under the same terms as Ruby.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
12
|
+
# FOR A PARTICULAR PURPOSE.
|
13
|
+
#
|
14
|
+
# == Author(s)
|
15
|
+
#
|
16
|
+
# * Satoru Takabayashi
|
17
|
+
|
18
|
+
# Author:: Satoru Takabayashi
|
19
|
+
# Copyright:: Copyright (c) 2001 Satoru Takabayashi
|
20
|
+
# License:: Ruby License
|
21
|
+
|
22
|
+
# = Console Progress Bar
|
23
|
+
#
|
24
|
+
# Console::ProgressBar is a terminal-based progress bar library.
|
25
|
+
#
|
26
|
+
# == Usage
|
27
|
+
#
|
28
|
+
# pbar = ConsoleProgressBar.new( "Demo", 100 )
|
29
|
+
# 100.times { pbar.inc }
|
30
|
+
# pbar.finish
|
31
|
+
#
|
32
|
+
|
33
|
+
module Console; end
|
34
|
+
|
35
|
+
class Console::ProgressBar
|
36
|
+
|
37
|
+
def initialize(title, total, out = STDERR)
|
38
|
+
@title = title
|
39
|
+
@total = total
|
40
|
+
@out = out
|
41
|
+
@bar_length = 80
|
42
|
+
@bar_mark = "o"
|
43
|
+
@total_overflow = true
|
44
|
+
@current = 0
|
45
|
+
@previous = 0
|
46
|
+
@is_finished = false
|
47
|
+
@start_time = Time.now
|
48
|
+
@format = "%-14s %3d%% %s %s"
|
49
|
+
@format_arguments = [:title, :percentage, :bar, :stat]
|
50
|
+
show_progress
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def convert_bytes (bytes)
|
55
|
+
if bytes < 1024
|
56
|
+
sprintf("%6dB", bytes)
|
57
|
+
elsif bytes < 1024 * 1000 # 1000kb
|
58
|
+
sprintf("%5.1fKB", bytes.to_f / 1024)
|
59
|
+
elsif bytes < 1024 * 1024 * 1000 # 1000mb
|
60
|
+
sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
|
61
|
+
else
|
62
|
+
sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def transfer_rate
|
67
|
+
bytes_per_second = @current.to_f / (Time.now - @start_time)
|
68
|
+
sprintf("%s/s", convert_bytes(bytes_per_second))
|
69
|
+
end
|
70
|
+
|
71
|
+
def bytes
|
72
|
+
convert_bytes(@current)
|
73
|
+
end
|
74
|
+
|
75
|
+
def format_time (t)
|
76
|
+
t = t.to_i
|
77
|
+
sec = t % 60
|
78
|
+
min = (t / 60) % 60
|
79
|
+
hour = t / 3600
|
80
|
+
sprintf("%02d:%02d:%02d", hour, min, sec);
|
81
|
+
end
|
82
|
+
|
83
|
+
# ETA stands for Estimated Time of Arrival.
|
84
|
+
def eta
|
85
|
+
if @current == 0
|
86
|
+
"ETA: --:--:--"
|
87
|
+
else
|
88
|
+
elapsed = Time.now - @start_time
|
89
|
+
eta = elapsed * @total / @current - elapsed;
|
90
|
+
sprintf("ETA: %s", format_time(eta))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def elapsed
|
95
|
+
elapsed = Time.now - @start_time
|
96
|
+
sprintf("Time: %s", format_time(elapsed))
|
97
|
+
end
|
98
|
+
|
99
|
+
def stat
|
100
|
+
if @is_finished then elapsed else eta end
|
101
|
+
end
|
102
|
+
|
103
|
+
def stat_for_file_transfer
|
104
|
+
if @is_finished then
|
105
|
+
sprintf("%s %s %s", bytes, transfer_rate, elapsed)
|
106
|
+
else
|
107
|
+
sprintf("%s %s %s", bytes, transfer_rate, eta)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def eol
|
112
|
+
if @is_finished then "\n" else "\r" end
|
113
|
+
end
|
114
|
+
|
115
|
+
def bar
|
116
|
+
len = percentage * @bar_length / 100
|
117
|
+
sprintf("|%s%s|", @bar_mark * len, " " * (@bar_length - len))
|
118
|
+
end
|
119
|
+
|
120
|
+
def percentage
|
121
|
+
if @total.zero?
|
122
|
+
100
|
123
|
+
else
|
124
|
+
@current * 100 / @total
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def title
|
129
|
+
@title[0,13] + ":"
|
130
|
+
end
|
131
|
+
|
132
|
+
def get_width
|
133
|
+
# FIXME: I don't know how portable it is.
|
134
|
+
default_width = 80
|
135
|
+
begin
|
136
|
+
tiocgwinsz = 0x5413
|
137
|
+
data = [0, 0, 0, 0].pack("SSSS")
|
138
|
+
if @out.ioctl(tiocgwinsz, data) >= 0 then
|
139
|
+
rows, cols, xpixels, ypixels = data.unpack("SSSS")
|
140
|
+
if cols >= 0 then cols else default_width end
|
141
|
+
else
|
142
|
+
default_width
|
143
|
+
end
|
144
|
+
rescue Exception
|
145
|
+
default_width
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def show
|
150
|
+
arguments = @format_arguments.map {|method| send(method) }
|
151
|
+
line = sprintf(@format, *arguments)
|
152
|
+
|
153
|
+
width = get_width
|
154
|
+
if line.length == width - 1
|
155
|
+
@out.print(line + eol)
|
156
|
+
elsif line.length >= width
|
157
|
+
@bar_length = [@bar_length - (line.length - width + 1), 0].max
|
158
|
+
if @bar_length == 0 then @out.print(line + eol) else show end
|
159
|
+
else #line.length < width - 1
|
160
|
+
@bar_length += width - line.length + 1
|
161
|
+
show
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def show_progress
|
166
|
+
if @total.zero?
|
167
|
+
cur_percentage = 100
|
168
|
+
prev_percentage = 0
|
169
|
+
else
|
170
|
+
cur_percentage = (@current * 100 / @total).to_i
|
171
|
+
prev_percentage = (@previous * 100 / @total).to_i
|
172
|
+
end
|
173
|
+
|
174
|
+
if cur_percentage > prev_percentage || @is_finished
|
175
|
+
show
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
public
|
180
|
+
def file_transfer_mode
|
181
|
+
@format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
|
182
|
+
end
|
183
|
+
|
184
|
+
def bar_mark= (mark)
|
185
|
+
@bar_mark = String(mark)[0..0]
|
186
|
+
end
|
187
|
+
|
188
|
+
def total_overflow= (boolv)
|
189
|
+
@total_overflow = boolv ? true : false
|
190
|
+
end
|
191
|
+
|
192
|
+
def format= (format)
|
193
|
+
@format = format
|
194
|
+
end
|
195
|
+
|
196
|
+
def format_arguments= (arguments)
|
197
|
+
@format_arguments = arguments
|
198
|
+
end
|
199
|
+
|
200
|
+
def finish
|
201
|
+
@current = @total
|
202
|
+
@is_finished = true
|
203
|
+
show_progress
|
204
|
+
end
|
205
|
+
|
206
|
+
def halt
|
207
|
+
@is_finished = true
|
208
|
+
show_progress
|
209
|
+
end
|
210
|
+
|
211
|
+
def set (count)
|
212
|
+
if count < 0
|
213
|
+
raise "invalid count less than zero: #{count}"
|
214
|
+
elsif count > @total
|
215
|
+
if @total_overflow
|
216
|
+
@total = count + 1
|
217
|
+
else
|
218
|
+
raise "invalid count greater than total: #{count}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
@current = count
|
222
|
+
show_progress
|
223
|
+
@previous = @current
|
224
|
+
end
|
225
|
+
|
226
|
+
def inc (step = 1)
|
227
|
+
@current += step
|
228
|
+
@current = @total if @current > @total
|
229
|
+
show_progress
|
230
|
+
@previous = @current
|
231
|
+
end
|
232
|
+
|
233
|
+
def inspect
|
234
|
+
"(ProgressBar: #{@current}/#{@total})"
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|