brice 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,56 @@
1
+ = brice - Extra cool IRb goodness for the masses
2
+
3
+ == VERSION
4
+
5
+ This documentation refers to brice version 0.0.1
6
+
7
+
8
+ == DESCRIPTION
9
+
10
+ Enhances your IRb experience by adding new functionality and by providing
11
+ a framework that you can utilize to add your own extensions. It comes with
12
+ a set of pre-selected features, but is highly configurable in that regard.
13
+
14
+ Add this to your <tt>.irbrc</tt> and receive the default goodness:
15
+
16
+ require 'rubygems'
17
+ require 'brice/init' # equivalent to: require 'brice'; Brice.init
18
+
19
+ Or get some more control over the configuration:
20
+
21
+ require 'rubygems'
22
+ require 'brice'
23
+
24
+ Brice.init { |config|
25
+ ...
26
+ }
27
+
28
+ See Brice::Config for what you can configure, and how.
29
+
30
+ It will even load your own extensions that you place in your <tt>~/.brice</tt>
31
+ directory. See Brice::DSL for helpers provided.
32
+
33
+ Please note that further changes to the configuration for brice can't be
34
+ guaranteed to have any effect after <tt>Brice.init</tt> has been called.
35
+
36
+
37
+ == AUTHORS
38
+
39
+ * Jens Wille <mailto:jens.wille@uni-koeln.de>
40
+
41
+
42
+ == LICENSE AND COPYRIGHT
43
+
44
+ Copyright (C) 2008 Jens Wille
45
+
46
+ brice is free software: you can redistribute it and/or modify it under the
47
+ terms of the GNU General Public License as published by the Free Software
48
+ Foundation, either version 3 of the License, or (at your option) any later
49
+ version.
50
+
51
+ brice is distributed in the hope that it will be useful, but WITHOUT ANY
52
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
53
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
54
+
55
+ You should have received a copy of the GNU General Public License along with
56
+ brice. If not, see <http://www.gnu.org/licenses/>.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require %q{lib/brice/version}
2
+
3
+ begin
4
+ require 'hen'
5
+
6
+ Hen.lay! {{
7
+ :rubyforge => {
8
+ :project => %q{prometheus},
9
+ :package => %q{brice}
10
+ },
11
+
12
+ :gem => {
13
+ :version => Brice::VERSION,
14
+ :summary => %q{Extra cool IRb goodness for the masses},
15
+ :files => FileList['lib/**/*.rb'].to_a,
16
+ :extra_files => FileList['[A-Z]*'].to_a,
17
+ :dependencies => %w[ruby-nuggets]
18
+ }
19
+ }}
20
+ rescue LoadError
21
+ abort "Please install the 'hen' gem first."
22
+ end
23
+
24
+ ### Place your custom Rake tasks here.
@@ -0,0 +1,159 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of brice, the extra cool IRb goodness donator #
5
+ # #
6
+ # Copyright (C) 2008 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@uni-koeln.de> #
10
+ # #
11
+ # brice is free software: you can redistribute it and/or modify it under the #
12
+ # terms of the GNU General Public License as published by the Free Software #
13
+ # Foundation, either version 3 of the License, or (at your option) any later #
14
+ # version. #
15
+ # #
16
+ # brice is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more #
19
+ # details. #
20
+ # #
21
+ # You should have received a copy of the GNU General Public License along #
22
+ # with brice. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ require 'ostruct'
28
+
29
+ class Brice
30
+
31
+ # Exclude unwanted packages:
32
+ #
33
+ # config.exclude 'foo', 'bar'
34
+ # Brice.config -= %w[quix quux]
35
+ #
36
+ # Include non-default packages:
37
+ #
38
+ # config.include 'foo', 'bar'
39
+ # Brice.config += %w[quix quux]
40
+ #
41
+ # Configure individual packages (depends on package):
42
+ #
43
+ # # set property
44
+ # config.foo.bar = 'baz'
45
+ #
46
+ # # set multiple properties
47
+ # config.foo = %w[bar baz]
48
+ # # equivalent to:
49
+ # #config.foo.bar = true
50
+ # #config.foo.baz = true
51
+ #
52
+ # # reset package configuration
53
+ # config.foo!
54
+ #
55
+ # # see whether package is enabled/included
56
+ # config.foo?
57
+
58
+ class Config
59
+
60
+ attr_reader :packages
61
+
62
+ def initialize(packages = [])
63
+ @packages = Hash.new { |h, k| h[k] = PackageConfig.new }
64
+ packages.each { |package| self[package] }
65
+ end
66
+
67
+ # call-seq:
68
+ # config[package]
69
+ #
70
+ # Accessor for package +package+.
71
+ def [](package)
72
+ @packages[package.to_s]
73
+ end
74
+
75
+ # call-seq:
76
+ # config.include(*packages)
77
+ # config += packages
78
+ #
79
+ # Enable/include packages +packages+.
80
+ def include(*packages)
81
+ packages.each { |package| self[package] }
82
+ self
83
+ end
84
+
85
+ alias_method :+, :include
86
+
87
+ # call-seq:
88
+ # config.exclude(*packages)
89
+ # config -= packages
90
+ #
91
+ # Disable/exclude packages +packages+.
92
+ def exclude(*packages)
93
+ packages.each { |package| @packages.delete(package.to_s) }
94
+ self
95
+ end
96
+
97
+ alias_method :-, :exclude
98
+
99
+ # call-seq:
100
+ # config.clear
101
+ #
102
+ # Clear all packages.
103
+ def clear
104
+ @packages.clear
105
+ end
106
+
107
+ # call-seq:
108
+ # config.include?(package) => true or false
109
+ # config.have?(package) => true or false
110
+ #
111
+ # See whether package +package+ is enabled/included.
112
+ def include?(package)
113
+ @packages.include?(package.to_s)
114
+ end
115
+
116
+ alias_method :have?, :include?
117
+
118
+ # call-seq:
119
+ # config.package # package configuration
120
+ # config.package = 'foo' # equivalent to: config.package.foo = true
121
+ # config.package = %w[foo bar] # see above, multiple
122
+ # config.package! # reset package configuration
123
+ # config.package? # see whether package is enabled/included
124
+ #
125
+ # Convenience accessors to individual package configurations.
126
+ def method_missing(method, *args)
127
+ package, punctuation = method.to_s.sub(/([=!?])?\z/, ''), $1
128
+
129
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 0)" \
130
+ unless punctuation == '=' || args.empty?
131
+
132
+ case punctuation
133
+ when '='
134
+ @packages[package] = PackageConfig.new
135
+ [*args.first].each { |arg| @packages[package].send("#{arg}=", true) }
136
+ when '!'
137
+ @packages[package] = PackageConfig.new
138
+ when '?'
139
+ self.include?(package)
140
+ else
141
+ self[package]
142
+ end
143
+ end
144
+
145
+ class PackageConfig < OpenStruct
146
+
147
+ # call-seq:
148
+ # pkgconfig.entries => anArray
149
+ #
150
+ # Returns all entries/keys.
151
+ def entries
152
+ instance_variable_get(:@table).keys.map { |key| key.to_s }.sort
153
+ end
154
+
155
+ end
156
+
157
+ end
158
+
159
+ end
data/lib/brice/dsl.rb ADDED
@@ -0,0 +1,161 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # A component of brice, the extra cool IRb goodness donator #
5
+ # #
6
+ # Copyright (C) 2008 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@uni-koeln.de> #
10
+ # #
11
+ # brice is free software: you can redistribute it and/or modify it under the #
12
+ # terms of the GNU General Public License as published by the Free Software #
13
+ # Foundation, either version 3 of the License, or (at your option) any later #
14
+ # version. #
15
+ # #
16
+ # brice is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more #
19
+ # details. #
20
+ # #
21
+ # You should have received a copy of the GNU General Public License along #
22
+ # with brice. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ class Brice
28
+
29
+ # Certain global helper methods for use inside IRb extensions. Also
30
+ # available inside the IRb session.
31
+
32
+ module DSL
33
+
34
+ # call-seq:
35
+ # irb_rc { ... }
36
+ #
37
+ # Add IRB_RC proc (to be executed whenever a (sub-)session is started).
38
+ def irb_rc
39
+ Brice.irb_rc << Proc.new
40
+ end
41
+
42
+ # call-seq:
43
+ # irb_def(symbol) { ... }
44
+ # irb_def(symbol, method)
45
+ #
46
+ # Define a method for use inside the IRb session.
47
+ def irb_def(symbol, method = nil)
48
+ irb_rc {
49
+ Object.instance_eval {
50
+ if method
51
+ define_method(symbol, method)
52
+ else
53
+ define_method(symbol, &Proc.new)
54
+ end
55
+ }
56
+ }
57
+ end
58
+
59
+ alias_method :define_irb_method, :irb_def
60
+
61
+ # call-seq:
62
+ # silence { ... }
63
+ #
64
+ # Silence warnings for block execution.
65
+ def silence
66
+ verbose, $VERBOSE = $VERBOSE, nil
67
+ yield
68
+ ensure
69
+ $VERBOSE = verbose
70
+ end
71
+
72
+ # call-seq:
73
+ # brice_rescue(what, args = [], error = Exception)
74
+ #
75
+ # Call +what+ with +args+ and rescue potential +error+, optionally
76
+ # executing block in case of success. Gives a nicer error location
77
+ # instead of the full backtrace.
78
+ #
79
+ # Returns either the result of the executed method or of the block.
80
+ def brice_rescue(what, args = [], error = Exception)
81
+ res = send(what, *args)
82
+
83
+ block_given? ? yield : res
84
+ rescue Exception => err
85
+ raise unless err.is_a?(error)
86
+
87
+ unless Brice.quiet
88
+ # FIXME: ideally, we'd want the __FILE__ and __LINE__ of the
89
+ # rc file where the error occurred.
90
+ location = caller.find { |c| c !~ %r{(?:\A|/)lib/brice[/.]} }
91
+ warn "#{err.class}: #{err} [#{location}]"
92
+ end
93
+ end
94
+
95
+ # call-seq:
96
+ # brice_require(string)
97
+ #
98
+ # Kernel#require the library named +string+ and optionally execute
99
+ # block in case of success.
100
+ #
101
+ # Returns either the result of the executed method or of the block.
102
+ def brice_require(string)
103
+ args = [:require, [string], LoadError]
104
+
105
+ if block_given?
106
+ brice_rescue(*args) { |*a| yield(*a) }
107
+ else
108
+ brice_rescue(*args)
109
+ end
110
+ end
111
+
112
+ # call-seq:
113
+ # brice_load(filename, wrap = false)
114
+ #
115
+ # Kernel#load the file named +filename+ and optionally execute
116
+ # block in case of success.
117
+ #
118
+ # Returns either the result of the executed method or of the block.
119
+ def brice_load(filename, wrap = false)
120
+ args = [:load, [filename, wrap]]
121
+
122
+ if block_given?
123
+ brice_rescue(*args) { |*a| yield(*a) }
124
+ else
125
+ brice_rescue(*args)
126
+ end
127
+ end
128
+
129
+ # call-seq:
130
+ # brice(package) # package == lib
131
+ # brice(package => lib)
132
+ # brice(package => [lib, ...])
133
+ #
134
+ # Declare package +package+. Optionally load given libraries (see below)
135
+ # and configure the package if it has been enabled/included.
136
+ #
137
+ # +package+ can be a String which already names the library to be loaded
138
+ # or a Hash of the form <tt>package => lib</tt> or <tt>package => [lib, ...]</tt>.
139
+ def brice(package)
140
+ package, libs = case package
141
+ when Hash
142
+ raise ArgumentError, "Too many package names: #{package.keys.join(' ')}" \
143
+ if package.size > 1
144
+ raise ArgumentError, 'No package name given' \
145
+ if package.size < 1
146
+
147
+ [package.keys.first, [*package.values.first]]
148
+ else
149
+ [package, [package]]
150
+ end
151
+
152
+ if Brice.include?(package)
153
+ if libs.all? { |lib| !lib || brice_require(lib) { true } }
154
+ yield Brice.config[package] if block_given?
155
+ end
156
+ end
157
+ end
158
+
159
+ end
160
+
161
+ end
data/lib/brice/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # just a short-cut
2
+ require File.dirname(__FILE__)
3
+ Brice.init
@@ -0,0 +1,27 @@
1
+ class Brice
2
+
3
+ module Version
4
+
5
+ MAJOR = 0
6
+ MINOR = 0
7
+ TINY = 1
8
+
9
+ class << self
10
+
11
+ # Returns array representation.
12
+ def to_a
13
+ [MAJOR, MINOR, TINY]
14
+ end
15
+
16
+ # Short-cut for version string.
17
+ def to_s
18
+ to_a.join('.')
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ VERSION = Version.to_s
26
+
27
+ end
data/lib/brice.rb ADDED
@@ -0,0 +1,170 @@
1
+ #--
2
+ ###############################################################################
3
+ # #
4
+ # brice -- Extra cool IRb goodness for the masses #
5
+ # #
6
+ # Copyright (C) 2008 Jens Wille #
7
+ # #
8
+ # Authors: #
9
+ # Jens Wille <jens.wille@uni-koeln.de> #
10
+ # #
11
+ # brice is free software: you can redistribute it and/or modify it under the #
12
+ # terms of the GNU General Public License as published by the Free Software #
13
+ # Foundation, either version 3 of the License, or (at your option) any later #
14
+ # version. #
15
+ # #
16
+ # brice is distributed in the hope that it will be useful, but WITHOUT ANY #
17
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
18
+ # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more #
19
+ # details. #
20
+ # #
21
+ # You should have received a copy of the GNU General Public License along #
22
+ # with brice. If not, see <http://www.gnu.org/licenses/>. #
23
+ # #
24
+ ###############################################################################
25
+ #++
26
+
27
+ require 'irb'
28
+ require 'rubygems'
29
+ require 'nuggets/env/user_home'
30
+
31
+ %w[config dsl version].each { |lib|
32
+ lib = "brice/#{lib}"
33
+ require lib
34
+ }
35
+
36
+ class Brice
37
+
38
+ BRICE_HOME = File.join(ENV.user_home, '.brice')
39
+
40
+ @verbose = false
41
+ @quiet = false
42
+
43
+ class << self
44
+
45
+ include DSL
46
+
47
+ attr_reader :config, :irb_rc
48
+
49
+ attr_accessor :verbose, :quiet
50
+
51
+ # call-seq:
52
+ # Brice.init { |config| ... }
53
+ # Brice.init(:verbose => true) { |config| ... }
54
+ #
55
+ # Initialize Brice and optionally configure any packages.
56
+ def init(options = {})
57
+ @irb_rc = []
58
+ @config = Config.new(rc_files(true).map { |rc|
59
+ File.basename(rc, '.rb').sub(/\A\d+_/, '')
60
+ })
61
+
62
+ options.each { |key, value|
63
+ method = "#{key}="
64
+
65
+ if respond_to?(method)
66
+ send(method, value)
67
+ else
68
+ raise ArgumentError, "illegal option: #{key}"
69
+ end
70
+ }
71
+
72
+ yield config if block_given?
73
+
74
+ load_rc_files(true)
75
+ finalize_irb_rc!
76
+
77
+ config
78
+ end
79
+
80
+ # call-seq:
81
+ # Brice.config = config
82
+ #
83
+ # Set config to +config+. Raises a TypeError if +config+ is not a
84
+ # Brice::Config.
85
+ def config=(config)
86
+ raise TypeError, "expected Brice::Config, got #{config.class}" \
87
+ unless config.is_a?(Config)
88
+
89
+ @config = config
90
+ end
91
+
92
+ # call-seq:
93
+ # Brice.include?(package) => true or false
94
+ # Brice.have?(package) => true or false
95
+ #
96
+ # See whether package +package+ is enabled/included.
97
+ def include?(package)
98
+ config.include?(package)
99
+ end
100
+
101
+ alias_method :have?, :include?
102
+
103
+ # call-seq:
104
+ # Brice.rc_files(include_custom_extensions = false) => anArray
105
+ #
106
+ # Get the extension files, optionally including custom extensions
107
+ # if +include_custom_extensions+ is true.
108
+ def rc_files(include_custom_extensions = false)
109
+ @rc_files ||= find_rc_files
110
+ include_custom_extensions ? @rc_files + custom_extensions : @rc_files
111
+ end
112
+
113
+ # call-seq:
114
+ # Brice.custom_extensions => anArray
115
+ #
116
+ # Get the custom extension files.
117
+ def custom_extensions
118
+ @custom_extensions ||= find_rc_files(BRICE_HOME)
119
+ end
120
+
121
+ private
122
+
123
+ # call-seq:
124
+ # load_rc_files(include_custom_extensions = false) => anArray
125
+ #
126
+ # Load the extension files, optionally including custom extensions
127
+ # if +include_custom_extensions+ is true.
128
+ def load_rc_files(include_custom_extensions = false)
129
+ Object.send(:include, DSL)
130
+
131
+ res = rc_files.each { |rc|
132
+ warn "Loading #{rc}..." if verbose
133
+ brice_load rc
134
+ }
135
+
136
+ include_custom_extensions ? res += load_custom_extensions : res
137
+ end
138
+
139
+ # call-seq:
140
+ # load_custom_extensions => anArray
141
+ #
142
+ # Load the custom extension files.
143
+ def load_custom_extensions
144
+ custom_extensions.each { |rc|
145
+ warn "Loading custom #{rc}..." if verbose
146
+ brice_load rc
147
+ }
148
+ end
149
+
150
+ # call-seq:
151
+ # find_rc_files(dir = ...) => anArray
152
+ #
153
+ # Find the actual extension files in +dir+.
154
+ def find_rc_files(dir = File.join(File.dirname(__FILE__), 'rc'))
155
+ File.directory?(dir) ? Dir["#{dir}/*.rb"].sort : []
156
+ end
157
+
158
+ # call-seq:
159
+ # finalize_irb_rc! => aProc
160
+ #
161
+ # Generate proc for IRB_RC from all added procs.
162
+ def finalize_irb_rc!
163
+ IRB.conf[:IRB_RC] = lambda { |context|
164
+ irb_rc.each { |rc| rc[context] }
165
+ } unless irb_rc.empty?
166
+ end
167
+
168
+ end
169
+
170
+ end
@@ -0,0 +1,27 @@
1
+ # Configure wirble[http://pablotron.org/software/wirble/]
2
+
3
+ brice 'wirble' do |config|
4
+
5
+ # Save history newest-first, instead of default oldest-first.
6
+ class Wirble::History
7
+ def save_history
8
+ if Object.const_defined?(:IRB)
9
+ path, max_size, perms = %w[path size perms].map { |v| cfg(v) }
10
+
11
+ lines = Readline::HISTORY.to_a.reverse.uniq.reverse
12
+ lines = lines[-max_size..-1] if lines.size > max_size
13
+
14
+ real_path = File.expand_path(path)
15
+ File.open(real_path, perms) { |fh| fh.puts lines }
16
+ say 'Saved %d lines to history file %s.' % [lines.size, path]
17
+ end
18
+ end
19
+ end
20
+
21
+ # Make wirble and ruby-debug use the same histfile
22
+ silence { FILE_HISTORY = Wirble::History::DEFAULTS[:history_path] }
23
+
24
+ Wirble.init(:skip_prompt => true)
25
+ Wirble.colorize
26
+
27
+ end
@@ -0,0 +1,24 @@
1
+ # Load Util::AddedMethods[http://prometheus.rubyforge.org/ruby-nuggets/classes/Util/AddedMethods.html]
2
+ # from ruby-nuggets[http://prometheus.rubyforge.org/ruby-nuggets/] if one (or both) of the following
3
+ # environment variables has been set:
4
+ #
5
+ # <tt>WATCH_FOR_ADDED_METHODS</tt>:: Regular expression or <tt>true</tt>
6
+ # <tt>WATCH_FOR_ADDED_METHODS_IN</tt>:: Space-delimited list of class names
7
+
8
+ brice 'added_methods' => 'nuggets/util/added_methods' do |config|
9
+
10
+ regexp = ENV['WATCH_FOR_ADDED_METHODS']
11
+ klasses = ENV['WATCH_FOR_ADDED_METHODS_IN']
12
+
13
+ if regexp || klasses
14
+ if regexp == 'true'
15
+ Util::AddedMethods.init
16
+ else
17
+ regexp = Regexp.new(regexp || '')
18
+ klasses = (klasses || '').split
19
+
20
+ Util::AddedMethods.init(regexp, klasses)
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,16 @@
1
+ # Load libraries
2
+
3
+ brice 'libs' => nil do |config|
4
+
5
+ libs = config.entries
6
+ libs = %w[
7
+ yaml
8
+ tempfile
9
+ benchmark
10
+ backports
11
+ what_methods
12
+ ] if libs.empty?
13
+
14
+ libs.each { |lib| brice_require lib }
15
+
16
+ end
@@ -0,0 +1,15 @@
1
+ # Load selected pieces from {Utility Belt}[http://utilitybelt.rubyforge.org/]
2
+
3
+ brice 'utility_belt' => %w[
4
+ utility_belt/interactive_editor
5
+ utility_belt/irb_verbosity_control
6
+ ] do |config|
7
+
8
+ brice_require 'utility_belt/language_greps' do
9
+
10
+ alias :mgrep :grep_methods
11
+ alias :cgrep :grep_classes
12
+
13
+ end
14
+
15
+ end