command-builder 0.1.0

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "depq", ">= 0.4"
5
+ gem "hash-utils", ">= 0.7.0"
6
+
7
+ # Add dependencies to develop your gem here.
8
+ # Include everything needed to run rake, tests, features, etc.
9
+ group :development do
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.5.2"
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ hash-utils (0.8.0)
6
+ jeweler (1.5.2)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.8.7)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ bundler (~> 1.0.0)
17
+ hash-utils (>= 0.7.0)
18
+ jeweler (~> 1.5.2)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ Command Builder
2
+ ===============
3
+
4
+ **Command Builder** builds call to some command runnable from shell
5
+ command line from its arguments. Here is real example of call to
6
+ `jpegoptim`:
7
+
8
+ require "command-builder"
9
+ cmd = CommandBuilder::new(:jpegoptim)
10
+
11
+ cmd.arg(:m, 2)
12
+ cmd << :preserve
13
+ cmd << "image.jpg"
14
+
15
+ cmd.to_s # will return 'jpegoptim -m 2 --preserve
16
+
17
+ Value escaping and assignments are supported automatically of sure,
18
+ so call:
19
+ cmd.arg(:dest, './it\'s "my" folder')
20
+
21
+ …will be interpreted as `jpegoptim --dest="it's \"my\" folder"`. It also
22
+ takes spaces into the account.
23
+
24
+ ### Flexibility
25
+
26
+ Syntax described above is supported by default, but you can achieve for
27
+ example an Windows like syntax:
28
+ jpegoptim /m:2 -dest "directory"
29
+
30
+ …simply by assigning:
31
+ cmd.separators = ["/", ":", "-", " "]
32
+
33
+ For illustration, the default one is `["-", " ", "--", "="]`.
34
+
35
+
36
+ Contributing
37
+ ------------
38
+
39
+ 1. Fork it.
40
+ 2. Create a branch (`git checkout -b 20101220-my-change`).
41
+ 3. Commit your changes (`git commit -am "Added something"`).
42
+ 4. Push to the branch (`git push origin 20101220-my-change`).
43
+ 5. Create an [Issue][2] with a link to your branch.
44
+ 6. Enjoy a refreshing Diet Coke and wait.
45
+
46
+
47
+ Copyright
48
+ ---------
49
+
50
+ Copyright &copy; 2011 [Martin Kozák][3]. See `LICENSE.txt` for
51
+ further details.
52
+
53
+ [2]: http://github.com/martinkozak/qrpc/issues
54
+ [3]: http://www.martinkozak.net/
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+ require 'rake'
12
+
13
+ require 'jeweler'
14
+ Jeweler::Tasks.new do |gem|
15
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
16
+ gem.name = "command-builder"
17
+ gem.homepage = "https://github.com/martinkozak/command-builder"
18
+ gem.license = "MIT"
19
+ gem.summary = 'Builds call to some command runnable from shell command line from its arguments.'
20
+ gem.email = "martinkozak@martinkozak.net"
21
+ gem.authors = ["Martin Kozák"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/rdoctask'
30
+ Rake::RDocTask.new do |rdoc|
31
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
32
+
33
+ rdoc.rdoc_dir = 'rdoc'
34
+ rdoc.title = "qrpc #{version}"
35
+ rdoc.rdoc_files.include('README*')
36
+ rdoc.rdoc_files.include('lib/**/*.rb')
37
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,54 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{command-builder}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Martin Kozák"]
12
+ s.date = %q{2011-02-16}
13
+ s.email = %q{martinkozak@martinkozak.net}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE.txt",
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "command-builder.gemspec",
27
+ "lib/command-builder.rb",
28
+ "test.rb"
29
+ ]
30
+ s.homepage = %q{https://github.com/martinkozak/command-builder}
31
+ s.licenses = ["MIT"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = %q{1.5.2}
34
+ s.summary = %q{Builds call to some command runnable from shell command line from its arguments.}
35
+
36
+ if s.respond_to? :specification_version then
37
+ s.specification_version = 3
38
+
39
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
+ s.add_runtime_dependency(%q<hash-utils>, [">= 0.7.0"])
41
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
42
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
43
+ else
44
+ s.add_dependency(%q<hash-utils>, [">= 0.7.0"])
45
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
46
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
47
+ end
48
+ else
49
+ s.add_dependency(%q<hash-utils>, [">= 0.7.0"])
50
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
51
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
52
+ end
53
+ end
54
+
@@ -0,0 +1,288 @@
1
+ # encoding: utf-8
2
+
3
+ require "hash-utils/object"
4
+
5
+ ##
6
+ # Represents one command line command with arguments and parameters.
7
+ #
8
+
9
+ class CommandBuilder
10
+
11
+ ##
12
+ # Holds command name.
13
+ # @return [String, Symbol] command body
14
+ #
15
+
16
+ attr_accessor :command
17
+ @command
18
+
19
+ ##
20
+ # Holds separators matrix. It's four-items array:
21
+ # - short argument separator,
22
+ # - short argument name/value separator,
23
+ # - long argument separator,
24
+ # - short argument name/value separator.
25
+ #
26
+ # Here is some example in the same order as in command:
27
+ #
28
+ # # ["-", " ", "--", "="]
29
+ # command -s something --long=something
30
+ #
31
+ # @return [Array] separators matrix
32
+ #
33
+
34
+ attr_accessor :separators
35
+ @separators
36
+
37
+ ##
38
+ # Holds arguments array. Each item is array pair with argument
39
+ # name and value.
40
+ #
41
+ # @return [Array] array of argument pairs
42
+ #
43
+
44
+ attr_accessor :args
45
+ @args
46
+
47
+ ##
48
+ # Holds parameters array.
49
+ #
50
+
51
+ @params
52
+
53
+ ##
54
+ # Constructor.
55
+ #
56
+ # @param [String, Symbol] command target command
57
+ # @param [Array] separators separators matrix
58
+ # @see #separators
59
+ #
60
+
61
+ def initialize(command, separators = ["-", " ", "--", "="])
62
+ @command = command
63
+ @separators = separators
64
+ @args = [ ]
65
+ @params = [ ]
66
+ end
67
+
68
+ ##
69
+ # Adds argument to command.
70
+ #
71
+ # One-letter arguments will be treated as "short" arguments for the
72
+ # syntax purposes, other as "long". See {#separators}.
73
+ #
74
+ # @example with default set of {#separators}
75
+ # cmd = Command::new(:jpegoptim)
76
+ # @cmd.argument(:p) # will be rendered as 'jpegoptim -p'
77
+ # @cmd.argument(:preserve) # will be rendered as 'jpegoptim -p --preserve'
78
+ # @cmd.argument(:m, 2) # will be rendered as 'jpegoptim -p --preserve -m 2'
79
+ # @cmd.argument(:max, 2) # will be rendered as 'jpegoptim -p --preserve -m 2 --max=2'
80
+ # @example with array-like call
81
+ # cmd = Command::new(:jpegoptim)
82
+ # @cmd[:m] = 2 # will be rendered as 'jpegoptim -m 2'
83
+ # @cmd[:max] = 2 # will be rendered as 'jpegoptim -m 2 --max=2'
84
+ #
85
+ # # But be warn, it pushes to arguments array as you can se, so
86
+ # # already existing values will not be replaced!
87
+ #
88
+ # @param [String, Symbol] name of the argument
89
+ # @param [Object] value of the argument
90
+ #
91
+
92
+ def argument(name, value = nil)
93
+ @args << [name, value]
94
+ end
95
+
96
+ alias :arg :argument
97
+ alias :[]= :argument
98
+
99
+ ##
100
+ # Returns array of argument pairs with given name.
101
+ #
102
+ # @param [String, Symbol] name argument name
103
+ # @return [Array] array of array pairs with this name
104
+ #
105
+
106
+ def [](name)
107
+ @args.select { |k, v| name == k }
108
+ end
109
+
110
+ ##
111
+ # Adds parameter to command.
112
+ # @param [Object] value value of the prameter convertable to String.
113
+ #
114
+
115
+ def parameter(value)
116
+ @params << value
117
+ end
118
+
119
+ alias :param :parameter
120
+
121
+ ##
122
+ # Adds multiple parameters to command at once. If no values are
123
+ # given, returns the current parameters array.
124
+ #
125
+ # @overload parameters
126
+ # Returns current parameters array.
127
+ # @return [Array] current parameters array
128
+ # @overload parameters(values)
129
+ # Adds multiple parameters at once.
130
+ # @param [Array] values array of values
131
+ # @see #parameter
132
+ #
133
+
134
+ def parameters(values = nil)
135
+ if values.nil?
136
+ return @params
137
+ else
138
+ @params += values
139
+ end
140
+ end
141
+
142
+ alias :params :parameters
143
+
144
+ ##
145
+ # Adds an item to command. If option is Symbol or value isn't +nil+,
146
+ # it will apply the item as an argument, in otherwise, it will treat
147
+ # as an symbol.
148
+ #
149
+ # @overload add(option)
150
+ # Adds parameter.
151
+ # @param [Object] option parameter value
152
+ # @see #parameter
153
+ # @overload add(options)
154
+ # Adds parameters
155
+ # @param [Array] options parameters values
156
+ # @see #parameters
157
+ # @overload add(option, value = nil)
158
+ # Adds argument.
159
+ # @param [Symbol] option argument name
160
+ # @param [Object] value argument value
161
+ # @see #argument
162
+ #
163
+ # @example
164
+ # cmd = Command::new(:jpegoptim)
165
+ # cmd << :preserve # will be rendered as 'jpegoptim --preserve'
166
+ # cmd << "file.jpg" # will be rendered as 'jpegoptiom --preserve file.jpg'
167
+ #
168
+
169
+ def add(option, value = nil)
170
+ if option.kind_of? Symbol or not value.nil?
171
+ self.argument(option, value)
172
+ elsif option.kind_of? Array
173
+ self.parameters(option)
174
+ else
175
+ self.parameter(option)
176
+ end
177
+ end
178
+
179
+ alias :<< :add
180
+
181
+ ##
182
+ # Quotes value for use in command line.
183
+ #
184
+ # Uses some heuristic for setting the right quotation. If both
185
+ # " and ' are found, escapes ' by \ and quotes by ". If only one of
186
+ # them found, escapes by the second one. If space found in the
187
+ # string, quotes by " too.
188
+ #
189
+ # @example
190
+ # cmd = Command::new(:jpegoptim)
191
+ # cmd.escape("hello 'something' world") # will result to < "hello 'something' world" >
192
+ # cmd.escape('hello "something" world') # will result to < 'hello "something" world' >
193
+ # cmd.escape('hello "som\'thing" world') # will result to < "hello \"som'thing\" world" >
194
+ # cmd.escape('hello something world') # will result to < "hello something world" >
195
+ #
196
+ # @param [String] value string for escaping
197
+ # @return [String] quoted value
198
+ #
199
+
200
+ def quote(value)
201
+ value = value.to_s
202
+
203
+ # Looks for " and '
204
+ single = value["'"].to_b
205
+ double = value['"'].to_b
206
+
207
+ # According to found characters selects quotation
208
+ if single and value
209
+ value = value.gsub('"', '\\"')
210
+ quotation = '"'
211
+ elsif single
212
+ quotation = '"'
213
+ elsif double
214
+ quotation = "'"
215
+ elsif value[" "]
216
+ quotation = '"'
217
+ else
218
+ quotation = ""
219
+ end
220
+
221
+ # Returns
222
+ return quotation + value + quotation
223
+ end
224
+
225
+ ##
226
+ # Executes the command.
227
+ #
228
+
229
+ def execute
230
+ Kernel.system(self.to_s)
231
+ end
232
+
233
+ alias :exec :execute
234
+
235
+ ##
236
+ # Converts command to string.
237
+ # @return [String] command in string form
238
+ #
239
+
240
+ def to_s
241
+ cmd = @command.to_s.gsub(" ", "\\ ")
242
+
243
+ # Arguments
244
+ @args.each do |name, value|
245
+ __add_arg(cmd, name, value)
246
+ end
247
+
248
+ # Parameters
249
+ @params.each do |param|
250
+ cmd << " " << self.quote(param.to_s)
251
+ end
252
+
253
+ return cmd
254
+ end
255
+
256
+
257
+ private
258
+
259
+ ##
260
+ # Adds argument to command.
261
+ #
262
+
263
+ def __add_arg(cmd, name, value)
264
+ cmd << " "
265
+ name = name.to_s
266
+
267
+ # Name
268
+ short = (name.length == 1)
269
+
270
+ if short
271
+ cmd << @separators[0]
272
+ else
273
+ cmd << @separators[2]
274
+ end
275
+ cmd << name
276
+
277
+ # Value
278
+ if not value.nil?
279
+ if short
280
+ cmd << @separators[1]
281
+ else
282
+ cmd << @separators[3]
283
+ end
284
+ cmd << self.quote(value.to_s)
285
+ end
286
+ end
287
+
288
+ end
data/test.rb ADDED
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ require "./jpeg"
4
+
5
+ cmd = CommandBuilder::new(:jpegoptim)
6
+ cmd << :preserve
7
+ cmd << :p
8
+ cmd << "file.jpg"
9
+ cmd << ["1.jpg", "2.jpg"]
10
+ cmd.arg(:max, 3)
11
+ cmd.arg(:m, 3)
12
+ cmd[:other] = "value"
13
+ cmd[:o] = "another '\" value"
14
+ puts cmd
15
+
16
+ puts cmd[:max].inspect
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: command-builder
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - "Martin Koz\xC3\xA1k"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-02-16 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: hash-utils
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.7.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.0.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: jeweler
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.5.2
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ description:
50
+ email: martinkozak@martinkozak.net
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - LICENSE.txt
57
+ - README.md
58
+ files:
59
+ - .document
60
+ - Gemfile
61
+ - Gemfile.lock
62
+ - LICENSE.txt
63
+ - README.md
64
+ - Rakefile
65
+ - VERSION
66
+ - command-builder.gemspec
67
+ - lib/command-builder.rb
68
+ - test.rb
69
+ has_rdoc: true
70
+ homepage: https://github.com/martinkozak/command-builder
71
+ licenses:
72
+ - MIT
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ hash: -3460613354245492068
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
93
+ requirements: []
94
+
95
+ rubyforge_project:
96
+ rubygems_version: 1.5.2
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Builds call to some command runnable from shell command line from its arguments.
100
+ test_files: []
101
+