rprogram 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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