shr 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.swp +0 -0
- data/lib/shr/command.rb +46 -0
- data/lib/shr/option.rb +28 -28
- data/lib/shr/shell.rb +39 -53
- data/lib/shr/version.rb +1 -1
- data/lib/shr/which.rb +30 -26
- data/spec/lib/shr/command_spec.rb +52 -0
- data/spec/lib/shr/option_spec.rb +28 -17
- data/spec/lib/shr/shell_spec.rb +57 -64
- data/spec/lib/shr/shell_win_spec.rb +80 -0
- metadata +8 -2
data/.swp
ADDED
Binary file
|
data/lib/shr/command.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#command utf-8
|
2
|
+
require 'open3'
|
3
|
+
require 'shr/option'
|
4
|
+
require 'shr/which'
|
5
|
+
|
6
|
+
module Shr
|
7
|
+
class Command
|
8
|
+
|
9
|
+
def initialize(command, options=[])
|
10
|
+
@command = command.to_s
|
11
|
+
Option.indicator = '/' if OS.windows?
|
12
|
+
@options = Option.translate(options).join(' ')
|
13
|
+
end
|
14
|
+
attr_reader :command
|
15
|
+
|
16
|
+
def command
|
17
|
+
command = release? ? @command.chomp('!') : @command
|
18
|
+
Which::builtins?(command) ? "cmd /c #{command}" : command
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
[command, @options].join(' ')
|
23
|
+
end
|
24
|
+
|
25
|
+
def exist?
|
26
|
+
Which::exist? @command.chomp('!')
|
27
|
+
end
|
28
|
+
|
29
|
+
def release?
|
30
|
+
@command.end_with? '!'
|
31
|
+
end
|
32
|
+
|
33
|
+
# xxx
|
34
|
+
def run(environment)
|
35
|
+
pid = spawn(self.to_s, environment)
|
36
|
+
watcher = Process.detach(pid)
|
37
|
+
environment[:out].close if environment[:out].kind_of?(IO)
|
38
|
+
watcher
|
39
|
+
end
|
40
|
+
|
41
|
+
# xxx
|
42
|
+
def run!
|
43
|
+
Open3.pipeline(self.to_s)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/shr/option.rb
CHANGED
@@ -2,43 +2,43 @@
|
|
2
2
|
|
3
3
|
module Shr
|
4
4
|
class Option
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
class << self
|
6
|
+
attr_accessor :indicator
|
7
|
+
|
8
|
+
def indicator
|
9
|
+
@indicator ||= '-'
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
else
|
23
|
-
if k.length > 1
|
24
|
-
@options << "#{translate_from(k)}=#{v}"
|
12
|
+
def translate(options)
|
13
|
+
result = []
|
14
|
+
options.each do |opt|
|
15
|
+
case opt
|
16
|
+
when String then result << opt
|
17
|
+
when Symbol then result << translate_from(opt)
|
18
|
+
when Fixnum then result << "#{indicator}#{opt}"
|
19
|
+
when Hash
|
20
|
+
opt.each do |k, v|
|
21
|
+
if v.eql?(true)
|
22
|
+
result << translate_from(k)
|
25
23
|
else
|
26
|
-
|
24
|
+
if k.length > 1
|
25
|
+
result << "#{translate_from(k)}=#{v}"
|
26
|
+
else
|
27
|
+
result << translate_from(k) << v
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
30
|
-
when Fixnum
|
31
|
-
@options << "#{@indicator}#{opt}"
|
32
32
|
end
|
33
|
+
result
|
33
34
|
end
|
34
|
-
@options
|
35
|
-
end
|
36
35
|
|
37
|
-
|
36
|
+
private
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
def translate_from(opt)
|
39
|
+
s = opt.to_s
|
40
|
+
"#{indicator}#{(s.length > 1 ? '-' : '') if indicator == '-'}#{s}"
|
41
|
+
end
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
data/lib/shr/shell.rb
CHANGED
@@ -1,61 +1,48 @@
|
|
1
1
|
#coding: utf-8
|
2
|
-
require '
|
3
|
-
require 'shr/option'
|
4
|
-
require 'shr/which'
|
2
|
+
require 'shr/command'
|
5
3
|
|
6
4
|
module Shr
|
7
5
|
class Shell
|
8
6
|
|
9
7
|
def initialize
|
10
8
|
@promise = []
|
11
|
-
@capture = false
|
12
|
-
@release = false
|
13
9
|
end
|
14
10
|
|
15
11
|
def method_missing(name, *args)
|
16
|
-
command =
|
17
|
-
unless
|
12
|
+
command = Command.new(name, args)
|
13
|
+
unless command.exist?
|
18
14
|
super
|
19
15
|
else
|
20
|
-
delay
|
21
|
-
|
16
|
+
delay command
|
17
|
+
force! if command.release?
|
22
18
|
self
|
23
19
|
end
|
24
20
|
end
|
25
21
|
|
26
22
|
def to_s
|
27
|
-
|
23
|
+
force
|
28
24
|
@command_out.read if filled?
|
29
25
|
end
|
30
26
|
|
31
|
-
# xxx
|
32
27
|
def inspect
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
instance_exec(&block)
|
41
|
-
@capture = false
|
42
|
-
end
|
43
|
-
|
44
|
-
def release(&block)
|
45
|
-
@release = true
|
46
|
-
instance_exec(&block)
|
47
|
-
@release = false
|
28
|
+
command_line = @promise.join(' | ').strip
|
29
|
+
force
|
30
|
+
res = "#<Shr::Shell>"
|
31
|
+
res << "<:command => #{command_line}>" if command_line.size > 0
|
32
|
+
res << "\n" if filled?
|
33
|
+
res << @command_out.read if filled?
|
34
|
+
res
|
48
35
|
end
|
49
36
|
|
50
37
|
def each
|
51
|
-
|
38
|
+
force
|
52
39
|
if filled?
|
53
40
|
block_given? ? @command_out.each { |ln| yield ln } : @command_out.each
|
54
41
|
end
|
55
42
|
end
|
56
43
|
|
57
44
|
def exitstatus
|
58
|
-
|
45
|
+
force
|
59
46
|
if @wait_thread
|
60
47
|
proc = @wait_thread.value
|
61
48
|
proc.exitstatus
|
@@ -63,53 +50,52 @@ module Shr
|
|
63
50
|
end
|
64
51
|
|
65
52
|
def redirect_from(src)
|
66
|
-
|
53
|
+
force(:in => src)
|
67
54
|
self
|
68
55
|
end
|
69
56
|
|
70
57
|
def redirect_to(dest)
|
71
|
-
|
58
|
+
force(:out => dest)
|
72
59
|
end
|
73
60
|
|
74
61
|
alias_method :<, :redirect_from
|
75
62
|
alias_method :>, :redirect_to
|
76
63
|
|
64
|
+
private
|
65
|
+
|
77
66
|
def filled?
|
78
67
|
@command_out && !@command_out.closed?
|
79
68
|
end
|
80
69
|
|
81
|
-
|
82
|
-
|
83
|
-
option = Option.new
|
84
|
-
option.indicator = '/' if OS.windows?
|
85
|
-
options = option.parse(args).join(' ')
|
86
|
-
|
87
|
-
if OS.windows?
|
88
|
-
"cmd /c #{name} #{options}".strip
|
89
|
-
else
|
90
|
-
"#{name} #{options}".strip
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def delay(name, args)
|
95
|
-
@promise << command_line(name, args)
|
70
|
+
def delay(command)
|
71
|
+
@promise << command
|
96
72
|
end
|
97
73
|
|
74
|
+
# xxx
|
98
75
|
def force(args={})
|
99
|
-
args = { :redirect => {} }.merge(args)
|
100
76
|
return if @promise.empty?
|
101
77
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
78
|
+
@promise.each do |promise|
|
79
|
+
io_r, io_w = IO.pipe
|
80
|
+
environment = { :out => io_w }
|
81
|
+
environment[:in] = @command_out if @command_out
|
82
|
+
environment.merge!(args)
|
83
|
+
|
84
|
+
watcher = promise.run(environment)
|
85
|
+
|
86
|
+
@command_out = io_r
|
87
|
+
@wait_thread = watcher
|
108
88
|
end
|
109
89
|
|
110
90
|
@promise.clear
|
111
91
|
end
|
112
92
|
|
113
|
-
|
93
|
+
# xxx
|
94
|
+
def force!
|
95
|
+
return if @promise.empty?
|
96
|
+
|
97
|
+
@promise[-1].run!
|
98
|
+
@promise.clear
|
99
|
+
end
|
114
100
|
end
|
115
101
|
end
|
data/lib/shr/version.rb
CHANGED
data/lib/shr/which.rb
CHANGED
@@ -5,7 +5,7 @@ require 'os'
|
|
5
5
|
# whichr - https://github.com/rdp/whichr
|
6
6
|
|
7
7
|
module Shr
|
8
|
-
|
8
|
+
module Which
|
9
9
|
@@path = ENV['PATH']
|
10
10
|
if OS.windows?
|
11
11
|
cwd = File::PATH_SEPARATOR + '.'
|
@@ -19,6 +19,7 @@ module Shr
|
|
19
19
|
cd chdir
|
20
20
|
cls
|
21
21
|
color
|
22
|
+
copy
|
22
23
|
date
|
23
24
|
del erace
|
24
25
|
dir
|
@@ -39,46 +40,49 @@ module Shr
|
|
39
40
|
start
|
40
41
|
time
|
41
42
|
title
|
43
|
+
type
|
42
44
|
var
|
43
45
|
verify
|
44
46
|
vol
|
45
47
|
}
|
46
48
|
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
+
class << self
|
51
|
+
def exist?(program)
|
52
|
+
programs = add_extensions(program)
|
50
53
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
entries = paths.product(programs).map { |list| list.join '/' }
|
55
|
+
result = entries.find do |exe|
|
56
|
+
File.executable?(exe) && !File.directory?(exe)
|
57
|
+
end
|
55
58
|
|
56
|
-
|
57
|
-
result
|
59
|
+
result = program.to_s if builtins?(program.to_s)
|
60
|
+
result
|
58
61
|
end
|
59
62
|
|
60
|
-
result
|
61
|
-
end
|
62
|
-
class << self
|
63
63
|
alias :exists? :exist?
|
64
|
-
end
|
65
64
|
|
66
|
-
|
67
|
-
|
68
|
-
# add .bat, .exe, etc.
|
69
|
-
extensions = ENV['PATHEXT'].split(';')
|
70
|
-
[program].product(extensions).map(&:join)
|
71
|
-
else
|
72
|
-
[program]
|
65
|
+
def builtins?(program)
|
66
|
+
@@builtins.include? program.to_s if OS.windows?
|
73
67
|
end
|
74
|
-
end
|
75
68
|
|
76
|
-
|
77
|
-
|
78
|
-
|
69
|
+
def add_extensions(program)
|
70
|
+
if OS.windows?
|
71
|
+
# add .bat, .exe, etc.
|
72
|
+
extensions = ENV['PATHEXT'].split(';')
|
73
|
+
[program].product(extensions).map(&:join)
|
74
|
+
else
|
75
|
+
[program]
|
76
|
+
end
|
79
77
|
end
|
80
|
-
end
|
81
78
|
|
82
|
-
|
79
|
+
def paths
|
80
|
+
@@path.split(File::PATH_SEPARATOR).map! do |path|
|
81
|
+
OS.windows? ? path.gsub('\\', '/') : path
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private :add_extensions, :paths
|
86
|
+
end
|
83
87
|
end
|
84
88
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#command utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Shr
|
5
|
+
describe Command do
|
6
|
+
let(:cmd) { Command.new(:ls, [:l, :t, :r]) }
|
7
|
+
|
8
|
+
it 'has the following methods' do
|
9
|
+
m = cmd.methods
|
10
|
+
m.should include(:command)
|
11
|
+
m.should include(:to_s)
|
12
|
+
m.should include(:exist?)
|
13
|
+
m.should include(:release?)
|
14
|
+
m.should include(:run)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#command' do
|
18
|
+
it 'returns the command name that passed in initializing' do
|
19
|
+
cmd.command.should eq('ls')
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when passed command end with '!'" do
|
23
|
+
it "returns the command name without '!'" do
|
24
|
+
Command.new(:ls!).command.should eq('ls')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#to_s' do
|
30
|
+
it 'returns the command and parsed options' do
|
31
|
+
cmd.to_s.should eq('ls -l -t -r')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#exist?' do
|
36
|
+
it "returns the command's existence" do
|
37
|
+
Command.new(:echo).exist?.should be_true
|
38
|
+
Command.new(:ohce).exist?.should be_false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#release?' do
|
43
|
+
context "when passed command without '!'" do
|
44
|
+
it { Command.new(:ls!).release?.should be_true }
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when passed command with '!'" do
|
48
|
+
it { Command.new(:ls).release?.should be_false }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/lib/shr/option_spec.rb
CHANGED
@@ -10,62 +10,73 @@ module Shr
|
|
10
10
|
MIXED_FORM = SHORT_FORM + LONG_FORM
|
11
11
|
|
12
12
|
it 'has the following methods' do
|
13
|
-
o =
|
14
|
-
o.should include(:
|
13
|
+
o = Option.methods
|
14
|
+
o.should include(:translate)
|
15
15
|
end
|
16
16
|
|
17
|
-
describe '#
|
17
|
+
describe '#translate' do
|
18
18
|
describe String do
|
19
19
|
it 'remains argument unchanged' do
|
20
|
-
|
20
|
+
Option.indicator = '-'
|
21
|
+
Option.translate(MIXED_FORM).should eq(MIXED_FORM)
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
describe Symbol do
|
25
26
|
context 'with a character' do
|
26
27
|
it 'tranlate argument to short-form' do
|
27
|
-
|
28
|
+
Option.indicator = '-'
|
29
|
+
Option.translate([:o]).should eq(['-o'])
|
28
30
|
end
|
29
31
|
|
30
32
|
it 'may be indicated by @indicator' do
|
31
|
-
|
32
|
-
|
33
|
+
Option.indicator = '/'
|
34
|
+
Option.translate([:o]).should eq(['/o'])
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
38
|
context 'with some characters' do
|
37
39
|
it 'translates argument to long-form' do
|
38
|
-
|
40
|
+
Option.indicator = '-'
|
41
|
+
Option.translate([:silent]).should eq(['--silent'])
|
39
42
|
end
|
40
43
|
|
41
44
|
it 'may be indicated by @indicator' do
|
42
|
-
|
43
|
-
|
45
|
+
Option.indicator = '/'
|
46
|
+
Option.translate([:silent]).should eq(['/silent'])
|
44
47
|
end
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
51
|
describe Hash do
|
49
|
-
it {
|
50
|
-
|
52
|
+
it {
|
53
|
+
Option.indicator = '-'
|
54
|
+
Option.translate([{ :o => 'page.html' }]).should eq(SHORT_FORM)
|
55
|
+
}
|
56
|
+
|
57
|
+
it {
|
58
|
+
Option.indicator = '-'
|
59
|
+
Option.translate([{ :shell => '/bin/sh', :silent => true }]).should eq(LONG_FORM)
|
60
|
+
}
|
51
61
|
|
52
62
|
context 'with indicator' do
|
53
63
|
it 'may be indicated by @indicator' do
|
54
|
-
|
55
|
-
|
64
|
+
Option.indicator = '/'
|
65
|
+
Option.translate([{ :o => 'page.html' }]).should eq(['/o', 'page.html'])
|
56
66
|
end
|
57
67
|
end
|
58
68
|
end
|
59
69
|
|
60
70
|
describe Fixnum do
|
61
71
|
it 'translates argument to short-form' do
|
62
|
-
|
72
|
+
Option.indicator = '-'
|
73
|
+
Option.translate([1, 2, 3]).should eq(['-1', '-2', '-3'])
|
63
74
|
end
|
64
75
|
|
65
76
|
context 'with indicator' do
|
66
77
|
it 'may be indicated by @indicator' do
|
67
|
-
|
68
|
-
|
78
|
+
Option.indicator = '/'
|
79
|
+
Option.translate([1, 2, 3]).should eq(['/1', '/2', '/3'])
|
69
80
|
end
|
70
81
|
end
|
71
82
|
end
|
data/spec/lib/shr/shell_spec.rb
CHANGED
@@ -8,18 +8,8 @@ module Shr
|
|
8
8
|
describe Shell do
|
9
9
|
let(:sh) { Shell.new }
|
10
10
|
|
11
|
-
before(:all) do
|
12
|
-
@tmpdir = Dir.mktmpdir
|
13
|
-
['perl.pl', 'python.py', 'ruby.rb'].each do |file|
|
14
|
-
FileUtils.touch File.join(@tmpdir, file)
|
15
|
-
end
|
16
|
-
@tmpfile = File.join(@tmpdir, 'ruby.rb.back')
|
17
|
-
end
|
18
|
-
|
19
11
|
it 'has the following methods' do
|
20
12
|
m = sh.methods
|
21
|
-
m.should include(:capture)
|
22
|
-
m.should include(:release)
|
23
13
|
m.should include(:exitstatus)
|
24
14
|
m.should include(:each)
|
25
15
|
m.should include(:redirect_from)
|
@@ -28,77 +18,80 @@ module Shr
|
|
28
18
|
m.should include(:>)
|
29
19
|
end
|
30
20
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
unless OS.windows?
|
22
|
+
before(:all) do
|
23
|
+
Option.indicator = '-'
|
24
|
+
@tmpdir = Dir.mktmpdir
|
25
|
+
['perl.pl', 'python.py', 'ruby.rb'].each do |file|
|
26
|
+
FileUtils.touch File.join(@tmpdir, file)
|
27
|
+
end
|
28
|
+
@tmpfile = File.join(@tmpdir, 'ruby.rb.back')
|
29
|
+
end
|
36
30
|
|
37
|
-
context "command end with '!'" do
|
38
31
|
it 'executes OS commands' do
|
39
|
-
|
40
|
-
|
41
|
-
|
32
|
+
cmd_result = `pwd`
|
33
|
+
sh_result = sh.pwd.to_s
|
34
|
+
sh_result.should eq(cmd_result)
|
42
35
|
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe '#capture' do
|
46
|
-
it 'captures output of commands'
|
47
|
-
end
|
48
36
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
it 'yields each line (result of command) to the block' do
|
55
|
-
files = []
|
56
|
-
sh.ls(@tmpdir).sort(:r).each do |file|
|
57
|
-
files << file.strip
|
37
|
+
context "command end with '!'" do
|
38
|
+
it 'executes OS commands' do
|
39
|
+
sh.touch! @tmpfile
|
40
|
+
File.should exist(@tmpfile)
|
41
|
+
FileUtils.rm @tmpfile
|
58
42
|
end
|
59
|
-
files.should eq(['ruby.rb', 'python.py', 'perl.pl'])
|
60
43
|
end
|
61
44
|
|
62
|
-
|
63
|
-
it '
|
64
|
-
|
45
|
+
describe '#each' do
|
46
|
+
it 'yields each line (result of command) to the block' do
|
47
|
+
files = []
|
48
|
+
sh.ls(@tmpdir).sort(:r).each do |file|
|
49
|
+
files << file.strip
|
50
|
+
end
|
51
|
+
files.should eq(['ruby.rb', 'python.py', 'perl.pl'])
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'without block' do
|
55
|
+
it 'returns Enumerator' do
|
56
|
+
sh.ls.each.should be_kind_of(Enumerator)
|
57
|
+
end
|
65
58
|
end
|
66
59
|
end
|
67
|
-
end
|
68
60
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
61
|
+
it "emulates the shell pipe operator by method chaining" do
|
62
|
+
cmd_result = `pwd | tr '[:lower:]' '[:upper:]'`
|
63
|
+
sh_result = sh.pwd.tr("'[:lower:]'", "'[:upper:]'").to_s
|
64
|
+
sh_result.should eq(cmd_result)
|
65
|
+
end
|
74
66
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
67
|
+
describe '#exitstatus' do
|
68
|
+
it "shows an exit status of process" do
|
69
|
+
sh.ruby('-e', "'exit 0'").exitstatus.should eq(0)
|
70
|
+
sh.ruby('-e', "'exit 1'").exitstatus.should eq(1)
|
71
|
+
end
|
79
72
|
end
|
80
|
-
end
|
81
73
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
74
|
+
describe '#redirect_from' do
|
75
|
+
it 'redirect from file to command' do
|
76
|
+
tempfile = Tempfile.new('temp')
|
77
|
+
sh.pwd.redirect_to(tempfile.path)
|
78
|
+
sh.cat.redirect_from(tempfile.path).to_s.should eq(`pwd`)
|
79
|
+
tempfile.close!
|
80
|
+
end
|
88
81
|
end
|
89
|
-
end
|
90
82
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
83
|
+
describe '#redirect_to' do
|
84
|
+
it 'redirecs result of command to file' do
|
85
|
+
tempfile = Tempfile.new('temp')
|
86
|
+
sh.pwd.redirect_to(tempfile.path)
|
87
|
+
sh.cat(tempfile.path).to_s.should eq(`pwd`)
|
88
|
+
tempfile.close!
|
89
|
+
end
|
97
90
|
end
|
98
|
-
end
|
99
91
|
|
100
|
-
|
101
|
-
|
92
|
+
after(:all) do
|
93
|
+
FileUtils.remove_entry_secure @tmpdir
|
94
|
+
end
|
102
95
|
end
|
103
96
|
end
|
104
97
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
module Shr
|
8
|
+
if OS.windows?
|
9
|
+
describe Shell do
|
10
|
+
let(:sh) { Shell.new }
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
Option.indicator = '/'
|
14
|
+
@tmpdir = Dir.mktmpdir
|
15
|
+
['perl.pl', 'python.py', 'ruby.rb'].each do |file|
|
16
|
+
FileUtils.touch File.join(@tmpdir, file)
|
17
|
+
end
|
18
|
+
@tmpfile = File.join(@tmpdir, 'ruby.rb.back')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'executes OS commands' do
|
22
|
+
cmd_result = `chdir`
|
23
|
+
sh_result = sh.chdir.to_s
|
24
|
+
sh_result.should eq(cmd_result)
|
25
|
+
end
|
26
|
+
|
27
|
+
context "command end with '!'" do
|
28
|
+
it 'executes OS commands' do
|
29
|
+
sh.copy!('nul', @tmpfile.gsub('/', '\\'))
|
30
|
+
File.should exist(@tmpfile)
|
31
|
+
FileUtils.rm @tmpfile
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#each' do
|
36
|
+
it 'yields each line (result of command) to the block' do
|
37
|
+
files = []
|
38
|
+
sh.dir(:B, @tmpdir.gsub('/', '\\')).sort(:R).each do |file|
|
39
|
+
files << file.strip
|
40
|
+
end
|
41
|
+
files.should eq(['ruby.rb', 'python.py', 'perl.pl'])
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'without block' do
|
45
|
+
it 'returns Enumerator' do
|
46
|
+
sh.dir.each.should be_kind_of(Enumerator)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "emulates the shell pipe operator by method chaining" do
|
52
|
+
cmd_result = `chdir | ruby -ne 'puts $_.tr("a-z", "A-Z")'`
|
53
|
+
sh_result = sh.chdir.ruby('-ne', %q{'puts $_.tr("a-z", "A-Z")'}).to_s
|
54
|
+
sh_result.should eq(cmd_result)
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#redirect_from' do
|
58
|
+
it 'redirect from file to command' do
|
59
|
+
tempfile = Tempfile.new('temp')
|
60
|
+
sh.chdir.redirect_to(tempfile.path)
|
61
|
+
sh.more.redirect_from(tempfile.path).to_s.should eq(`chdir`)
|
62
|
+
tempfile.close!
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#redirect_to' do
|
67
|
+
it 'redirecs result of command to file' do
|
68
|
+
tempfile = Tempfile.new('temp')
|
69
|
+
sh.chdir.redirect_to(tempfile.path)
|
70
|
+
sh.type(tempfile.path.gsub('/', '\\')).to_s.should eq(`chdir`)
|
71
|
+
tempfile.close!
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
after(:all) do
|
76
|
+
FileUtils.remove_entry_secure @tmpdir
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: os
|
@@ -35,19 +35,23 @@ extensions: []
|
|
35
35
|
extra_rdoc_files: []
|
36
36
|
files:
|
37
37
|
- .gitignore
|
38
|
+
- .swp
|
38
39
|
- Gemfile
|
39
40
|
- Guardfile
|
40
41
|
- LICENSE.md
|
41
42
|
- README.md
|
42
43
|
- Rakefile
|
43
44
|
- lib/shr.rb
|
45
|
+
- lib/shr/command.rb
|
44
46
|
- lib/shr/option.rb
|
45
47
|
- lib/shr/shell.rb
|
46
48
|
- lib/shr/version.rb
|
47
49
|
- lib/shr/which.rb
|
48
50
|
- shr.gemspec
|
51
|
+
- spec/lib/shr/command_spec.rb
|
49
52
|
- spec/lib/shr/option_spec.rb
|
50
53
|
- spec/lib/shr/shell_spec.rb
|
54
|
+
- spec/lib/shr/shell_win_spec.rb
|
51
55
|
- spec/lib/shr/which_spec.rb
|
52
56
|
- spec/lib/shr_spec.rb
|
53
57
|
- spec/spec_helper.rb
|
@@ -76,8 +80,10 @@ signing_key:
|
|
76
80
|
specification_version: 3
|
77
81
|
summary: Make controlling subprocess easier in Ruby.
|
78
82
|
test_files:
|
83
|
+
- spec/lib/shr/command_spec.rb
|
79
84
|
- spec/lib/shr/option_spec.rb
|
80
85
|
- spec/lib/shr/shell_spec.rb
|
86
|
+
- spec/lib/shr/shell_win_spec.rb
|
81
87
|
- spec/lib/shr/which_spec.rb
|
82
88
|
- spec/lib/shr_spec.rb
|
83
89
|
- spec/spec_helper.rb
|