shell-proxy 0.0.0 → 0.0.1

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/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/README.md CHANGED
@@ -6,27 +6,65 @@ Totes leeb.
6
6
  Inputs:
7
7
 
8
8
  ```ruby
9
- require './shell_proxy'
9
+ require './lib/shell-proxy'
10
10
 
11
11
  ShellProxy.new.__main__ do
12
12
  cd "Somedir"
13
13
 
14
+ __function("butts_function") do
15
+ touch "butts"
16
+ end
17
+
14
18
  __subshell do
15
19
  __subshell do
16
20
  mkdir "borp"
17
21
  cd "borp"
18
22
  touch "thing"
19
23
  end
20
- touch "somefile"
24
+ %w[foo bar baz].each do |dir|
25
+ mkdir dir
26
+ touch "#{dir}/#{dir}"
27
+ end
28
+ touch("somefile")
21
29
  mkdir "foo/bar/thing", { :p => nil }
30
+ echo("foo") | wc({:c => nil})
22
31
  end
23
32
 
24
33
  __chdir "/tmp" do
25
34
  touch "rawr"
26
35
  end
27
36
 
37
+ __set("foo", bare("$RANDOM"))
38
+
39
+ some | thing | some | other | thing
40
+
41
+ __case(raw("$foo")) do |c|
42
+ c.when(10000) do
43
+ echo "holy shit, did not expect that"
44
+ end
45
+ c.when("*") do
46
+ echo "Welp, that was predictable"
47
+ end
48
+ end
49
+
50
+ __for(bare("foo bar baz"), "i") do
51
+ echo raw("$i")
52
+ end
53
+
28
54
  rm "foo", { :r => nil, :f => nil }
29
55
  mongod({ :config => "/usr/local/etc/mongod.conf" })
56
+
57
+ __if(raw("[[ $foo == 'foo' ]]")) do |c|
58
+ c.then do
59
+ echo "it was true"
60
+ end
61
+ c.elseif(raw("[[ bar == bar ]]")) do
62
+ echo "this is definitely true"
63
+ end
64
+ c.else do
65
+ echo "This wont be reached"
66
+ end
67
+ end
30
68
  end
31
69
  ```
32
70
 
@@ -34,19 +72,50 @@ outputs:
34
72
 
35
73
  ```bash
36
74
  cd 'Somedir'
75
+ function butts_function() {
76
+ touch 'butts'
77
+ }
37
78
  (
38
79
  (
39
80
  mkdir 'borp'
40
81
  cd 'borp'
41
82
  touch 'thing'
42
83
  )
84
+ mkdir 'foo'
85
+ touch 'foo/foo'
86
+ mkdir 'bar'
87
+ touch 'bar/bar'
88
+ mkdir 'baz'
89
+ touch 'baz/baz'
43
90
  touch 'somefile'
44
91
  mkdir '-p' 'foo/bar/thing'
92
+ echo 'foo' | wc '-c'
45
93
  )
46
94
  (
47
95
  cd '/tmp'
48
96
  touch 'rawr'
49
97
  )
98
+ foo=$RANDOM
99
+ some | thing | some | other | thing
100
+ case "$foo" in
101
+ 10000)
102
+ echo 'holy shit, did not expect that'
103
+ ;;
104
+ *)
105
+ echo 'Welp, that was predictable'
106
+ ;;
107
+ esac
108
+ for i in foo bar baz; do
109
+ echo "$i"
110
+ done
50
111
  rm '-r' '-f' 'foo'
51
112
  mongod '--config' '/usr/local/etc/mongod.conf'
113
+ if [[ $foo == 'foo' ]]
114
+ then
115
+ echo 'it was true'
116
+ else if [[ bar == bar ]]
117
+ echo 'this is definitely true'
118
+ else
119
+ echo 'This wont be reached'
120
+ fi
52
121
  ```
@@ -0,0 +1,203 @@
1
+ require_relative 'shell-proxy/escaping'
2
+ require_relative 'shell-proxy/case'
3
+ require_relative 'shell-proxy/for'
4
+ require_relative 'shell-proxy/if'
5
+
6
+ INDENT_PADDING=" "
7
+
8
+ class RawString < String
9
+ def quote
10
+ inspect
11
+ end
12
+ end
13
+
14
+ class BareString < String
15
+ end
16
+
17
+ def raw(s)
18
+ RawString.new(s)
19
+ end
20
+
21
+ def bare(s)
22
+ BareString.new(s)
23
+ end
24
+
25
+ class ShellProxy
26
+ include Escaping
27
+
28
+ def __main__(writer = nil, &block)
29
+ @cmd_buffer = CmdBuffer.new
30
+ instance_exec(&block)
31
+ @cmd_buffer.write(writer || __writer)
32
+ end
33
+
34
+ def __subshell(&block)
35
+ @cmd_buffer << "("
36
+ @cmd_buffer.indent
37
+ yield
38
+ @cmd_buffer.undent
39
+ @cmd_buffer << ")"
40
+ end
41
+
42
+ def __chdir(dir, &block)
43
+ __subshell do
44
+ cd(dir)
45
+ yield
46
+ end
47
+ end
48
+
49
+ def __case(value, &block)
50
+ CaseStub.new(__escapinate(value), &block).__handle(@cmd_buffer)
51
+ end
52
+
53
+ def __for(over, iter, &block)
54
+ ForStub.new(over, iter, &block).__handle(@cmd_buffer)
55
+ end
56
+
57
+ def __if(condition, &block)
58
+ IfStub.new(condition, &block).__handle(@cmd_buffer)
59
+ end
60
+
61
+ def __set(variable, value)
62
+ __eval("#{variable}=#{__escapinate(value)}")
63
+ end
64
+
65
+ def __return(val)
66
+ __eval("return #{__escapinate(val)}")
67
+ end
68
+
69
+ def __function(name, &block)
70
+ @cmd_buffer << "function #{name}() {"
71
+ @cmd_buffer.indent
72
+ yield
73
+ @cmd_buffer.undent
74
+ @cmd_buffer << "}"
75
+ end
76
+
77
+ def method_missing(sym, *args)
78
+ opts = case args[-1]
79
+ when Hash
80
+ args.pop
81
+ else
82
+ {}
83
+ end
84
+
85
+ stub = CmdStub.new(@cmd_buffer)
86
+
87
+ cmd = sym.to_s
88
+ cmd << " #{__process_opts(opts)}" unless opts.empty?
89
+ cmd << " #{__process_args(args)}" unless args.empty?
90
+ @cmd_buffer << cmd
91
+ stub
92
+ end
93
+
94
+ def __eval(str)
95
+ @cmd_buffer << str
96
+ end
97
+
98
+ def __emit(str)
99
+ __writer.flush
100
+ end
101
+
102
+ def __writer
103
+ @writer ||= ShellWriter.new($stdout)
104
+ end
105
+
106
+ def __process_args(args)
107
+ args.map do |v|
108
+ __escapinate(v)
109
+ end.join(" ")
110
+ end
111
+
112
+ def __process_opts(opts)
113
+ outputs = []
114
+ __process_and_escape(opts) do |value|
115
+ outputs << value
116
+ end
117
+ outputs.join(" ")
118
+ end
119
+
120
+ def __process_and_escape(opts)
121
+ opts.each do |k, v|
122
+ k = k.to_s
123
+ k = (k.length == 1 ? "-" : "--") + k
124
+ yield __escapinate(k)
125
+ yield __escapinate(v) unless v.nil?
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ class CmdStub
132
+ def initialize(buffer)
133
+ @buffer = buffer
134
+ end
135
+
136
+ def emit(data)
137
+ @emitter.call(data)
138
+ end
139
+
140
+ def |(other)
141
+ # Append a pipe to the second last command in the stack
142
+ last = @buffer.pop
143
+ @buffer << "#{@buffer.pop} | #{last.strip}"
144
+ self
145
+ end
146
+ end
147
+
148
+
149
+ class CmdBuffer
150
+ def initialize
151
+ @indent = 0
152
+ @buffer = []
153
+ end
154
+
155
+ def indent
156
+ @indent += 1
157
+ end
158
+
159
+ def undent
160
+ @indent -= 1
161
+ end
162
+
163
+ def << (other)
164
+ @buffer << "#{INDENT_PADDING * @indent}#{other}"
165
+ end
166
+
167
+ def pop
168
+ @buffer.pop
169
+ end
170
+
171
+ def write(buf)
172
+ @buffer.each do |l|
173
+ buf.puts l
174
+ end
175
+ buf.flush
176
+ end
177
+ end
178
+
179
+ class ShellWriter
180
+ def initialize(to)
181
+ case to
182
+ when String
183
+ @to = File.open(to)
184
+ when IO
185
+ @to = to
186
+ else
187
+ raise "I don't know what to do"
188
+ end
189
+ end
190
+
191
+ def write(str)
192
+ @to.write(str)
193
+ end
194
+
195
+ def puts(str)
196
+ @to.puts(str)
197
+ end
198
+
199
+ def flush
200
+ @to.flush
201
+ end
202
+
203
+ end
@@ -0,0 +1,38 @@
1
+ class CaseStub
2
+ def initialize(value, &block)
3
+ @value = value
4
+ @block = block
5
+ end
6
+
7
+ def __handle(buffer)
8
+ handler = CaseHandler.new(buffer)
9
+ buffer << "case #{@value} in"
10
+ buffer.indent
11
+ @block.call(handler)
12
+ buffer.undent
13
+ buffer << "esac"
14
+ end
15
+ end
16
+
17
+
18
+ class CaseHandler
19
+ def initialize(buffer)
20
+ @buffer = buffer
21
+ end
22
+
23
+ def __escapinate(v)
24
+ if v.empty?
25
+ '""'
26
+ else
27
+ v
28
+ end
29
+ end
30
+
31
+ def when(opt, &block)
32
+ @buffer << "#{__escapinate(opt.to_s)})"
33
+ @buffer.indent
34
+ yield
35
+ @buffer.undent
36
+ @buffer << ";;"
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ module Escaping
2
+ def __escapinate(v)
3
+ case v
4
+ when RawString
5
+ v.quote
6
+ when BareString
7
+ v
8
+ when String
9
+ "'#{v.gsub(/'/, "\\'").gsub("\\", "\\\\")}'"
10
+ when Fixnum
11
+ v
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,17 @@
1
+ class ForStub
2
+ include ::Escaping
3
+
4
+ def initialize(over, iter, &block)
5
+ @over = over
6
+ @iter = iter
7
+ @block = block
8
+ end
9
+
10
+ def __handle(buffer)
11
+ buffer << "for #{@iter} in #{__escapinate(@over)}; do"
12
+ buffer.indent
13
+ @block.call
14
+ buffer.undent
15
+ buffer << "done"
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ class IfStub
2
+ def initialize(condition, &block)
3
+ @condition = condition
4
+ @block = block
5
+ end
6
+
7
+ def __handle(buffer)
8
+ handler = IfHandler.new(buffer)
9
+ buffer << "if #{@condition}"
10
+ @block.call(handler)
11
+ buffer << "fi"
12
+ end
13
+ end
14
+
15
+ class IfHandler
16
+ def initialize(buffer)
17
+ @buffer = buffer
18
+ end
19
+
20
+ def then(&block)
21
+ @buffer << "then"
22
+ @buffer.indent
23
+ block.call
24
+ @buffer.undent
25
+ end
26
+
27
+ def elseif(condition, &block)
28
+ @buffer << "else if #{condition}"
29
+ @buffer.indent
30
+ block.call
31
+ @buffer.undent
32
+ end
33
+
34
+ def else(&block)
35
+ @buffer << "else"
36
+ @buffer.indent
37
+ block.call
38
+ @buffer.undent
39
+ end
40
+ end
data/proof_of_concept.rb CHANGED
@@ -1,22 +1,60 @@
1
- require './shell_proxy'
1
+ require './lib/shell-proxy'
2
2
 
3
3
  ShellProxy.new.__main__ do
4
4
  cd "Somedir"
5
5
 
6
+ __function("butts_function") do
7
+ touch "butts"
8
+ end
9
+
6
10
  __subshell do
7
11
  __subshell do
8
12
  mkdir "borp"
9
13
  cd "borp"
10
14
  touch "thing"
11
15
  end
12
- touch "somefile"
16
+ %w[foo bar baz].each do |dir|
17
+ mkdir dir
18
+ touch "#{dir}/#{dir}"
19
+ end
20
+ touch("somefile")
13
21
  mkdir "foo/bar/thing", { :p => nil }
22
+ echo("foo") | wc({:c => nil})
14
23
  end
15
24
 
16
25
  __chdir "/tmp" do
17
26
  touch "rawr"
18
27
  end
19
28
 
29
+ __set("foo", bare("$RANDOM"))
30
+
31
+ some | thing | some | other | thing
32
+
33
+ __case(raw("$foo")) do |c|
34
+ c.when(10000) do
35
+ echo "holy shit, did not expect that"
36
+ end
37
+ c.when("*") do
38
+ echo "Welp, that was predictable"
39
+ end
40
+ end
41
+
42
+ __for(bare("foo bar baz"), "i") do
43
+ echo raw("$i")
44
+ end
45
+
20
46
  rm "foo", { :r => nil, :f => nil }
21
47
  mongod({ :config => "/usr/local/etc/mongod.conf" })
48
+
49
+ __if(raw("[[ $foo == 'foo' ]]")) do |c|
50
+ c.then do
51
+ echo "it was true"
52
+ end
53
+ c.elseif(raw("[[ bar == bar ]]")) do
54
+ echo "this is definitely true"
55
+ end
56
+ c.else do
57
+ echo "This wont be reached"
58
+ end
59
+ end
22
60
  end
data/shell-proxy.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "shell-proxy"
5
- s.version = "0.0.0"
5
+ s.version = "0.0.1"
6
6
  s.authors = ["Richo Healey"]
7
7
  s.email = ["richo@psych0tik.net"]
8
8
  s.homepage = "http://github.com/richo/shell-proxy"
data/test_shell_proxy.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rspec'
2
- require File.expand_path("../shell_proxy.rb", __FILE__)
2
+ require File.expand_path("../lib/shell-proxy.rb", __FILE__)
3
3
 
4
4
  describe "ShellProxy" do
5
5
  before(:each) do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shell-proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
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-06 00:00:00.000000000 Z
12
+ date: 2013-04-18 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: description
15
15
  email:
@@ -18,14 +18,19 @@ executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - .gitignore
21
22
  - Makefile
22
23
  - README.md
23
24
  - README/1
24
25
  - README/2
25
26
  - README/3
27
+ - lib/shell-proxy.rb
28
+ - lib/shell-proxy/case.rb
29
+ - lib/shell-proxy/escaping.rb
30
+ - lib/shell-proxy/for.rb
31
+ - lib/shell-proxy/if.rb
26
32
  - proof_of_concept.rb
27
33
  - shell-proxy.gemspec
28
- - shell_proxy.rb
29
34
  - test_shell_proxy.rb
30
35
  homepage: http://github.com/richo/shell-proxy
31
36
  licenses: []
data/shell_proxy.rb DELETED
@@ -1,105 +0,0 @@
1
- class ShellProxy
2
-
3
- INDENT_PADDING=" "
4
-
5
- def initialize
6
- @indent = 0
7
- end
8
-
9
- def __main__(&block)
10
- instance_exec(&block)
11
- end
12
-
13
- def __subshell(&block)
14
- __emit("(")
15
- @indent += 1
16
- yield
17
- @indent -= 1
18
- __emit(")")
19
- end
20
-
21
- def __chdir(dir, &block)
22
- __subshell do
23
- cd(dir)
24
- yield
25
- end
26
- end
27
-
28
- def method_missing(sym, *args)
29
- opts = case args[-1]
30
- when Hash
31
- args.pop
32
- else
33
- {}
34
- end
35
-
36
- cmd = sym.to_s
37
- cmd << " #{__process_opts(opts)}" unless opts.empty?
38
- cmd << " #{__process_args(args)}" unless args.empty?
39
- __emit cmd
40
- end
41
-
42
- def __emit(str)
43
- __writer.write(INDENT_PADDING * @indent)
44
- __writer.puts(str)
45
- __writer.flush
46
- end
47
-
48
- def __writer
49
- @writer ||= ShellWriter.new($stdout)
50
- end
51
-
52
- def __process_args(args)
53
- args.map do |v|
54
- __escapinate(v)
55
- end.join(" ")
56
- end
57
-
58
- def __process_opts(opts)
59
- outputs = []
60
- __process_and_escape(opts) do |value|
61
- outputs << value
62
- end
63
- outputs.join(" ")
64
- end
65
-
66
- def __process_and_escape(opts)
67
- opts.each do |k, v|
68
- k = k.to_s
69
- k = (k.length == 1 ? "-" : "--") + k
70
- yield __escapinate(k)
71
- yield __escapinate(v) unless v.nil?
72
- end
73
- end
74
-
75
- def __escapinate(v)
76
- "'#{v.gsub(/'/, "\\'").gsub("\\", "\\\\")}'"
77
- end
78
-
79
- end
80
-
81
- class ShellWriter
82
- def initialize(to)
83
- case to
84
- when String
85
- @to = File.open(to)
86
- when IO
87
- @to = to
88
- else
89
- raise "I don't know what to do"
90
- end
91
- end
92
-
93
- def write(str)
94
- @to.write(str)
95
- end
96
-
97
- def puts(str)
98
- @to.puts(str)
99
- end
100
-
101
- def flush
102
- @to.flush
103
- end
104
-
105
- end