rprogram 0.1.8 → 0.2.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/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ doc
2
+ pkg
3
+ tmp/*
4
+ .DS_Store
5
+ .yardoc
6
+ *.db
7
+ *.log
8
+ *.swp
9
+ *~
data/.specopts ADDED
@@ -0,0 +1 @@
1
+ --colour --format specdoc
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title 'RProgram Documentation' --protected --files ChangeLog.md,LICENSE.txt
data/ChangeLog.md ADDED
@@ -0,0 +1,103 @@
1
+ ### 0.2.0 / 2010-10-03
2
+
3
+ * Added {RProgram::Nameable::ClassMethods}.
4
+ * Added {RProgram::Options::ClassMethods}.
5
+ * Added {RProgram::Nameable::ClassMethods#path}:
6
+ * {RProgram::Program.find} will default to
7
+ {RProgram::Nameable::ClassMethods#path} if set.
8
+
9
+ ### 0.1.8 / 2009-12-24
10
+
11
+ * Allow Program to run commands under sudo:
12
+ * Added {RProgram::Compat.sudo}.
13
+ * Added {RProgram::Task#sudo}.
14
+ * Added {RProgram::Task#sudo=}.
15
+ * Added {RProgram::Task#sudo?}.
16
+ * Added {RProgram::Program#sudo}.
17
+
18
+ ### 0.1.7 / 2009-09-21
19
+
20
+ * Require Hoe >= 2.3.3.
21
+ * Require YARD >= 0.2.3.5.
22
+ * Require RSpec >= 1.2.8.
23
+ * Use 'hoe/signing' for signed RubyGems.
24
+ * Moved to YARD based documentation.
25
+ * All specs pass on JRuby 1.3.1.
26
+
27
+ ### 0.1.6 / 2009-06-30
28
+
29
+ * Use Hoe 2.2.0.
30
+ * Removed requirement for 'open3'.
31
+ * Renamed PRogram::Compat.PATHS to {RProgram::Compat.paths}.
32
+ * Refactored {RProgram::Option#arguments}.
33
+ * Removed `RProgram::Option#format`.
34
+ * Refactored {RProgram::NonOption#arguments}.
35
+ * Renamed `RProgram::NonOption#leading` to {RProgram::NonOption#leading?}.
36
+ * Removed `RProgram::NonOption#tailing`.
37
+ * Added {RProgram::NonOption#tailing?}.
38
+ * Added specs.
39
+ * All specs pass on Ruby 1.9.1-p0 and 1.8.6-p287.
40
+
41
+ ### 0.1.5 / 2009-01-14
42
+
43
+ * Use Kernel.system in {RProgram::Program#run}, instead of Open3.popen3:
44
+ * popen3 is not well supported on Windows.
45
+ * win32-open3 does not allow for the execution of single programs with
46
+ separate command-line arguments. Instead, it merely executes a command
47
+ string in command.com. This seems to allow arbitrary command injection
48
+ via command-line arguments.
49
+ * {RProgram::Program#run} will now return either `true` or `false`,
50
+ depending on the exit status of the program.
51
+ * Added some missing documentation.
52
+
53
+ ### 0.1.4 / 2009-01-07
54
+
55
+ * Added `lib/rprogram/rprogram.rb` to the Manifest.
56
+ * Added more documentation.
57
+
58
+ ### 0.1.3 / 2008-01-27
59
+
60
+ * Renamed `RProgram::Program.create_from_path` to
61
+ {RProgram::Program.find_with_path}.
62
+ * Renamed `RProgram::Program.create_from_paths` to
63
+ {RProgram::Program.find_with_paths}.
64
+ * Renamed `RProgram::Program.create` to {RProgram::Program.find}.
65
+ * Renamed `RProgram::Program.run_with_task` to {RProgram::Program#run_task}.
66
+
67
+ ### 0.1.2 / 2008-01-18
68
+
69
+ * DRYed up lib/rprogram/task.
70
+ * Added {RProgram::Task.define_option}.
71
+ * Added OptionList so that Option may contain sub-options.
72
+ * Touched up documenation.
73
+
74
+ ### 0.1.1 / 2008-01-18
75
+
76
+ * Added support for the {RProgram::Option} argument separators.
77
+
78
+ #
79
+ # Creates arguments of the form:
80
+ #
81
+ # ["-opts","value1:value2:value3"]
82
+ #
83
+ long_option :flag => '-opts', :separator => ':'
84
+
85
+ * Fixed the `lib/rprogram.rb` file.
86
+
87
+ ### 0.1.0 / 2008-01-17
88
+
89
+ * Removed redundent methods in {RProgram::Program}:
90
+ * `RProgram::Program.find_by_name`
91
+ * `RProgram::Program.find_by_names`
92
+ * Added `RProgram::Program#create`.
93
+ * Made {RProgram::Program} nameable by default.
94
+ * Prevented arbitrary command-injection in {RProgram::Program#run}.
95
+
96
+ ### 0.0.9 / 2008-01-09
97
+
98
+ * Initial release.
99
+ * Provides cross-platform access to the `PATH` environment variable.
100
+ * Supports mapping long and short options.
101
+ * Supports mapping leading and tailing non-options.
102
+ * Supports custom formating of options.
103
+
data/LICENSE.txt CHANGED
@@ -1,23 +1,22 @@
1
1
 
2
+ Copyright (c) 2007-2010 Hal Brodigan
2
3
 
3
- The MIT License
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ 'Software'), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
4
11
 
5
- Copyright (c) 2007-2008 Hal Brodigan
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
6
14
 
7
- Permission is hereby granted, free of charge, to any person obtaining a copy
8
- of this software and associated documentation files (the "Software"), to deal
9
- in the Software without restriction, including without limitation the rights
10
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- copies of the Software, and to permit persons to whom the Software is
12
- furnished to do so, subject to the following conditions:
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
22
 
14
- The above copyright notice and this permission notice shall be included in
15
- all copies or substantial portions of the Software.
16
-
17
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # RProgram
2
+
3
+ * [github.com/postmodern/rprogram](http://github.com/postmodern/rprogram)
4
+ * [github.com/postmodern/rprogram/issues](http://github.com/postmodern/rprogram/issues)
5
+ * Postmodern (postmodern.mod3 at gmail.com)
6
+
7
+ ## Description
8
+
9
+ RProgram is a library for creating wrappers around command-line programs.
10
+ RProgram provides a Rubyful interface to programs and all their options
11
+ or non-options. RProgram can also search for programs installed on a
12
+ system.
13
+
14
+ ## Features
15
+
16
+ * Uses Kernel.system for safe execution of individual programs and their
17
+ separate command-line arguments.
18
+ * Allows running programs under `sudo`.
19
+ * Provides cross-platform access to the PATH variable.
20
+ * Supports leading/tailing non-options.
21
+ * Supports long-options and short-options.
22
+ * Supports custom formating of options.
23
+
24
+ ## Examples
25
+
26
+ First, create the class to represent the options of the program, using
27
+ {RProgram::Task} as the base class:
28
+
29
+ require 'rprogram/task'
30
+
31
+ class MyProgTask < RProgram::Task
32
+
33
+ # map in the short-options
34
+ short_option :flag => '-o', :name => :output
35
+ short_option :flag => '-oX', :name => :xml_output
36
+
37
+ # map in long options
38
+ long_option :flag => '--no-resolv', :name => :disable_resolv
39
+
40
+ # long_option can infer the :name option, based on the :flag
41
+ long_option :flag => '--mode'
42
+
43
+ # options can also take multiple values
44
+ long_option :flag => '--includes', :multiple => true
45
+
46
+ # options with multiple values can have a custom separator character
47
+ long_option :flag => '--ops',
48
+ :multiple => true,
49
+ :separator => ','
50
+
51
+ # define any non-options (aka additional arguments)
52
+ non_option :tailing => true, :name => :files
53
+
54
+ end
55
+
56
+ Next, create the class to represent the program you wish to interface with,
57
+ using {RProgram::Program} as the base class:
58
+
59
+ require 'my_prog_task'
60
+
61
+ require 'rprogram/program'
62
+
63
+ class MyProg < RProgram::Program
64
+
65
+ # identify the file-name of the program
66
+ name_program 'my_prg'
67
+
68
+ # add a top-level method which finds and runs your program.
69
+ def self.my_run(options={},&block)
70
+ self.find.my_run(options,&block)
71
+ end
72
+
73
+ # add a method which runs the program with MyProgTask.
74
+ def my_run(options={},&block)
75
+ run_task(MyProgTask.new(options,&block))
76
+ end
77
+
78
+ end
79
+
80
+ Finally, run your program with options or a block:
81
+
82
+ MyProgram.my_run(:mode => :fast, :files => ['test1'])
83
+ # => true
84
+
85
+ MyProgram.my_run do |my_prog|
86
+ my_prog.includes = ['one', 'two', 'three']
87
+ my_prog.mode == :safe
88
+
89
+ my_prog.output = 'output.txt'
90
+ my_prog.files = ['test1.txt', 'test2.txt']
91
+ end
92
+ # => true
93
+
94
+ ## Install
95
+
96
+ $ sudo gem install rprogram
97
+
98
+ ## License
99
+
100
+ See {file:LICENSE.txt} for license information.
101
+
data/Rakefile CHANGED
@@ -1,22 +1,43 @@
1
- # -*- ruby -*-
2
-
3
1
  require 'rubygems'
4
- require 'hoe'
5
- require 'hoe/signing'
6
- require './tasks/spec.rb'
7
- require './tasks/yard.rb'
2
+ require 'rake'
3
+ require './lib/rprogram/version.rb'
8
4
 
9
- Hoe.spec('rprogram') do
10
- self.rubyforge_name = 'rprogram'
11
- self.developer('Postmodern', 'postmodern.mod3@gmail.com')
12
- self.remote_rdoc_dir = ''
5
+ begin
6
+ gem 'jeweler', '~> 1.4.0'
7
+ require 'jeweler'
13
8
 
14
- self.extra_dev_deps = [
15
- ['rspec', '>=1.2.8'],
16
- ['yard', '>=0.5.2']
17
- ]
9
+ Jeweler::Tasks.new do |gem|
10
+ gem.name = 'rprogram'
11
+ gem.version = RProgram::VERSION
12
+ gem.summary = %Q{A library for creating wrappers around command-line programs.}
13
+ gem.description = %Q{RProgram is a library for creating wrappers around command-line programs. RProgram provides a Rubyful interface to programs and all their options or non-options. RProgram can also search for programs installed on a system.}
14
+ gem.email = 'postmodern.mod3@gmail.com'
15
+ gem.homepage = 'http://github.com/postmodern/rprogram'
16
+ gem.authors = ['Postmodern']
17
+ gem.add_development_dependency 'rspec', '>= 1.3.0'
18
+ gem.add_development_dependency 'yard', '>= 0.5.3'
19
+ gem.has_rdoc = 'yard'
20
+ end
21
+ Jeweler::GemcutterTasks.new
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
+ end
18
25
 
19
- self.spec_extras = {:has_rdoc => 'yard'}
26
+ require 'spec/rake/spectask'
27
+ Spec::Rake::SpecTask.new(:spec) do |spec|
28
+ spec.libs += ['lib', 'spec']
29
+ spec.spec_files = FileList['spec/**/*_spec.rb']
30
+ spec.spec_opts = ['--options', '.specopts']
20
31
  end
21
32
 
22
- # vim: syntax=Ruby
33
+ task :spec => :check_dependencies
34
+ task :default => :spec
35
+
36
+ begin
37
+ require 'yard'
38
+ YARD::Rake::YardocTask.new
39
+ rescue LoadError
40
+ task :yard do
41
+ abort "YARD is not available. In order to run yard, you must: gem install yard"
42
+ end
43
+ end
@@ -16,10 +16,10 @@ module RProgram
16
16
  end
17
17
 
18
18
  #
19
- # Determines the contents of the +PATH+ environment variable.
19
+ # Determines the contents of the `PATH` environment variable.
20
20
  #
21
21
  # @return [Array]
22
- # The contents of the +PATH+ environment variable.
22
+ # The contents of the `PATH` environment variable.
23
23
  #
24
24
  # @example
25
25
  # Compat.paths #=> ["/bin", "/usr/bin"]
@@ -109,7 +109,7 @@ module RProgram
109
109
  # Specifies whether the program exited successfully.
110
110
  #
111
111
  # @raise [ProgramNotFound]
112
- # Indicates that the +sudo+ program could not be located.
112
+ # Indicates that the `sudo` program could not be located.
113
113
  #
114
114
  # @since 0.1.8
115
115
  #
@@ -0,0 +1,84 @@
1
+ module RProgram
2
+ module Nameable
3
+ module ClassMethods
4
+ #
5
+ # @return [String]
6
+ # The name of the program.
7
+ #
8
+ def program_name
9
+ @program_name ||= nil
10
+ end
11
+
12
+ #
13
+ # @return [Array]
14
+ # The program's aliases.
15
+ #
16
+ def program_aliases
17
+ @program_aliases ||= []
18
+ end
19
+
20
+ #
21
+ # Combines program_name with program_aliases.
22
+ #
23
+ # @return [Array]
24
+ # Names the program is known by.
25
+ #
26
+ def program_names
27
+ ([program_name] + program_aliases).compact
28
+ end
29
+
30
+ #
31
+ # Sets the program name for the class.
32
+ #
33
+ # @param [String, Symbol] name
34
+ # The new program name.
35
+ #
36
+ # @example
37
+ # name_program 'ls'
38
+ #
39
+ def name_program(name)
40
+ @program_name = name.to_s
41
+ end
42
+
43
+ #
44
+ # Sets the program aliases for the class.
45
+ #
46
+ # @param [Array] aliases
47
+ # The new program aliases.
48
+ #
49
+ # @example
50
+ # alias_program 'vim', 'vi'
51
+ #
52
+ def alias_program(*aliases)
53
+ @program_aliases = aliases.map { |name| name.to_s }
54
+ end
55
+
56
+ #
57
+ # The default path of the program.
58
+ #
59
+ # @return [String, nil]
60
+ # The path to the program.
61
+ #
62
+ # @since 0.2.0
63
+ #
64
+ def path
65
+ @program_path
66
+ end
67
+
68
+ #
69
+ # Sets the default path to the program.
70
+ #
71
+ # @param [String] new_path
72
+ # The new path to the program.
73
+ #
74
+ # @return [String, nil]
75
+ # The path to the program.
76
+ #
77
+ # @since 0.2.0
78
+ #
79
+ def path=(new_path)
80
+ @program_path = (File.expand_path(new_path) if new_path)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,34 @@
1
+ require 'rprogram/nameable/class_methods'
2
+ require 'rprogram/compat'
3
+
4
+ module RProgram
5
+ module Nameable
6
+ def self.included(base)
7
+ base.send :extend, ClassMethods
8
+ end
9
+
10
+ #
11
+ # @return [String]
12
+ # The program name of the class.
13
+ #
14
+ def program_name
15
+ self.class.program_name
16
+ end
17
+
18
+ #
19
+ # @return [Array]
20
+ # The program aliases of the class.
21
+ #
22
+ def program_aliases
23
+ self.class.program_aliases
24
+ end
25
+
26
+ #
27
+ # @return [Array]
28
+ # The program names of the class.
29
+ #
30
+ def program_names
31
+ self.class.program_names
32
+ end
33
+ end
34
+ end
@@ -1,86 +1,2 @@
1
- require 'rprogram/extensions/meta'
2
- require 'rprogram/compat'
3
-
4
- module RProgram
5
- module Nameable
6
- def self.included(base)
7
- base.metaclass_eval do
8
- #
9
- # @return [String]
10
- # The name of the program.
11
- #
12
- def program_name
13
- @program_name ||= nil
14
- end
15
-
16
- #
17
- # @return [Array]
18
- # The program's aliases.
19
- #
20
- def program_aliases
21
- @program_aliases ||= []
22
- end
23
-
24
- #
25
- # Combines program_name with program_aliases.
26
- #
27
- # @return [Array]
28
- # Names the program is known by.
29
- #
30
- def program_names
31
- ([program_name] + program_aliases).compact
32
- end
33
-
34
- #
35
- # Sets the program name for the class.
36
- #
37
- # @param [String, Symbol] name
38
- # The new program name.
39
- #
40
- # @example
41
- # name_program 'ls'
42
- #
43
- def name_program(name)
44
- @program_name = name.to_s
45
- end
46
-
47
- #
48
- # Sets the program aliases for the class.
49
- #
50
- # @param [Array] aliases
51
- # The new program aliases.
52
- #
53
- # @example
54
- # alias_program 'vim', 'vi'
55
- #
56
- def alias_program(*aliases)
57
- @program_aliases = aliases.map { |name| name.to_s }
58
- end
59
- end
60
- end
61
-
62
- #
63
- # @return [String]
64
- # The program name of the class.
65
- #
66
- def program_name
67
- self.class.program_name
68
- end
69
-
70
- #
71
- # @return [Array]
72
- # The program aliases of the class.
73
- #
74
- def program_aliases
75
- self.class.program_aliases
76
- end
77
-
78
- #
79
- # @return [Array]
80
- # The program names of the class.
81
- #
82
- def program_names
83
- self.class.program_names
84
- end
85
- end
86
- end
1
+ require 'rprogram/nameable/class_methods'
2
+ require 'rprogram/nameable/nameable'
@@ -29,14 +29,14 @@ module RProgram
29
29
  # The command-line flag to use.
30
30
  #
31
31
  # @option options [true, false] :equals (false)
32
- # Implies the option maybe formated as <tt>"--flag=value"</tt>.
32
+ # Implies the option maybe formated as `--flag=value`.
33
33
  #
34
34
  # @option options [true, false] :multiple (false)
35
35
  # Specifies the option maybe given an Array of values.
36
36
  #
37
37
  # @option options [String] :separator
38
38
  # The separator to use for formating multiple arguments into one
39
- # +String+. Cannot be used with the +:multiple+ option.
39
+ # `String`. Cannot be used with the `:multiple` option.
40
40
  #
41
41
  # @option options [true, false] :sub_options (false)
42
42
  # Specifies that the option contains sub-options.
@@ -0,0 +1,112 @@
1
+ module RProgram
2
+ module Options
3
+ module ClassMethods
4
+ #
5
+ # @return [Hash]
6
+ # All defined non-options of the class.
7
+ #
8
+ def non_options
9
+ @non_options ||= {}
10
+ end
11
+
12
+ #
13
+ # Searches for the non-option with the matching name in the class
14
+ # and it's ancestors.
15
+ #
16
+ # @param [Symbol, String] name
17
+ # The name to search for.
18
+ #
19
+ # @return [true, false]
20
+ # Specifies whether the non-option with the matching name was
21
+ # defined.
22
+ #
23
+ def has_non_option?(name)
24
+ name = name.to_sym
25
+
26
+ ancestors.each do |base|
27
+ if base.include?(RProgram::Options)
28
+ return true if base.non_options.include?(name)
29
+ end
30
+ end
31
+
32
+ return false
33
+ end
34
+
35
+ #
36
+ # Searches for the non-option with the matching name in the class
37
+ # and it's ancestors.
38
+ #
39
+ # @param [Symbol, String] name
40
+ # The name to search for.
41
+ #
42
+ # @return [NonOption]
43
+ # The non-option with the matching name.
44
+ #
45
+ def get_non_option(name)
46
+ name = name.to_sym
47
+
48
+ ancestors.each do |base|
49
+ if base.include?(RProgram::Options)
50
+ if base.non_options.has_key?(name)
51
+ return base.non_options[name]
52
+ end
53
+ end
54
+ end
55
+
56
+ return nil
57
+ end
58
+
59
+ #
60
+ # @return [Hash]
61
+ # All defined options for the class.
62
+ #
63
+ def options
64
+ @options ||= {}
65
+ end
66
+
67
+ #
68
+ # Searches for the option with the matching name in the class and
69
+ # it's ancestors.
70
+ #
71
+ # @param [Symbol, String] name
72
+ # The name to search for.
73
+ #
74
+ # @return [true, false]
75
+ # Specifies whether the option with the matching name was defined.
76
+ #
77
+ def has_option?(name)
78
+ name = name.to_sym
79
+
80
+ ancestors.each do |base|
81
+ if base.include?(RProgram::Options)
82
+ return true if base.options.has_key?(name)
83
+ end
84
+ end
85
+
86
+ return false
87
+ end
88
+
89
+ #
90
+ # Searches for the option with the matching name in the class and
91
+ # it's ancestors.
92
+ #
93
+ # @param [Symbol, String] name
94
+ # The name to search for.
95
+ #
96
+ # @return [Option]
97
+ # The option with the matching name.
98
+ #
99
+ def get_option(name)
100
+ name = name.to_sym
101
+
102
+ ancestors.each do |base|
103
+ if base.include?(RProgram::Options)
104
+ return base.options[name] if base.options.has_key?(name)
105
+ end
106
+ end
107
+
108
+ return nil
109
+ end
110
+ end
111
+ end
112
+ end