shr 0.1.1 → 0.1.2
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/.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
|