rprogram 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +33 -11
- data/README.md +7 -3
- data/lib/rprogram/program.rb +214 -24
- data/lib/rprogram/sudo.rb +14 -0
- data/lib/rprogram/sudo_task.rb +68 -0
- data/lib/rprogram/system.rb +316 -0
- data/lib/rprogram/task.rb +144 -16
- data/lib/rprogram/version.rb +1 -1
- data/rprogram.gemspec +1 -1
- data/spec/classes/aliased_program.rb +1 -5
- data/spec/classes/named_program.rb +1 -5
- data/spec/program_spec.rb +84 -1
- data/spec/scripts/echo.rb +3 -0
- data/spec/scripts/fail.rb +3 -0
- data/spec/scripts/print.rb +3 -0
- data/spec/scripts/success.rb +3 -0
- data/spec/system_spec.rb +80 -0
- data/spec/task_spec.rb +0 -15
- metadata +15 -20
- data/lib/rprogram/compat.rb +0 -124
- data/lib/rprogram/extensions.rb +0 -1
- data/lib/rprogram/nameable.rb +0 -2
- data/lib/rprogram/nameable/class_methods.rb +0 -84
- data/lib/rprogram/nameable/nameable.rb +0 -34
- data/lib/rprogram/options.rb +0 -2
- data/lib/rprogram/options/class_methods.rb +0 -112
- data/lib/rprogram/options/options.rb +0 -39
- data/spec/compat_spec.rb +0 -21
- data/spec/nameable_spec.rb +0 -83
data/ChangeLog.md
CHANGED
@@ -1,14 +1,36 @@
|
|
1
|
+
### 0.3.0 / 2011-04-08
|
2
|
+
|
3
|
+
* Merged `RProgram::Nameable` into {RProgram::Program}.
|
4
|
+
* Merged `RProgram::Options` into {RProgram::Task}.
|
5
|
+
* Renamed `RProgram::Compat` to {RProgram::System}.
|
6
|
+
* Added {RProgram::System.arch}.
|
7
|
+
* Added {RProgram::System.platform}.
|
8
|
+
* Added {RProgram::System.windows?}.
|
9
|
+
* Added {RProgram::System.ruby_1_8?}.
|
10
|
+
* Added {RProgram::System.jruby?}.
|
11
|
+
* Added {RProgram::System.sudo_path}.
|
12
|
+
* Added {RProgram::System.sudo_path=}.
|
13
|
+
* Added {RProgram::System.sudo?}.
|
14
|
+
* Added {RProgram::Sudo}.
|
15
|
+
* Added {RProgram::SudoTask}.
|
16
|
+
* Allow passing tailing [exec-options](http://rubydoc.info/stdlib/core/1.9.2/Kernel#spawn-instance_method)
|
17
|
+
to {RProgram::System.run} (only supported on Ruby 1.9).
|
18
|
+
* Allow using `IO.popen` in {RProgram::System.run} if the `:popen` option
|
19
|
+
is specified (only available on Ruby 1.9).
|
20
|
+
* Allow specifying the environment variables in {RProgram::System.run}
|
21
|
+
if the `:env` option is specified (only available on Ruby 1.9).
|
22
|
+
|
1
23
|
### 0.2.3 / 2011-03-30
|
2
24
|
|
3
25
|
* Require env ~> 0.1, >= 0.1.2.
|
4
26
|
* Automatically search for programs with a `.exe` suffix, when running on
|
5
27
|
Windows.
|
6
|
-
*
|
28
|
+
* `RProgram::Compat.find_program` and `RProgram::Compat.find_program_by_names`
|
7
29
|
now return a `Pathname` object.
|
8
30
|
|
9
31
|
### 0.2.2 / 2011-01-22
|
10
32
|
|
11
|
-
* Deprecated
|
33
|
+
* Deprecated `RProgram::Compat.platform`.
|
12
34
|
* Use `File::PATH_SEPARATOR` to separate the `PATH` environment variable
|
13
35
|
in `RProgram::Compat.paths`.
|
14
36
|
|
@@ -18,19 +40,19 @@
|
|
18
40
|
|
19
41
|
### 0.2.0 / 2010-10-03
|
20
42
|
|
21
|
-
* Added
|
22
|
-
* Added
|
23
|
-
* Added
|
43
|
+
* Added `RProgram::Nameable::ClassMethods`.
|
44
|
+
* Added `RProgram::Options::ClassMethods`.
|
45
|
+
* Added `RProgram::Nameable::ClassMethods#path`:
|
24
46
|
* {RProgram::Program.find} will default to
|
25
|
-
|
47
|
+
`RProgram::Nameable::ClassMethods#path` if set.
|
26
48
|
|
27
49
|
### 0.1.8 / 2009-12-24
|
28
50
|
|
29
51
|
* Allow Program to run commands under sudo:
|
30
|
-
* Added
|
31
|
-
* Added
|
32
|
-
* Added
|
33
|
-
* Added
|
52
|
+
* Added `RProgram::Compat.sudo`.
|
53
|
+
* Added `RProgram::Task#sudo`.
|
54
|
+
* Added `RProgram::Task#sudo=`.
|
55
|
+
* Added `RProgram::Task#sudo?`.
|
34
56
|
* Added {RProgram::Program#sudo}.
|
35
57
|
|
36
58
|
### 0.1.7 / 2009-09-21
|
@@ -46,7 +68,7 @@
|
|
46
68
|
|
47
69
|
* Use Hoe 2.2.0.
|
48
70
|
* Removed requirement for 'open3'.
|
49
|
-
* Renamed PRogram::Compat.PATHS to `RProgram::Compat.paths`.
|
71
|
+
* Renamed `PRogram::Compat.PATHS` to `RProgram::Compat.paths`.
|
50
72
|
* Refactored {RProgram::Option#arguments}.
|
51
73
|
* Removed `RProgram::Option#format`.
|
52
74
|
* Refactored {RProgram::NonOption#arguments}.
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
* [Source](http://github.com/postmodern/rprogram)
|
4
4
|
* [Issues](http://github.com/postmodern/rprogram/issues)
|
5
|
-
* [Documentation](http://rubydoc.info/gems/rprogram)
|
5
|
+
* [Documentation](http://rubydoc.info/gems/rprogram/frames)
|
6
6
|
* [Email](mailto:postmodern.mod3 at gmail.com)
|
7
7
|
|
8
8
|
## Description
|
@@ -14,8 +14,12 @@ system.
|
|
14
14
|
|
15
15
|
## Features
|
16
16
|
|
17
|
-
*
|
18
|
-
|
17
|
+
* Safely executes individual programs and their separate command-line
|
18
|
+
arguments, to prevent command or option injection.
|
19
|
+
* Supports using Ruby 1.9 [exec options](http://rubydoc.info/stdlib/core/1.9.2/Kernel#spawn-instance_method).
|
20
|
+
* Supports specifying environment variables of a process
|
21
|
+
(only available on Ruby 1.9).
|
22
|
+
* Allows running programs with `IO.popen` (only available on Ruby 1.9).
|
19
23
|
* Allows running programs under `sudo`.
|
20
24
|
* Provides cross-platform access to the `PATH` environment variable.
|
21
25
|
* Supports leading/tailing non-options.
|
data/lib/rprogram/program.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
require 'rprogram/rprogram'
|
2
|
-
require 'rprogram/
|
2
|
+
require 'rprogram/system'
|
3
3
|
require 'rprogram/task'
|
4
|
-
require 'rprogram/
|
4
|
+
require 'rprogram/sudo_task'
|
5
5
|
require 'rprogram/exceptions/program_not_found'
|
6
6
|
|
7
7
|
module RProgram
|
8
8
|
class Program
|
9
9
|
|
10
|
-
include Nameable
|
11
|
-
|
12
10
|
# Path to the program
|
13
11
|
attr_reader :path
|
14
12
|
|
@@ -47,6 +45,87 @@ module RProgram
|
|
47
45
|
block.call(self) if block
|
48
46
|
end
|
49
47
|
|
48
|
+
#
|
49
|
+
# @return [String]
|
50
|
+
# The name of the program.
|
51
|
+
#
|
52
|
+
def self.program_name
|
53
|
+
@program_name ||= nil
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# @return [Array]
|
58
|
+
# The program's aliases.
|
59
|
+
#
|
60
|
+
def self.program_aliases
|
61
|
+
@program_aliases ||= []
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Combines program_name with program_aliases.
|
66
|
+
#
|
67
|
+
# @return [Array]
|
68
|
+
# Names the program is known by.
|
69
|
+
#
|
70
|
+
def self.program_names
|
71
|
+
([program_name] + program_aliases).compact
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Sets the program name for the class.
|
76
|
+
#
|
77
|
+
# @param [String, Symbol] name
|
78
|
+
# The new program name.
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# name_program 'ls'
|
82
|
+
#
|
83
|
+
def self.name_program(name)
|
84
|
+
@program_name = name.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Sets the program aliases for the class.
|
89
|
+
#
|
90
|
+
# @param [Array] aliases
|
91
|
+
# The new program aliases.
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# alias_program 'vim', 'vi'
|
95
|
+
#
|
96
|
+
def self.alias_program(*aliases)
|
97
|
+
@program_aliases = aliases.map { |name| name.to_s }
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# The default path of the program.
|
102
|
+
#
|
103
|
+
# @return [String, nil]
|
104
|
+
# The path to the program.
|
105
|
+
#
|
106
|
+
# @since 0.2.0
|
107
|
+
#
|
108
|
+
def self.path
|
109
|
+
@program_path
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Sets the default path to the program.
|
114
|
+
#
|
115
|
+
# @param [String] new_path
|
116
|
+
# The new path to the program.
|
117
|
+
#
|
118
|
+
# @return [String, nil]
|
119
|
+
# The path to the program.
|
120
|
+
#
|
121
|
+
# @since 0.2.0
|
122
|
+
#
|
123
|
+
def self.path=(new_path)
|
124
|
+
@program_path = if new_path
|
125
|
+
File.expand_path(new_path)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
50
129
|
#
|
51
130
|
# Creates a new program object.
|
52
131
|
#
|
@@ -76,7 +155,7 @@ module RProgram
|
|
76
155
|
# # => nil
|
77
156
|
#
|
78
157
|
def self.find_with_path(path,*arguments,&block)
|
79
|
-
|
158
|
+
self.new(path,*arguments,&block) if File.file?(path)
|
80
159
|
end
|
81
160
|
|
82
161
|
#
|
@@ -111,7 +190,9 @@ module RProgram
|
|
111
190
|
#
|
112
191
|
def self.find_with_paths(paths,*arguments,&block)
|
113
192
|
paths.each do |path|
|
114
|
-
|
193
|
+
if File.file?(path)
|
194
|
+
return self.new(path,*arguments,&block)
|
195
|
+
end
|
115
196
|
end
|
116
197
|
end
|
117
198
|
|
@@ -145,7 +226,7 @@ module RProgram
|
|
145
226
|
#
|
146
227
|
def self.find(*arguments,&block)
|
147
228
|
path = self.path
|
148
|
-
path ||=
|
229
|
+
path ||= System.find_program_by_names(*self.program_names)
|
149
230
|
|
150
231
|
unless path
|
151
232
|
names = self.program_names.map { |name| name.dump }.join(', ')
|
@@ -156,11 +237,54 @@ module RProgram
|
|
156
237
|
return self.new(path,*arguments,&block)
|
157
238
|
end
|
158
239
|
|
240
|
+
#
|
241
|
+
# @return [String]
|
242
|
+
# The program name of the class.
|
243
|
+
#
|
244
|
+
def program_name
|
245
|
+
self.class.program_name
|
246
|
+
end
|
247
|
+
|
248
|
+
#
|
249
|
+
# @return [Array]
|
250
|
+
# The program aliases of the class.
|
251
|
+
#
|
252
|
+
def program_aliases
|
253
|
+
self.class.program_aliases
|
254
|
+
end
|
255
|
+
|
256
|
+
#
|
257
|
+
# @return [Array]
|
258
|
+
# The program names of the class.
|
259
|
+
#
|
260
|
+
def program_names
|
261
|
+
self.class.program_names
|
262
|
+
end
|
263
|
+
|
159
264
|
#
|
160
265
|
# Runs the program.
|
161
266
|
#
|
162
|
-
# @
|
163
|
-
#
|
267
|
+
# @overload run(*arguments)
|
268
|
+
# Run the program with the given arguments.
|
269
|
+
#
|
270
|
+
# @param [Array] arguments
|
271
|
+
# Additional arguments to run the program with.
|
272
|
+
#
|
273
|
+
# @overload run(*arguments,options)
|
274
|
+
# Run the program with the given arguments and options.
|
275
|
+
#
|
276
|
+
# @param [Array] arguments
|
277
|
+
# Additional arguments to run the program with.
|
278
|
+
#
|
279
|
+
# @param [Hash] options
|
280
|
+
# Additional options to execute the program with.
|
281
|
+
#
|
282
|
+
# @option options [Hash{String => String}] :env
|
283
|
+
# Environment variables to execute the program with.
|
284
|
+
#
|
285
|
+
# @option options [String] :popen
|
286
|
+
# Specifies to run the program using `IO.popen` with the given
|
287
|
+
# IO mode.
|
164
288
|
#
|
165
289
|
# @return [true, false]
|
166
290
|
# Specifies the exit status of the program.
|
@@ -171,17 +295,34 @@ module RProgram
|
|
171
295
|
# # hello
|
172
296
|
# # => true
|
173
297
|
#
|
174
|
-
# @see Kernel
|
298
|
+
# @see http://rubydoc.info/stdlib/core/1.9.2/Kernel#spawn-instance_method
|
299
|
+
# For acceptable options.
|
175
300
|
#
|
176
|
-
def run(*
|
177
|
-
|
301
|
+
def run(*arguments)
|
302
|
+
System.run(@path,*arguments)
|
178
303
|
end
|
179
304
|
|
180
305
|
#
|
181
306
|
# Runs the program under sudo.
|
182
307
|
#
|
183
|
-
# @
|
184
|
-
#
|
308
|
+
# @overload sudo(*arguments)
|
309
|
+
# Run the program under `sudo` with the given arguments.
|
310
|
+
#
|
311
|
+
# @param [Array] arguments
|
312
|
+
# Additional arguments to run the program with.
|
313
|
+
#
|
314
|
+
# @overload sudo(*arguments,options)
|
315
|
+
# Run the program under `sudo` with the given arguments
|
316
|
+
# and options.
|
317
|
+
#
|
318
|
+
# @param [Array] arguments
|
319
|
+
# Additional arguments to run the program with.
|
320
|
+
#
|
321
|
+
# @param [Hash] options
|
322
|
+
# Additional options to execute the program with.
|
323
|
+
#
|
324
|
+
# @option options [Hash{Symbol => Object}] :sudo
|
325
|
+
# Additional `sudo` options.
|
185
326
|
#
|
186
327
|
# @return [Boolean]
|
187
328
|
# Specifies whether the program exited successfully.
|
@@ -191,27 +332,76 @@ module RProgram
|
|
191
332
|
#
|
192
333
|
# @since 0.1.8
|
193
334
|
#
|
194
|
-
|
195
|
-
|
335
|
+
# @see http://rubydoc.info/stdlib/core/1.9.2/Kernel#spawn-instance_method
|
336
|
+
# For acceptable options.
|
337
|
+
#
|
338
|
+
# @see SudoTask
|
339
|
+
# For valid `:sudo` options.
|
340
|
+
#
|
341
|
+
def sudo(*arguments)
|
342
|
+
options = if arguments.last.kind_of?(Hash)
|
343
|
+
arguments.pop
|
344
|
+
else
|
345
|
+
{}
|
346
|
+
end
|
347
|
+
|
348
|
+
task = SudoTask.new(options.delete(:sudo) || {})
|
349
|
+
task.command = [@path] + arguments
|
350
|
+
|
351
|
+
arguments = task.arguments
|
352
|
+
arguments << options unless options.empty?
|
353
|
+
|
354
|
+
return System.sudo(*arguments)
|
196
355
|
end
|
197
356
|
|
198
357
|
#
|
199
358
|
# Runs the program with the arguments from the given task.
|
200
359
|
#
|
201
|
-
# @param [Task] task
|
360
|
+
# @param [Task, #to_a] task
|
202
361
|
# The task who's arguments will be used to run the program.
|
203
362
|
#
|
363
|
+
# @param [Hash] options
|
364
|
+
# Additional options to execute the program with.
|
365
|
+
#
|
204
366
|
# @return [true, false]
|
205
367
|
# Specifies the exit status of the program.
|
206
368
|
#
|
207
|
-
# @see
|
369
|
+
# @see #run
|
208
370
|
#
|
209
|
-
def run_task(task)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
371
|
+
def run_task(task,options={})
|
372
|
+
arguments = task.arguments
|
373
|
+
arguments << options unless options.empty?
|
374
|
+
|
375
|
+
return run(*arguments)
|
376
|
+
end
|
377
|
+
|
378
|
+
#
|
379
|
+
# Runs the program under `sudo` with the arguments from the given task.
|
380
|
+
#
|
381
|
+
# @param [Task, #to_a] task
|
382
|
+
# The task who's arguments will be used to run the program.
|
383
|
+
#
|
384
|
+
# @param [Hash] options
|
385
|
+
# Spawn options for the program to be ran.
|
386
|
+
#
|
387
|
+
# @yield [sudo]
|
388
|
+
# If a block is given, it will be passed the sudo task.
|
389
|
+
#
|
390
|
+
# @yieldparam [SudoTask] sudo
|
391
|
+
# The sudo tasks.
|
392
|
+
#
|
393
|
+
# @return [true, false]
|
394
|
+
# Specifies the exit status of the program.
|
395
|
+
#
|
396
|
+
# @see #sudo
|
397
|
+
#
|
398
|
+
# @since 0.3.0
|
399
|
+
#
|
400
|
+
def sudo_task(task,options={},&block)
|
401
|
+
arguments = task.arguments
|
402
|
+
arguments << options unless options.empty?
|
403
|
+
|
404
|
+
return sudo(*arguments,&block)
|
215
405
|
end
|
216
406
|
|
217
407
|
#
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rprogram/task'
|
2
|
+
|
3
|
+
module RProgram
|
4
|
+
#
|
5
|
+
# Represents the options for `sudo`.
|
6
|
+
#
|
7
|
+
# ## Sudo options:
|
8
|
+
#
|
9
|
+
# * `-A` - `sudo.ask_password`
|
10
|
+
# * `-b` - `sudo.background`
|
11
|
+
# * `-C` - `sudo.close_from`
|
12
|
+
# * `-E` - `sudo.preserve_env`
|
13
|
+
# * `-e` - `sudo.edit`
|
14
|
+
# * `-g` - `sudo.group`
|
15
|
+
# * `-H` - `sudo.home`
|
16
|
+
# * `-h` - `sudo.help`
|
17
|
+
# * `-i` - `sudo.simulate_initial_login`
|
18
|
+
# * `-k` - `sudo.kill`
|
19
|
+
# * `-K` - `sudo.sure_kill`
|
20
|
+
# * `-L` - `sudo.list_defaults`
|
21
|
+
# * `-l` - `sudo.list`
|
22
|
+
# * `-n` - `sudo.non_interactive`
|
23
|
+
# * `-P` - `sudo.preserve_group`
|
24
|
+
# * `-p` - `sudo.prompt`
|
25
|
+
# * `-r` - `sudo.role`
|
26
|
+
# * `-S` - `sudo.stdin`
|
27
|
+
# * `-s` - `sudo.shell`
|
28
|
+
# * `-t` - `sudo.type`
|
29
|
+
# * `-U` - `sudo.other_user`
|
30
|
+
# * `-u` - `sudo.user`
|
31
|
+
# * `-V` - `sudo.version`
|
32
|
+
# * `-v` - `sudo.validate`
|
33
|
+
#
|
34
|
+
# * `[command]` - `sudo.command`
|
35
|
+
#
|
36
|
+
# @since 0.3.0
|
37
|
+
#
|
38
|
+
class SudoTask < Task
|
39
|
+
|
40
|
+
short_option :name => :ask_password, :flag => '-A'
|
41
|
+
short_option :name => :background, :flag => '-b'
|
42
|
+
short_option :name => :close_from, :flag => '-C'
|
43
|
+
short_option :name => :preserve_env, :flag => '-E'
|
44
|
+
short_option :name => :edit, :flag => '-e'
|
45
|
+
short_option :name => :group, :flag => '-g'
|
46
|
+
short_option :name => :home, :flag => '-H'
|
47
|
+
short_option :name => :help, :flag => '-h'
|
48
|
+
short_option :name => :simulate_initial_login, :flag => '-i'
|
49
|
+
short_option :name => :kill, :flag => '-k'
|
50
|
+
short_option :name => :sure_kill, :flag => '-K'
|
51
|
+
short_option :name => :list_defaults, :flag => '-L'
|
52
|
+
short_option :name => :list, :flag => '-l'
|
53
|
+
short_option :name => :non_interactive, :flag => '-n'
|
54
|
+
short_option :name => :preserve_group, :flag => '-P'
|
55
|
+
short_option :name => :prompt, :flag => '-p'
|
56
|
+
short_option :name => :role, :flag => '-r'
|
57
|
+
short_option :name => :stdin, :flag => '-S'
|
58
|
+
short_option :name => :shell, :flag => '-s'
|
59
|
+
short_option :name => :type, :flag => '-t'
|
60
|
+
short_option :name => :other_user, :flag => '-U'
|
61
|
+
short_option :name => :user, :flag => '-u'
|
62
|
+
short_option :name => :version, :flag => '-V'
|
63
|
+
short_option :name => :validate, :flag => '-v'
|
64
|
+
|
65
|
+
non_option :tailing => true, :name => :command
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|