lsl 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/lsl.rb +42 -45
- data/lib/lsl/command/compound.rb +16 -0
- data/lib/lsl/command/execution.rb +111 -0
- data/lib/lsl/command/single.rb +21 -0
- data/lib/lsl/ext/ext.rb +43 -0
- data/lib/lsl/grammars/base.treetop +1 -1
- data/lib/lsl/grammars/compound_command.treetop +17 -1
- data/lib/lsl/grammars/single_command.treetop +2 -1
- data/lib/lsl/mapping/mapping.rb +32 -0
- data/lib/lsl/sandbox.rb +2 -40
- data/lib/lsl/server.rb +4 -0
- data/lib/lsl/shell.rb +88 -0
- data/lsl.gemspec +16 -3
- data/spec/compound_command_spec.rb +35 -0
- data/spec/lsl_spec.rb +0 -5
- data/spec/mock_dir/a.txt +0 -0
- data/spec/mock_dir/b.txt +0 -0
- data/spec/mock_dir/log.txt +5 -0
- data/spec/mock_dir/output.txt +1 -0
- data/spec/shell_spec.rb +48 -0
- data/spec/single_command_spec.rb +13 -0
- data/to +4 -0
- metadata +16 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lib/lsl.rb
CHANGED
@@ -6,55 +6,52 @@ require 'mharris_ext'
|
|
6
6
|
require File.dirname(__FILE__) + "/lsl/grammars/#{g}"
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
to_s.strip == ''
|
12
|
-
end
|
13
|
-
def present?
|
14
|
-
!blank?
|
15
|
-
end
|
16
|
-
def unquoted
|
17
|
-
((self[0..0]+self[-1..-1]) == '""') ? self[1..-2] : self
|
18
|
-
end
|
9
|
+
%w(single compound execution).each do |f|
|
10
|
+
require File.dirname(__FILE__) + "/lsl/command/#{f}"
|
19
11
|
end
|
20
12
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
13
|
+
%w(ext).each do |f|
|
14
|
+
require File.dirname(__FILE__) + "/lsl/ext/#{f}"
|
15
|
+
end
|
16
|
+
|
17
|
+
%w(mapping).each do |f|
|
18
|
+
require File.dirname(__FILE__) + "/lsl/mapping/#{f}"
|
19
|
+
end
|
20
|
+
|
21
|
+
%w(shell).each do |f|
|
22
|
+
require File.dirname(__FILE__) + "/lsl/#{f}"
|
23
|
+
end
|
24
|
+
|
25
|
+
module LSL
|
26
|
+
module ExecutionStrategy
|
27
|
+
class Base
|
29
28
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
elements.each do |e|
|
36
|
-
return e.send(node) if e.respond_to?(node)
|
29
|
+
class Shell < Base
|
30
|
+
def call(cmd)
|
31
|
+
str = "#{cmd.ex} " + cmd.args.join(" ")
|
32
|
+
`#{str}`
|
33
|
+
end
|
37
34
|
end
|
38
|
-
|
39
|
-
|
35
|
+
class Eval < Base
|
36
|
+
def str(cmd)
|
37
|
+
"#{cmd.ex} " + cmd.args.map { |x| x.quoted }.join(" ")
|
38
|
+
end
|
39
|
+
def call(cmd)
|
40
|
+
eval(str(cmd))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
40
45
|
end
|
41
|
-
|
42
46
|
end
|
43
47
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
ex.split(".").last
|
55
|
-
end
|
56
|
-
def obj
|
57
|
-
a = ex.split(".")
|
58
|
-
(a.size > 1) ? eval(a.first) : nil
|
59
|
-
end
|
60
|
-
end
|
48
|
+
def with_debug
|
49
|
+
$debug = true
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
$debug = false
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
@@ -0,0 +1,111 @@
|
|
1
|
+
class Array
|
2
|
+
def each_with_expansion(&b)
|
3
|
+
return if empty?
|
4
|
+
first.array_aware_each do |x|
|
5
|
+
if size == 1
|
6
|
+
yield([x])
|
7
|
+
else
|
8
|
+
self[1..-1].each_with_expansion do |args|
|
9
|
+
yield([x] + args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Object
|
17
|
+
def array_aware_each(&b)
|
18
|
+
if kind_of?(Array)
|
19
|
+
each(&b)
|
20
|
+
else
|
21
|
+
yield(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
def send_with_expansion(sym,*args,&b)
|
25
|
+
return send(sym,&b) if args.empty?
|
26
|
+
res = []
|
27
|
+
args.each_with_expansion do |a|
|
28
|
+
res << send(sym,*a,&b)
|
29
|
+
end
|
30
|
+
res = res.select { |x| x.present? }
|
31
|
+
if res.size == 1
|
32
|
+
res = res.first
|
33
|
+
elsif res.empty?
|
34
|
+
res = nil
|
35
|
+
end
|
36
|
+
res
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module LSL
|
41
|
+
module CommandExecution
|
42
|
+
#a CommandExecution is method independant
|
43
|
+
class Base
|
44
|
+
attr_accessor :command_str, :shell
|
45
|
+
include FromHash
|
46
|
+
end
|
47
|
+
class Single < Base
|
48
|
+
attr_accessor :command, :input_args
|
49
|
+
fattr(:simple_obj) { command.obj || shell.env }
|
50
|
+
fattr(:obj) do
|
51
|
+
m = LSL::Mapping.new
|
52
|
+
m.method(command) || simple_obj
|
53
|
+
end
|
54
|
+
fattr(:command_args) do
|
55
|
+
res = command.args
|
56
|
+
res << [command.options] unless command.options.empty?
|
57
|
+
res
|
58
|
+
end
|
59
|
+
def fixed_input_args
|
60
|
+
return [] unless input_args
|
61
|
+
return [] if input_args.respond_to?("empty?") && input_args.empty?
|
62
|
+
res = input_args
|
63
|
+
res = [res] unless res.kind_of?(Array)
|
64
|
+
#puts "ia #{res.inspect}"
|
65
|
+
res
|
66
|
+
[res]
|
67
|
+
end
|
68
|
+
fattr(:args) do
|
69
|
+
command_args + fixed_input_args
|
70
|
+
end
|
71
|
+
fattr(:result) do
|
72
|
+
if obj.respond_to?(command.method)
|
73
|
+
res = obj.send_with_expansion(command.method,*args)
|
74
|
+
#puts "RES #{res.inspect}" if res
|
75
|
+
res
|
76
|
+
else
|
77
|
+
`#{command.raw}`.output_to_array
|
78
|
+
end
|
79
|
+
end
|
80
|
+
def run!
|
81
|
+
result
|
82
|
+
rescue => exp
|
83
|
+
puts "command failed #{exp.message}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
class Compound < Base
|
87
|
+
fattr(:command) { shell.parser.parse(command_str).command_hash }
|
88
|
+
fattr(:command_executions) do
|
89
|
+
exes = []
|
90
|
+
input_args = lambda { exes.last.andand.result || [] }
|
91
|
+
command.each_command do |c,args|
|
92
|
+
c = LSL::CommandExecution::Single.new(:shell => shell, :command => c, :input_args => input_args[])
|
93
|
+
c.run!
|
94
|
+
exes << c
|
95
|
+
end
|
96
|
+
exes
|
97
|
+
end
|
98
|
+
def run!
|
99
|
+
command_executions
|
100
|
+
if command.output_filename
|
101
|
+
::File.create(command.output_filename,result.join("\n"))
|
102
|
+
else
|
103
|
+
puts result.join("\n") if result
|
104
|
+
end
|
105
|
+
end
|
106
|
+
def result
|
107
|
+
command_executions.last.result
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LSL
|
2
|
+
module Command
|
3
|
+
class Single
|
4
|
+
attr_accessor :ex, :args, :options, :raw
|
5
|
+
include FromHash
|
6
|
+
def to_h
|
7
|
+
{:ex => ex, :args => args, :options => options}
|
8
|
+
end
|
9
|
+
def url
|
10
|
+
"http://localhost:4567/#{ex}" + args.map { |x| "/#{x}" }.join
|
11
|
+
end
|
12
|
+
def method
|
13
|
+
ex.split(".").last
|
14
|
+
end
|
15
|
+
def obj
|
16
|
+
a = ex.split(".")
|
17
|
+
(a.size > 1) ? eval(a.first) : nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/lsl/ext/ext.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
class Object
|
2
|
+
def blank?
|
3
|
+
to_s.strip == ''
|
4
|
+
end
|
5
|
+
def present?
|
6
|
+
!blank?
|
7
|
+
end
|
8
|
+
def quoted?
|
9
|
+
((self[0..0]+self[-1..-1]) == '""')
|
10
|
+
end
|
11
|
+
def unquoted
|
12
|
+
quoted? ? self[1..-2] : self
|
13
|
+
end
|
14
|
+
def quoted
|
15
|
+
quoted? ? self : "\"#{self}\""
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Object
|
20
|
+
def list_values
|
21
|
+
elements.map { |x| x.text_value.strip }.map { |x| x.split(" ") }.flatten.map { |x| x.strip }.select { |x| x.present? }.map { |x| x.unquoted }
|
22
|
+
end
|
23
|
+
def find_child_node(node)
|
24
|
+
find_child_nodes(node).first
|
25
|
+
end
|
26
|
+
def find_child_nodes(node)
|
27
|
+
return [] unless elements
|
28
|
+
res = []
|
29
|
+
elements.each do |e|
|
30
|
+
#puts e.inspect if $debug and node.to_s == 'single_command'
|
31
|
+
if e.respond_to?(node)
|
32
|
+
res << e.send(node)
|
33
|
+
else
|
34
|
+
res += e.find_child_nodes(node)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
#return send(node) if respond_to?(node)
|
38
|
+
res
|
39
|
+
end
|
40
|
+
def find_child_node2(node)
|
41
|
+
find_child_node(node)
|
42
|
+
end
|
43
|
+
end
|
@@ -3,7 +3,23 @@ module LSL
|
|
3
3
|
include LSL::SingleCommand
|
4
4
|
include LSL::File
|
5
5
|
rule full_command
|
6
|
-
single_command (ows ">" ows filename)?
|
6
|
+
single_command (ows "|" ows single_command)* (ows ">" ows filename)? {
|
7
|
+
def filename
|
8
|
+
find_child_node(:filename)
|
9
|
+
end
|
10
|
+
def single_commands
|
11
|
+
|
12
|
+
res = [single_command.command_hash]
|
13
|
+
rest = find_child_nodes(:single_command).map { |x| x.command_hash }
|
14
|
+
#puts "rest #{rest.size}"
|
15
|
+
res + rest
|
16
|
+
end
|
17
|
+
def command_hash
|
18
|
+
res = LSL::Command::Compound.new(:commands => single_commands)
|
19
|
+
res.output_filename = filename.text_value if filename
|
20
|
+
res
|
21
|
+
end
|
22
|
+
}
|
7
23
|
end
|
8
24
|
end
|
9
25
|
end
|
@@ -11,7 +11,8 @@ module LSL
|
|
11
11
|
find_child_node(:options)
|
12
12
|
end
|
13
13
|
def command_hash
|
14
|
-
|
14
|
+
LSL::Command::Single.new(:raw => text_value, :ex => ex.text_value,
|
15
|
+
:args => args.andand.list_values || [], :options => options.andand.hash_values || {})
|
15
16
|
end
|
16
17
|
}
|
17
18
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rake'
|
2
|
+
task :abc do
|
3
|
+
puts "task abc"
|
4
|
+
end
|
5
|
+
|
6
|
+
class RemoteCall
|
7
|
+
def remote_call(*args)
|
8
|
+
require 'open-uri'
|
9
|
+
open("http://localhost:4567/remote_call").read
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class RakeRunner
|
14
|
+
def method_missing(sym,*args,&b)
|
15
|
+
Rake::Task[sym].invoke
|
16
|
+
"ran"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module LSL
|
21
|
+
class Mapping
|
22
|
+
def method(cmd)
|
23
|
+
if cmd.ex == 'remote_call'
|
24
|
+
RemoteCall.new
|
25
|
+
elsif cmd.ex == 'abc'
|
26
|
+
RakeRunner.new
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/lsl/sandbox.rb
CHANGED
@@ -1,43 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + "/../lsl"
|
2
|
-
require 'open-uri'
|
3
|
-
require 'fileutils'
|
2
|
+
#require 'open-uri'
|
4
3
|
|
5
|
-
class CommandEnv
|
6
|
-
def echo(str)
|
7
|
-
puts "ECHOING #{str}"
|
8
|
-
end
|
9
|
-
def cp(a,b)
|
10
|
-
puts "gonna copy #{a} to #{b}"
|
11
|
-
end
|
12
|
-
def del(a)
|
13
|
-
puts "deleting #{a}"
|
14
|
-
end
|
15
|
-
end
|
16
4
|
|
17
|
-
|
18
|
-
def self.bar(*args)
|
19
|
-
puts "bar #{args.inspect}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class Shell
|
24
|
-
fattr(:env) { CommandEnv.new }
|
25
|
-
fattr(:parser) { LSL::SingleCommandParser.new }
|
26
|
-
def run(str)
|
27
|
-
command = parser.parse(str).command_hash
|
28
|
-
obj = command.obj || env
|
29
|
-
obj.send(command.method,*command.args)
|
30
|
-
#open(command.url)
|
31
|
-
rescue => exp
|
32
|
-
puts "command failed #{exp.message}"
|
33
|
-
end
|
34
|
-
def run_loop
|
35
|
-
loop do
|
36
|
-
str = STDIN.gets.strip
|
37
|
-
run(str)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
s = Shell.new
|
43
|
-
s.run_loop
|
5
|
+
run_shell!
|
data/lib/lsl/server.rb
CHANGED
data/lib/lsl/shell.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
class String
|
4
|
+
def output_to_array
|
5
|
+
split("\n").select { |x| x.present? }.map { |x| x.strip }
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def ec_array(cmd)
|
10
|
+
`#{cmd}`.output_to_array
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
$printed ||= []
|
15
|
+
module LSL
|
16
|
+
module ShellLike
|
17
|
+
module Inner
|
18
|
+
def echo(*args)
|
19
|
+
#puts args.inspect
|
20
|
+
puts args.join(" ")
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
def ls(d=".")
|
24
|
+
ec_array "ls #{d}"
|
25
|
+
end
|
26
|
+
def pf(f)
|
27
|
+
str = ::File.read(f)
|
28
|
+
$printed << str
|
29
|
+
puts str
|
30
|
+
end
|
31
|
+
def foo
|
32
|
+
["foo"]
|
33
|
+
end
|
34
|
+
def longest(*args)
|
35
|
+
res = args.sort_by { |x| x.size }.last
|
36
|
+
#puts "Longest: #{res}"
|
37
|
+
res
|
38
|
+
end
|
39
|
+
def pm(a,b)
|
40
|
+
puts a.length * b.length
|
41
|
+
end
|
42
|
+
def cc(*args)
|
43
|
+
args.reverse.join("")
|
44
|
+
end
|
45
|
+
def la(*args)
|
46
|
+
::File.append("spec/mock_dir/log.txt","LOG #{Time.now} " + args.join(",") + "\n")
|
47
|
+
end
|
48
|
+
def cd(d)
|
49
|
+
Dir.chdir(d)
|
50
|
+
end
|
51
|
+
def exit(*args)
|
52
|
+
puts "Exiting"
|
53
|
+
Kernel.exit(*args)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
include FileUtils
|
57
|
+
include Inner
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
class CommandEnv
|
62
|
+
include LSL::ShellLike
|
63
|
+
end
|
64
|
+
|
65
|
+
class Shell
|
66
|
+
fattr(:env) { LSL::CommandEnv.new }
|
67
|
+
fattr(:parser) { LSL::CompoundCommandParser.new }
|
68
|
+
def run(str)
|
69
|
+
LSL::CommandExecution::Compound.new(:command_str => str, :shell => self).tap { |x| x.run! }
|
70
|
+
end
|
71
|
+
def get_input
|
72
|
+
STDIN.gets.strip
|
73
|
+
end
|
74
|
+
def run_loop
|
75
|
+
loop do
|
76
|
+
print "#{Dir.getwd}> "
|
77
|
+
str = get_input
|
78
|
+
run(str)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def run_shell!(obj=nil)
|
85
|
+
s = LSL::Shell.new
|
86
|
+
s.env = obj if obj
|
87
|
+
s.run_loop
|
88
|
+
end
|
data/lsl.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{lsl}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["mharris717"]
|
12
|
-
s.date = %q{2010-12-
|
12
|
+
s.date = %q{2010-12-31}
|
13
13
|
s.default_executable = %q{lsl}
|
14
14
|
s.description = %q{little shell language}
|
15
15
|
s.email = %q{mharris717@gmail.com}
|
@@ -29,20 +29,32 @@ Gem::Specification.new do |s|
|
|
29
29
|
"VERSION",
|
30
30
|
"bin/lsl",
|
31
31
|
"lib/lsl.rb",
|
32
|
+
"lib/lsl/command/compound.rb",
|
33
|
+
"lib/lsl/command/execution.rb",
|
34
|
+
"lib/lsl/command/single.rb",
|
35
|
+
"lib/lsl/ext/ext.rb",
|
32
36
|
"lib/lsl/grammars/base.treetop",
|
33
37
|
"lib/lsl/grammars/compound_command.treetop",
|
34
38
|
"lib/lsl/grammars/file.treetop",
|
35
39
|
"lib/lsl/grammars/list.treetop",
|
36
40
|
"lib/lsl/grammars/quoting.treetop",
|
37
41
|
"lib/lsl/grammars/single_command.treetop",
|
42
|
+
"lib/lsl/mapping/mapping.rb",
|
38
43
|
"lib/lsl/sandbox.rb",
|
39
44
|
"lib/lsl/server.rb",
|
45
|
+
"lib/lsl/shell.rb",
|
40
46
|
"lsl.gemspec",
|
41
47
|
"spec/compound_command_spec.rb",
|
42
48
|
"spec/lsl_spec.rb",
|
49
|
+
"spec/mock_dir/a.txt",
|
50
|
+
"spec/mock_dir/b.txt",
|
51
|
+
"spec/mock_dir/log.txt",
|
52
|
+
"spec/mock_dir/output.txt",
|
43
53
|
"spec/quoting_spec.rb",
|
54
|
+
"spec/shell_spec.rb",
|
44
55
|
"spec/single_command_spec.rb",
|
45
|
-
"spec/spec_helper.rb"
|
56
|
+
"spec/spec_helper.rb",
|
57
|
+
"to"
|
46
58
|
]
|
47
59
|
s.homepage = %q{http://github.com/mharris717/lsl}
|
48
60
|
s.licenses = ["MIT"]
|
@@ -53,6 +65,7 @@ Gem::Specification.new do |s|
|
|
53
65
|
"spec/compound_command_spec.rb",
|
54
66
|
"spec/lsl_spec.rb",
|
55
67
|
"spec/quoting_spec.rb",
|
68
|
+
"spec/shell_spec.rb",
|
56
69
|
"spec/single_command_spec.rb",
|
57
70
|
"spec/spec_helper.rb"
|
58
71
|
]
|
@@ -5,11 +5,46 @@ describe "CompoundCommand" do
|
|
5
5
|
@parser = LSL::CompoundCommandParser.new
|
6
6
|
end
|
7
7
|
def parser; @parser; end
|
8
|
+
def parse(*args); parser.parse(*args); end
|
9
|
+
def parse_obj(*args); parse(*args).command_hash; end
|
8
10
|
it 'single_command' do
|
9
11
|
parser.should be_parsed("cp a b -v a")
|
10
12
|
end
|
11
13
|
it 'command with output redirection' do
|
12
14
|
parser.should be_parsed("cp a b > foo.txt")
|
13
15
|
end
|
16
|
+
it 'command with output redirection 2' do
|
17
|
+
parser.parse("cp a b > foo.txt").command_hash.output_filename.should == 'foo.txt'
|
18
|
+
end
|
19
|
+
it 'makes command obj without output filename' do
|
20
|
+
parser.parse("cp a b").command_hash.output_filename.should be_nil
|
21
|
+
end
|
22
|
+
it 'pipes' do
|
23
|
+
parser.should be_parsed("cp a b | cp a b > foo.txt")
|
24
|
+
end
|
25
|
+
it 'has one command' do
|
26
|
+
parser.parse("cp a b").command_hash.commands.size.should == 1
|
27
|
+
end
|
28
|
+
it 'has multiple commands' do
|
29
|
+
parser.parse("cp a b | ls c d").command_hash.commands.size.should == 2
|
30
|
+
end
|
31
|
+
it 'has 1st command' do
|
32
|
+
parse_obj("cp a b | ls c d").commands.first.ex.should == 'cp'
|
33
|
+
end
|
34
|
+
it 'has 2nd command' do
|
35
|
+
c = parse_obj("cp a b | ls c d").commands.last
|
36
|
+
c.ex.should == 'ls'
|
37
|
+
c.args.should == ['c','d']
|
38
|
+
end
|
39
|
+
describe "execution" do
|
40
|
+
it "each_command args" do
|
41
|
+
res = []
|
42
|
+
parse_obj("cp a b | ls c d").each_command do |c,args|
|
43
|
+
res << args
|
44
|
+
14
|
45
|
+
end
|
46
|
+
res.should == [[],14]
|
47
|
+
end
|
48
|
+
end
|
14
49
|
|
15
50
|
end
|
data/spec/lsl_spec.rb
CHANGED
data/spec/mock_dir/a.txt
ADDED
File without changes
|
data/spec/mock_dir/b.txt
ADDED
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
VERSION
|
data/spec/shell_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Shell" do
|
4
|
+
before do
|
5
|
+
@shell = LSL::Shell.new
|
6
|
+
end
|
7
|
+
def run(*args); @shell.run(*args); end
|
8
|
+
it 'smoke' do
|
9
|
+
2.should == 2
|
10
|
+
end
|
11
|
+
it 'simple' do
|
12
|
+
@shell.run("ls VERSION").result.should == ['VERSION']
|
13
|
+
@shell.run("ls VERSIONX").result.should == []
|
14
|
+
end
|
15
|
+
it 'piping' do
|
16
|
+
@shell.run('ls VERSION | pf')
|
17
|
+
$printed.should == ['0.0.1']
|
18
|
+
end
|
19
|
+
it 'foo' do
|
20
|
+
#30.times do
|
21
|
+
#@shell.run("foo | echo")
|
22
|
+
#end
|
23
|
+
run("ls VERSION | longest").result.should == 'VERSION'
|
24
|
+
run("ls VERSION | longest abc").result.should == 'VERSION'
|
25
|
+
run("ls VERSION | longest abc abcdefgh").result.should == 'abcdefgh'
|
26
|
+
end
|
27
|
+
it 'star arg' do
|
28
|
+
run("ls Gemfile*").result.should == ['Gemfile','Gemfile.lock']
|
29
|
+
end
|
30
|
+
it 'remote call' do
|
31
|
+
run("remote_call foo").result.should == 'rc'
|
32
|
+
run("remote_call foo | echo")
|
33
|
+
end
|
34
|
+
it 'rake' do
|
35
|
+
run("abc").result.should == "ran"
|
36
|
+
end
|
37
|
+
describe 'output redirection' do
|
38
|
+
before do
|
39
|
+
@file = "spec/mock_dir/output.txt"
|
40
|
+
eat_exceptions { FileUtils.rm @file }
|
41
|
+
end
|
42
|
+
it "foo" do
|
43
|
+
run("ls VERSION > #{@file}")
|
44
|
+
File.read(@file).should == "VERSION"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/spec/single_command_spec.rb
CHANGED
@@ -55,6 +55,12 @@ describe "Command" do
|
|
55
55
|
it "ex and args" do
|
56
56
|
parse("cp a b").command_hash.to_h.should == {:ex => "cp", :args => ['a','b'], :options => {}}
|
57
57
|
end
|
58
|
+
it "ex and args 2" do
|
59
|
+
parse("cp a b").command_hash.ex.should == 'cp'
|
60
|
+
end
|
61
|
+
it "ex and 3 args" do
|
62
|
+
parse("cp a b c").command_hash.to_h.should == {:ex => "cp", :args => ['a','b','c'], :options => {}}
|
63
|
+
end
|
58
64
|
it 'quoted arg' do
|
59
65
|
parse('cp "abc"').command_hash.args.should == ['abc']
|
60
66
|
end
|
@@ -67,6 +73,9 @@ describe "Command" do
|
|
67
73
|
it "ex and option value" do
|
68
74
|
parse("cp -v a").command_hash.to_h.should == {:ex => "cp", :args => [], :options => {"v" => 'a'}}
|
69
75
|
end
|
76
|
+
it 'raw string' do
|
77
|
+
parse("cp a b").command_hash.raw.should == 'cp a b'
|
78
|
+
end
|
70
79
|
end
|
71
80
|
|
72
81
|
end
|
@@ -78,4 +87,8 @@ quoting
|
|
78
87
|
going to ignore list arguments for now
|
79
88
|
how to i break out into raw code
|
80
89
|
ability to bring code directly into the shell
|
90
|
+
easy extensibility by anyone using the library
|
91
|
+
pipes
|
92
|
+
need a lesson on bash syntax
|
93
|
+
piping inut, communicating in json. what's diff between array and array of args
|
81
94
|
EOF
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 0
|
8
7
|
- 1
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- mharris717
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-12-
|
17
|
+
date: 2010-12-31 00:00:00 -05:00
|
18
18
|
default_executable: lsl
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -127,20 +127,32 @@ files:
|
|
127
127
|
- VERSION
|
128
128
|
- bin/lsl
|
129
129
|
- lib/lsl.rb
|
130
|
+
- lib/lsl/command/compound.rb
|
131
|
+
- lib/lsl/command/execution.rb
|
132
|
+
- lib/lsl/command/single.rb
|
133
|
+
- lib/lsl/ext/ext.rb
|
130
134
|
- lib/lsl/grammars/base.treetop
|
131
135
|
- lib/lsl/grammars/compound_command.treetop
|
132
136
|
- lib/lsl/grammars/file.treetop
|
133
137
|
- lib/lsl/grammars/list.treetop
|
134
138
|
- lib/lsl/grammars/quoting.treetop
|
135
139
|
- lib/lsl/grammars/single_command.treetop
|
140
|
+
- lib/lsl/mapping/mapping.rb
|
136
141
|
- lib/lsl/sandbox.rb
|
137
142
|
- lib/lsl/server.rb
|
143
|
+
- lib/lsl/shell.rb
|
138
144
|
- lsl.gemspec
|
139
145
|
- spec/compound_command_spec.rb
|
140
146
|
- spec/lsl_spec.rb
|
147
|
+
- spec/mock_dir/a.txt
|
148
|
+
- spec/mock_dir/b.txt
|
149
|
+
- spec/mock_dir/log.txt
|
150
|
+
- spec/mock_dir/output.txt
|
141
151
|
- spec/quoting_spec.rb
|
152
|
+
- spec/shell_spec.rb
|
142
153
|
- spec/single_command_spec.rb
|
143
154
|
- spec/spec_helper.rb
|
155
|
+
- to
|
144
156
|
has_rdoc: true
|
145
157
|
homepage: http://github.com/mharris717/lsl
|
146
158
|
licenses:
|
@@ -175,5 +187,6 @@ test_files:
|
|
175
187
|
- spec/compound_command_spec.rb
|
176
188
|
- spec/lsl_spec.rb
|
177
189
|
- spec/quoting_spec.rb
|
190
|
+
- spec/shell_spec.rb
|
178
191
|
- spec/single_command_spec.rb
|
179
192
|
- spec/spec_helper.rb
|