rprogram 0.2.3 → 0.3.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/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
|