brash 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 +17 -0
- data/.rspec +1 -0
- data/Gemfile +10 -0
- data/Guardfile +8 -0
- data/README +0 -0
- data/Rakefile +2 -0
- data/brash.gemspec +17 -0
- data/lib/brash.rb +66 -0
- data/lib/brash/command.rb +0 -0
- data/lib/brash/version.rb +3 -0
- data/spec/command_spec.rb +48 -0
- data/spec/spec_helper.rb +3 -0
- metadata +59 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-cfs
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
guard 'rspec' do
|
4
|
+
watch(%r{^spec/.+_spec\.rb$})
|
5
|
+
watch('lib/rash.rb') { "spec" }
|
6
|
+
watch(%r{^lib/rash/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
data/README
ADDED
File without changes
|
data/Rakefile
ADDED
data/brash.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/brash/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Joshua Lane"]
|
6
|
+
gem.email = ["lane.joshlane@gmail.com"]
|
7
|
+
gem.description = %q{Build bash commands with Ruby}
|
8
|
+
gem.summary = %q{Build bash commands with Ruby}
|
9
|
+
gem.homepage = "http://github.com/lanej/brash"
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "brash"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Brash::VERSION
|
17
|
+
end
|
data/lib/brash.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require "brash/version"
|
2
|
+
|
3
|
+
require File.expand_path "../brash/command", __FILE__
|
4
|
+
|
5
|
+
module Brash
|
6
|
+
def self.build(*args, &block)
|
7
|
+
CommandContext.surround(*args, &block).command
|
8
|
+
end
|
9
|
+
class CommandContext
|
10
|
+
attr_reader :command, :depth
|
11
|
+
def method_missing(method, *args, &block)
|
12
|
+
@command = Command.new(method, *args, &block).tap{|c| c.context = self}
|
13
|
+
end
|
14
|
+
def initialize(depth=0)
|
15
|
+
@depth = depth
|
16
|
+
end
|
17
|
+
def self.surround(*args, &block)
|
18
|
+
context = CommandContext.new(*args)
|
19
|
+
context.instance_eval(&block) if block_given?
|
20
|
+
context
|
21
|
+
end
|
22
|
+
end
|
23
|
+
class Command
|
24
|
+
attr_accessor :context
|
25
|
+
def method_missing(method, *args, &block)
|
26
|
+
@compound_command = Command.new(method, *args, &block).tap{|c| c.context = context}
|
27
|
+
end
|
28
|
+
def initialize(command, *args)
|
29
|
+
@command = command
|
30
|
+
@args = Array(args).join("")
|
31
|
+
end
|
32
|
+
def pipe_to(&block)
|
33
|
+
command = Brash.build(&block)
|
34
|
+
@args += " | " + command.to_bash
|
35
|
+
end
|
36
|
+
def dash(*args)
|
37
|
+
@args += "-#{args.first}" if args.length > 0
|
38
|
+
@args += " " + args[1..-1].map{|arg| escape_arg(arg)}.join(" ") if args.length > 1
|
39
|
+
self
|
40
|
+
end
|
41
|
+
def arg(arg)
|
42
|
+
@args += " " + escape_arg(arg)
|
43
|
+
self
|
44
|
+
end
|
45
|
+
def escape_arg(arg)
|
46
|
+
if arg.is_a?(Proc)
|
47
|
+
CommandContext.surround(context.depth + 1, &arg).command.to_bash
|
48
|
+
elsif arg.is_a?(String) && arg.include?(" ")
|
49
|
+
escape(arg, context.depth+1)
|
50
|
+
else arg
|
51
|
+
end
|
52
|
+
end
|
53
|
+
def escape(bash, depth=context.depth)
|
54
|
+
escaped = bash
|
55
|
+
escaped = "\\"*(depth-1) + "\"" + "#{escaped}" + "\\"*(depth-1) + "\"" if depth > 0
|
56
|
+
escaped
|
57
|
+
end
|
58
|
+
def to_bash
|
59
|
+
bash = @command.to_s
|
60
|
+
bash += " " + @args unless @args == ""
|
61
|
+
bash += " " + @compound_command.to_bash if @compound_command
|
62
|
+
escape(bash)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "commands" do
|
4
|
+
it "should build simple command" do
|
5
|
+
brash = Brash.build { rm.dash("rf", "/tmp/nothing") }
|
6
|
+
brash.to_bash.should == "rm -rf /tmp/nothing"
|
7
|
+
end
|
8
|
+
it "should build simple command without dash" do
|
9
|
+
brash = Brash.build { cd("/tmp/somewhere") }
|
10
|
+
brash.to_bash.should == "cd /tmp/somewhere"
|
11
|
+
end
|
12
|
+
it "should build compound command" do
|
13
|
+
brash = Brash.build { xargs.echo }
|
14
|
+
brash.to_bash.should == "xargs echo"
|
15
|
+
end
|
16
|
+
it "should allow additional args" do
|
17
|
+
brash = Brash.build { email.dash("u", "jlane@engineyard.com").arg("ohhai") }
|
18
|
+
brash.to_bash.should == 'email -u jlane@engineyard.com ohhai'
|
19
|
+
end
|
20
|
+
it "should escape additional args with a space" do
|
21
|
+
brash = Brash.build { email.dash("u", "jlane@engineyard.com").arg("oh hai") }
|
22
|
+
brash.to_bash.should == 'email -u jlane@engineyard.com "oh hai"'
|
23
|
+
end
|
24
|
+
it "should escape dash arguments with a space" do
|
25
|
+
brash = Brash.build { email.dash("m", "lol ulol") }
|
26
|
+
brash.to_bash.should == 'email -m "lol ulol"'
|
27
|
+
end
|
28
|
+
it "should build simple command with pipe" do
|
29
|
+
brash = Brash.build { cat("/tmp/kitty").pipe_to { xargs } }
|
30
|
+
brash.to_bash.should == "cat /tmp/kitty | xargs"
|
31
|
+
end
|
32
|
+
it "should build compound command with pipe" do
|
33
|
+
brash = Brash.build { cat("/tmp/kitty").pipe_to { xargs.echo } }
|
34
|
+
brash.to_bash.should == "cat /tmp/kitty | xargs echo"
|
35
|
+
end
|
36
|
+
it "should escape compound command string arguments" do
|
37
|
+
brash = Brash.build do
|
38
|
+
ssh.dash("c", Proc.new { pwd })
|
39
|
+
end
|
40
|
+
brash.to_bash.should == 'ssh -c "pwd"'
|
41
|
+
end
|
42
|
+
it "should escape compound command string arguments more than once" do
|
43
|
+
brash = Brash.build do
|
44
|
+
ssh.dash("c", Proc.new { ssh.dash("c", Proc.new { pwd }) })
|
45
|
+
end
|
46
|
+
brash.to_bash.should == 'ssh -c "ssh -c \"pwd\""'
|
47
|
+
end
|
48
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: brash
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Joshua Lane
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-18 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: Build bash commands with Ruby
|
15
|
+
email:
|
16
|
+
- lane.joshlane@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- .rspec
|
23
|
+
- Gemfile
|
24
|
+
- Guardfile
|
25
|
+
- README
|
26
|
+
- Rakefile
|
27
|
+
- brash.gemspec
|
28
|
+
- lib/brash.rb
|
29
|
+
- lib/brash/command.rb
|
30
|
+
- lib/brash/version.rb
|
31
|
+
- spec/command_spec.rb
|
32
|
+
- spec/spec_helper.rb
|
33
|
+
homepage: http://github.com/lanej/brash
|
34
|
+
licenses: []
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.8.6
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: Build bash commands with Ruby
|
57
|
+
test_files:
|
58
|
+
- spec/command_spec.rb
|
59
|
+
- spec/spec_helper.rb
|