rubikon 0.4.1 → 0.5.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.
@@ -56,6 +56,8 @@ module Rubikon
56
56
  end
57
57
  end
58
58
 
59
+ private
60
+
59
61
  # Add a new parameter for this command
60
62
  #
61
63
  # @param [Parameter, Hash] parameter The parameter to add to this
@@ -119,6 +121,11 @@ module Rubikon
119
121
  # @see Flag
120
122
  # @see Option
121
123
  def parse_arguments(args)
124
+ current_param = Application::InstanceMethods.
125
+ instance_method(:current_param).bind(@app)
126
+ set_current_param = Application::InstanceMethods.
127
+ instance_method(:current_param=).bind(@app)
128
+
122
129
  @args = []
123
130
  args.each do |arg|
124
131
  if arg.start_with?('-')
@@ -128,20 +135,20 @@ module Rubikon
128
135
  end
129
136
 
130
137
  unless parameter.nil?
131
- @app.current_param.active! unless @app.current_param.nil?
132
- @app.current_param = parameter
138
+ current_param.call.send(:active!) unless current_param.call.nil?
139
+ set_current_param.call(parameter)
133
140
  next
134
141
  end
135
142
 
136
- if @app.current_param.nil? || !@app.current_param.more_args?
143
+ if current_param.call.nil? || !current_param.call.send(:more_args?)
137
144
  self << arg
138
145
  else
139
- @app.current_param << arg
146
+ current_param.call.send(:<<, arg)
140
147
  end
141
148
  end
142
149
 
143
- @app.current_param.active! unless @app.current_param.nil?
144
- @app.current_param = nil
150
+ current_param.call.send(:active!) unless current_param.call.nil?
151
+ set_current_param.call(nil)
145
152
  end
146
153
 
147
154
  # Resets this command to its initial state
@@ -150,7 +157,9 @@ module Rubikon
150
157
  # @since 0.4.0
151
158
  def reset
152
159
  super
153
- @params.values.uniq.each { |param| param.reset if param.is_a? Parameter }
160
+ @params.values.uniq.each do |param|
161
+ param.send(:reset) if param.is_a? Parameter
162
+ end
154
163
  end
155
164
 
156
165
  # Checks whether a parameter with the given name exists for this command
@@ -171,7 +180,8 @@ module Rubikon
171
180
  def run(*args)
172
181
  parse_arguments(args)
173
182
  check_args
174
- @app.sandbox.instance_eval(&@block)
183
+ Application::InstanceMethods.instance_method(:sandbox).bind(@app).call.
184
+ instance_eval(&@block)
175
185
  end
176
186
 
177
187
  end
@@ -0,0 +1,39 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ module Rubikon
7
+
8
+ module Config
9
+
10
+ # A configuration provider loading various configuration file formats using
11
+ # another provider depending on the extension of the configuration file.
12
+ #
13
+ # @author Sebastian Staudt
14
+ # @since 0.5.0
15
+ class AutoProvider
16
+
17
+ # Load a configuration file with the corresponding provider detected
18
+ # from the file extension
19
+ #
20
+ # @param [String] file The path of the config file to load
21
+ # @return [Hash] The configuration values loaded from the file
22
+ # @see YamlProvider
23
+ def self.load_config(file)
24
+ ext = File.extname(file)
25
+ case ext
26
+ when '.ini'
27
+ IniProvider.load_config file
28
+ when '.yaml', '.yml'
29
+ YamlProvider.load_config file
30
+ else
31
+ raise UnsupportedConfigFormatError.new(ext)
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,65 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ require 'rubikon/config/auto_provider'
7
+ require 'rubikon/config/ini_provider'
8
+ require 'rubikon/config/yaml_provider'
9
+
10
+ module Rubikon
11
+
12
+ # This module contains several classes used to load configuration data from
13
+ # various sources
14
+ #
15
+ # @author Sebastian Staudt
16
+ # @since 0.5.0
17
+ module Config
18
+
19
+ # The configuration factory is used to load one or more configuration
20
+ # files from different search paths and using different file formats, e.g.
21
+ # YAML.
22
+ #
23
+ # @author Sebastian Staudt
24
+ class Factory
25
+
26
+ # Providers available for use
27
+ PROVIDERS = [ :auto, :ini, :yaml ]
28
+
29
+ # @return [Hash] The configuration data loaded from the configuration
30
+ # files found inside the search paths
31
+ attr_reader :config
32
+
33
+ # @return [Array<String>] The paths of the configuration files found and
34
+ # loaded
35
+ attr_reader :files
36
+
37
+ # Creates a new factory instance with a given file name to be searched in
38
+ # the given paths and using the specified provider to load the
39
+ # configuration data from the files.
40
+ #
41
+ # @param [String] name The name of the configuration file
42
+ # @param [Array<String>] search_paths An array of paths to be searched
43
+ # for configuration files
44
+ # @param [PROVIDERS] provider The provider to use for loading
45
+ # configuration data from the files found
46
+ def initialize(name, search_paths, provider = :yaml)
47
+ provider = :auto unless PROVIDERS.include?(provider)
48
+ provider = Config.const_get("#{provider.to_s.capitalize}Provider")
49
+
50
+ @files = []
51
+ @config = {}
52
+ search_paths.each do |path|
53
+ config_file = File.join path, name
54
+ if File.exists? config_file
55
+ @config.merge! provider.load_config(config_file)
56
+ @files << config_file
57
+ end
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,60 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ module Rubikon
7
+
8
+ module Config
9
+
10
+ # A configuration provider loading configuration data from INI files
11
+ #
12
+ # @author Sebastian Staudt
13
+ # @since 0.5.0
14
+ class IniProvider
15
+
16
+ # Loads a configuration Hash from a INI file
17
+ #
18
+ # This method is taken from code written by gdsx in #ruby-lang (see
19
+ # http://snippets.dzone.com/posts/show/563).
20
+ #
21
+ # @param [String] file The path of the file to load
22
+ # @return [Hash] The configuration data loaded from the file
23
+ def self.load_config(file)
24
+ content = File.new(file).readlines.map do |line|
25
+ line.gsub(/(?:#|;).*/, '').strip
26
+ end.join("\n")
27
+
28
+ config = {}
29
+ content = content.split(/\[([^\]]+)\]/)[1..-1]
30
+ content.inject([]) do |temp, field|
31
+ temp << field
32
+ if temp.length == 2
33
+ value = temp[1].sub(/^\s+/,'').sub(/\s+$/,'')
34
+ if config[temp[0]].nil?
35
+ config[temp[0]] = value
36
+ else
37
+ config[temp[0]] << "\n#{value}"
38
+ end
39
+ temp.clear
40
+ end
41
+ temp
42
+ end
43
+
44
+ config.dup.each do |key, value|
45
+ value_list = value.split /[\r\n]+/
46
+ config[key] = value_list.inject({}) do |hash, val|
47
+ k, v = val.split /\s*=\s*/
48
+ hash[k] = v
49
+ hash
50
+ end
51
+ end
52
+
53
+ config
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,30 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ require 'yaml'
7
+
8
+ module Rubikon
9
+
10
+ module Config
11
+
12
+ # A configuration provider loading configuration data from YAML files
13
+ #
14
+ # @author Sebastian Staudt
15
+ # @since 0.5.0
16
+ class YamlProvider
17
+
18
+ # Loads a configuration Hash from a YAML formatted file
19
+ #
20
+ # @param [String] file The path of the file to load
21
+ # @return [Hash] The configuration data loaded from the file
22
+ def self.load_config(file)
23
+ YAML.load_file file
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -78,4 +78,16 @@ module Rubikon
78
78
 
79
79
  end
80
80
 
81
+ # Raised if a command has been supplied that does not exist
82
+ #
83
+ # @author Sebastian Staudt
84
+ # @since 0.5.0
85
+ class UnsupportedConfigFormatError < ArgumentError
86
+
87
+ def initialize(ext)
88
+ super "Unknown config file extension: #{ext}"
89
+ end
90
+
91
+ end
92
+
81
93
  end
data/lib/rubikon/flag.rb CHANGED
@@ -18,6 +18,8 @@ module Rubikon
18
18
 
19
19
  include Parameter
20
20
 
21
+ private
22
+
21
23
  # Adds an argument to this flag
22
24
  #
23
25
  # @param arg (see Parameter#<<)
@@ -78,6 +78,8 @@ module Rubikon
78
78
  @args[arg]
79
79
  end
80
80
 
81
+ protected
82
+
81
83
  # Adds an argument to this parameter. Arguments can be accessed inside the
82
84
  # application code using the args method.
83
85
  #
@@ -36,14 +36,6 @@ module Rubikon
36
36
  @name = name.to_sym
37
37
  end
38
38
 
39
- # Marks this parameter as active when it has been supplied by the user on
40
- # the command-line. This also calls the code block of the parameter if it
41
- # exists
42
- def active!
43
- @active = true
44
- @app.sandbox.instance_eval(&@block) unless @block.nil?
45
- end
46
-
47
39
  # Returns whether this parameter has is active, i.e. it has been supplied
48
40
  # by the user on the command-line
49
41
  #
@@ -53,6 +45,17 @@ module Rubikon
53
45
  end
54
46
  alias_method :given?, :active?
55
47
 
48
+ protected
49
+
50
+ # Marks this parameter as active when it has been supplied by the user on
51
+ # the command-line. This also calls the code block of the parameter if it
52
+ # exists
53
+ def active!
54
+ @active = true
55
+ Application::InstanceMethods.instance_method(:sandbox).bind(@app).call.
56
+ instance_eval(&@block) unless @block.nil?
57
+ end
58
+
56
59
  # Resets this parameter to its initial state
57
60
  #
58
61
  # @since 0.4.0
@@ -35,13 +35,19 @@ module Rubikon
35
35
  end
36
36
  @maximum.round
37
37
 
38
- @progress_char = options[:char] || '#'
39
- @ostream = options[:ostream] || $stdout
40
- @progress = 0
41
- @size = options[:size] || 20
42
- @factor = @size.round.to_f / @maximum
43
- @value = 0
38
+ @progress_char = options[:char] || '#'
39
+ @ostream = options[:ostream] || $stdout
40
+ @progress = 0
41
+ @size = options[:size] || 20
42
+ @factor = @size.round.to_f / @maximum
43
+ @value = 0
44
+ @brackets = options[:brackets] || false
45
+ @bracket_filler = options[:bracket_filler] || ' '
44
46
 
47
+ if @brackets
48
+ @ostream << '[' + @bracket_filler * @size + ']'+ "\b" * (@size + 1)
49
+ @ostream.flush
50
+ end
45
51
  self + (options[:start] || 0)
46
52
  end
47
53
 
@@ -21,16 +21,16 @@ module Rubikon
21
21
  # @param [Thread] thread The thread that should be watched
22
22
  # @see Application::InstanceMethods#throbber
23
23
  def initialize(ostream, thread)
24
- proc = Proc.new do |ostream, thread|
24
+ proc = Proc.new do |os, thr|
25
25
  step = 0
26
- ostream.putc 32
27
- while thread.alive?
28
- ostream << "\b#{SPINNER[step].chr}"
29
- ostream.flush
26
+ os.putc 32
27
+ while thr.alive?
28
+ os << "\b#{SPINNER[step].chr}"
29
+ os.flush
30
30
  step = (step + 1) % 4
31
31
  sleep 0.25
32
32
  end
33
- ostream.putc 8
33
+ os.putc 8
34
34
  end
35
35
 
36
36
  super { proc.call(ostream, thread) }
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This code is free software; you can redistribute it and/or modify it under
4
+ # the terms of the new BSD License.
5
+ #
6
+ # Copyright (c) 2010, Sebastian Staudt
7
+
8
+ if ENV['RUBIKON_DEV']
9
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', '..', 'lib', 'rubikon')
10
+ else
11
+ require 'rubygems'
12
+ require 'rubikon'
13
+ end
14
+
15
+ # A Rubikon application demonstrating the configuration feature
16
+ class ConfigSample < Rubikon::Application::Base
17
+
18
+ dir = File.dirname __FILE__
19
+ global_dir = File.join dir, 'global'
20
+ local_dir = File.join dir, 'local'
21
+
22
+ set :config_file, 'config.yml'
23
+ set :config_paths, [ global_dir, local_dir ]
24
+
25
+ global_flag :'exclude-local' do
26
+ set :config_paths, [ global_dir ]
27
+
28
+ puts "Seems like you changed the truth...\n\n"
29
+ end
30
+
31
+ default do
32
+ puts "A pretty #{config[:string]} example of Rubikon's config."
33
+ puts "#{config[:number]} is greater than 1."
34
+ puts "A lie is never #{config[:boolean]}."
35
+ puts 'Global configs are loaded...' if config[:global]
36
+ puts 'and overriden by local configs' if config[:local]
37
+ end
38
+
39
+ end
@@ -15,11 +15,16 @@ end
15
15
  # A relatively simple Hello World application using Rubikon
16
16
  class HelloWorld < Rubikon::Application::Base
17
17
 
18
+ set :config_file, 'helloworld.ini'
19
+ set :config_format, :ini
20
+
18
21
  # Greet the whole world per default
19
22
  flag :more
20
23
  option :name, [:who]
21
24
  option :names, -1
22
25
  default 'Simple hello world' do
26
+ p config
27
+
23
28
  debug 'Starting to greet the world...'
24
29
  if given? :name
25
30
  greet parameters[:name].who
@@ -38,14 +43,15 @@ class HelloWorld < Rubikon::Application::Base
38
43
  # Ask the user for his name and greet him
39
44
  command :interactive, 'Greet interactively' do
40
45
  name = input 'Please enter your name'
41
- greet name
46
+ call :'__default', '--name', name
42
47
  end
43
48
 
44
49
  # Show a progress bar while iterating through a loop
50
+ flag :brackets
45
51
  command :progress, 'Display a progress bar' do
46
52
  put 'Watch my progress while I greet the world: '
47
53
  x = 1000000
48
- progress_bar(:char => '+', :maximum => x, :size => 30) do |progress|
54
+ progress_bar(:char => '+', :maximum => x, :size => 30, :brackets => brackets.given?, :bracket_filler => '-') do |progress|
49
55
  x.times do
50
56
  progress.+
51
57
  end