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 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
- * {RProgram::Compat.find_program} and {RProgram::Compat.find_program_by_names}
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 {RProgram::Compat.platform}.
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 {RProgram::Nameable::ClassMethods}.
22
- * Added {RProgram::Options::ClassMethods}.
23
- * Added {RProgram::Nameable::ClassMethods#path}:
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
- {RProgram::Nameable::ClassMethods#path} if set.
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 {RProgram::Compat.sudo}.
31
- * Added {RProgram::Task#sudo}.
32
- * Added {RProgram::Task#sudo=}.
33
- * Added {RProgram::Task#sudo?}.
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
- * Uses Kernel.system for safe execution of individual programs and their
18
- separate command-line arguments.
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.
@@ -1,14 +1,12 @@
1
1
  require 'rprogram/rprogram'
2
- require 'rprogram/compat'
2
+ require 'rprogram/system'
3
3
  require 'rprogram/task'
4
- require 'rprogram/nameable'
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
- return self.new(path,*arguments,&block) if File.file?(path)
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
- return self.new(path,*arguments,&block) if File.file?(path)
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 ||= Compat.find_program_by_names(*self.program_names)
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
- # @param [Array] args
163
- # Addition arguments to run the program with.
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.system
298
+ # @see http://rubydoc.info/stdlib/core/1.9.2/Kernel#spawn-instance_method
299
+ # For acceptable options.
175
300
  #
176
- def run(*args)
177
- Compat.run(@path,*args)
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
- # @param [Array] args
184
- # Additional arguments to run the program with.
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
- def sudo(*args)
195
- Compat.sudo(@path,*args)
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 Kernel.system
369
+ # @see #run
208
370
  #
209
- def run_task(task)
210
- if task.sudo?
211
- return sudo(*(task.arguments))
212
- else
213
- return run(*(task.arguments))
214
- end
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,14 @@
1
+ require 'rprogram/program'
2
+
3
+ module RProgram
4
+ #
5
+ # Represents the `sudo` executable.
6
+ #
7
+ # @since 0.3.0
8
+ #
9
+ class Sudo < Program
10
+
11
+ name_program 'sudo'
12
+
13
+ end
14
+ end
@@ -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