library 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.ruby ADDED
@@ -0,0 +1,57 @@
1
+ ---
2
+ source:
3
+ - var
4
+ authors:
5
+ - name: trans
6
+ email: transfire@gmail.com
7
+ copyrights:
8
+ - holder: Rubyworks
9
+ year: '2006'
10
+ license: BSD-2-Clause
11
+ replacements: []
12
+ alternatives: []
13
+ requirements:
14
+ - name: detroit
15
+ groups:
16
+ - build
17
+ development: true
18
+ - name: setup
19
+ version: 5.0+
20
+ groups:
21
+ - build
22
+ development: true
23
+ - name: rubytest
24
+ groups:
25
+ - test
26
+ development: true
27
+ - name: lemon
28
+ groups:
29
+ - test
30
+ development: true
31
+ - name: ae
32
+ groups:
33
+ - test
34
+ development: true
35
+ dependencies: []
36
+ conflicts: []
37
+ repositories:
38
+ - uri: git://github.com/rubyworks/library.git
39
+ scm: git
40
+ name: upstream
41
+ resources:
42
+ home: http://rubyworks.github.com/library
43
+ code: http://github.com/rubyworks/library
44
+ mail: http://groups.google.com/groups/rubyworks-mailinglist
45
+ extra: {}
46
+ load_path:
47
+ - lib
48
+ revision: 0
49
+ created: '2006-12-10'
50
+ summary: Objectifying the Ruby Library
51
+ title: Library
52
+ version: 0.1.0
53
+ name: library
54
+ description: ! "The Library class encapsulates the essential nature \nof a Ruby library
55
+ --a location on disk from which\nscripts can be required."
56
+ organization: rubyworks
57
+ date: '2012-01-10'
@@ -0,0 +1,6 @@
1
+ --title Library
2
+ --protected
3
+ --private
4
+ lib/
5
+ -
6
+ [A-Z]*.*
@@ -0,0 +1,30 @@
1
+ = COPYRIGHT NOTICES
2
+
3
+ == Library
4
+
5
+ Copyright:: (c) 2006 Rubyworks
6
+ License:: BSD-2-Clause
7
+ Website:: http://rubyworks.github.com/library
8
+
9
+ Copyright (c) 2006 Rubyworks. All rights reserved.
10
+
11
+ Redistribution and use in source and binary forms, with or without modification, are
12
+ permitted provided that the following conditions are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright notice, this list of
15
+ conditions and the following disclaimer.
16
+
17
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
18
+ of conditions and the following disclaimer in the documentation and/or other materials
19
+ provided with the distribution.
20
+
21
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
22
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
24
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
@@ -0,0 +1,13 @@
1
+ = RELEASE HISTORY
2
+
3
+ == 0.1.0 / 2012-01-10
4
+
5
+ The Library gem is a spin-off of the Rolls gem. The Library class
6
+ is at the heart of Rolls, but is well defined enough to stand on its
7
+ own as a separate supporting package. By having it as a separate
8
+ project it becomes easier to focus on it's essential functionality.
9
+
10
+ Changes:
11
+
12
+ * Spin-off from Rolls and release.
13
+
@@ -0,0 +1,177 @@
1
+ # RUBY LIBRARY
2
+
3
+ <img src="" />
4
+
5
+ [home](http://rubyworks.github.com/library) /
6
+ [code](http://github.com/rubyworks/library)
7
+
8
+
9
+ ## DESCRIPTION
10
+
11
+ Library is, as its name implies, the objectification of the Ruby library.
12
+ Along with the Library Ledger, which keeps an indexed list of available
13
+ libraries, a variety of useful features are bestowed to Ruby developers.
14
+
15
+ * Work with libraries in an object-oriented manner.
16
+ * Develop interdependent projects in real time without installing, linking or vendoring.
17
+ * Create isolated library environments based on project requirements.
18
+ * Libraries can be stored anywhere. There is no special "home" path they must reside.
19
+ * Serve gem installed libraries as easily as it serves developer's libraries.
20
+ * Is the foundation of the Rolls gem, which provides a superset of library management functions.
21
+
22
+ IMPORTANT: Presently gem installed packages can only be served if a `.ruby` file
23
+ is part of the gem package. This should be fixed in the next release. To work
24
+ around the `dotruby` gem can be used to generate a `.ruby` file for installed
25
+ gems.
26
+
27
+
28
+ ## USAGE
29
+
30
+ ### Using the API
31
+
32
+ The basics of the Library API are fairly simple. Given a location on disc
33
+ that houses a Ruby library, e.g. `projects/hello`, a new Library instance
34
+ can be created like any other object.
35
+
36
+ mylib = Library.new('projects/hello')
37
+
38
+ With a library object in hand, we can require or load files from that library.
39
+
40
+ mylib.require 'world'
41
+
42
+ Or look at information about the library.
43
+
44
+ mylib.name #=> 'hello'
45
+ mylib.version #=> '1.0.0'
46
+
47
+ Crating a library object via`#new` gives us a one-off object. But to persist
48
+ the library and make it available by name we can use `#add` instead.
49
+
50
+ Library.add('projects/hello')
51
+
52
+ Or, delving down a bit deeper into the belly of system, one could simply
53
+ feed the path to the master Ledger instance.
54
+
55
+ $LEDGER << 'projects/hello'
56
+
57
+ Both have the same exact effect. Our library will then be available via
58
+ Library's various look-up methods. There are a few of these. One of these is
59
+ the Kernel method `#library`.
60
+
61
+ library('hello')
62
+
63
+ Another is `#[]` class method.
64
+
65
+ Library['hello']
66
+
67
+ There are many other useful Library methods, see the API documentation
68
+ for more details.
69
+
70
+ ### Using RUBYLIBS
71
+
72
+ To use Library on a regular basis, add library paths to the `RUBYLIBS`
73
+ environment variable. (NOTICE It is plural!!!)
74
+
75
+ export RUBYLIBS="~/workspace/ruby-projects"
76
+
77
+ And add `-rubylibs` to the RUBYOPT environment variable.
78
+
79
+ export RUBYOPT="-rubylibs"
80
+
81
+ You might already have `-rubygems` there, which is fine too.
82
+
83
+ export RUBYOPT="-rubylibs -rubygems"
84
+
85
+ If you want access to project executables you will also need to append the
86
+ project `bin` locations to the PATH environment variable.
87
+
88
+ export PATH="$PATH:$(ruby -e'Library::PATH()')"
89
+
90
+ This will add the `bin` locations of the programs encompassed by your
91
+ current `RUBYLIBS` setting.
92
+
93
+ Of course, you will probably want to add these lines to your startup `.bashrc`
94
+ file (or equivalent) so they are ready to go every time you bring up your
95
+ shell console.
96
+
97
+ ### Preping Projects
98
+
99
+ For a project to be usable via Library it must conform to common organizational
100
+ conventions for a Ruby project and it should have a `.ruby` file.
101
+
102
+ It is highly recommend that a project have a `.ruby` file although a `.gemspec`
103
+ file can serve as a fallback if a `.ruby` file isn't found. But relying on a
104
+ `.gemspec` is going to slow things down a fair bit. It also requires that
105
+ the `dotruby` library be installed.
106
+
107
+ To activate .gemspec support set the environment variable `RUBYLIBS_GEMSPEC=true`.
108
+
109
+ See http://dotruby.github.com/dotruby for more information about `.ruby` files.
110
+
111
+
112
+ ### Autoload Caveat
113
+
114
+ Ruby has a "bug" which prevents `#autoload` from using custom `#require`
115
+ methods. So `#autoload` calls cannot make use of the Library setup.
116
+ This is not as significant as it might seem since `#autoload` is being
117
+ deprecated as of Ruby 2.0. So it is best to discontinue it's use anyway.
118
+
119
+
120
+ ## LEARNING MORE
121
+
122
+ The above provides a brief overview of using the Library gem. But there is
123
+ more to it. To get a deeper understanding of the system its fullest extent,
124
+ please visit http://rubyworks.github.org/library.
125
+
126
+
127
+ ## INSTALLATION
128
+
129
+ ### RubyGems Installation
130
+
131
+ We strongly recommend installing Roller manually b/c Roller is a
132
+ peer to RubyGems. However, the last we tested it, Roller could
133
+ be install via Gems as a means of trying it out --though you won't
134
+ get the full benefits of the system.
135
+
136
+ $ gem install library
137
+
138
+ If you like Roller, then later you can uninstall the gem and
139
+ do a proper manual install.
140
+
141
+
142
+ ### Manual Installation
143
+
144
+ Manual installation is recommended for regular usage, since it
145
+ can then be loaded without going through RubyGems.
146
+
147
+ First you need a copy of the tarball (or zip) archive. You will
148
+ find them [here](http://github.com/rubyworks/library/download).
149
+ You will of course need to unpack the file. For example,
150
+
151
+ $ tar -xvzf library-0.1.0
152
+
153
+ If you already have Ruby Setup installed on your system you can
154
+ use it to install (See: http://rubyworks.github.com/setup).
155
+
156
+ $ cd library-0.1.0
157
+ $ sudo setup.rb
158
+
159
+ Otherwise, the package includes a copy of Ruby Setup that you can
160
+ use.
161
+
162
+ $ cd library-0.1.0
163
+ $ sudo script/setup.
164
+
165
+ On Windows, this last line will need to be 'ruby script/setup'.
166
+
167
+
168
+ ## COPYRIGHTS
169
+
170
+ Ruby Library
171
+
172
+ Copyright (c) 2006 Rubyworks
173
+
174
+ Ruby Library is distributable in accordance with the **FreeBSD** license.
175
+
176
+ See the COPYING.rdoc file details.
177
+
@@ -0,0 +1,532 @@
1
+ require 'library/core_ext'
2
+ require 'library/ledger'
3
+ require 'library/errors'
4
+ require 'library/metadata'
5
+ require 'library/feature'
6
+ require 'library/version'
7
+ require 'library/domain'
8
+
9
+ # Library class encapsulates a location on disc that contains a Ruby
10
+ # project, with loadable features, of course.
11
+ #
12
+ class Library
13
+
14
+ #
15
+ # Library ledger.
16
+ #
17
+ $LEDGER = Ledger.new
18
+
19
+ #
20
+ # When loading files, the current library doing the loading is pushed
21
+ # on this stack, and then popped-off when it is finished.
22
+ #
23
+ $LOAD_STACK = []
24
+
25
+ #
26
+ #
27
+ #
28
+ $LOAD_CACHE = {}
29
+
30
+ # Dynamic link extension.
31
+ #DLEXT = '.' + ::RbConfig::CONFIG['DLEXT']
32
+
33
+ # TODO: Some extensions are platform specific --only add the ones needed
34
+ # for the current platform to SUFFIXES.
35
+
36
+ #
37
+ # Possible suffixes for feature files, that #require will try automatically.
38
+ #
39
+ SUFFIXES = ['.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar'] #, '']
40
+
41
+ #
42
+ # Extensions glob, joins extensions with comma and wrap in curly brackets.
43
+ #
44
+ SUFFIX_PATTERN = "{#{SUFFIXES.join(',')}}"
45
+
46
+ #
47
+ # A shortcut for #instance.
48
+ #
49
+ # @return [Library,NilClass] The activated Library instance, or `nil` if not found.
50
+ #
51
+ def self.[](name, constraint=nil)
52
+ $LEDGER.activate(name, constraint) if $LEDGER.key?(name)
53
+ end
54
+
55
+ #
56
+ # Get an instance of a library by name, or name and version.
57
+ # Libraries are singleton, so once loaded the same object is
58
+ # always returned.
59
+ #
60
+ # @todo This method might be deprecated.
61
+ #
62
+ # @return [Library,NilClass] The activated Library instance, or `nil` if not found.
63
+ #
64
+ def self.instance(name, constraint=nil)
65
+ $LEDGER.activate(name, constraint) if $LEDGER.key?(name)
66
+ end
67
+
68
+ #
69
+ # Activate a library. Same as #instance but will raise and error if the
70
+ # library is not found. This can also take a block to yield on the library.
71
+ #
72
+ # @param [String] name
73
+ # Name of library.
74
+ #
75
+ # @param [String] constraint
76
+ # Valid version constraint.
77
+ #
78
+ # @raise [LoadError]
79
+ # If library not found.
80
+ #
81
+ # @return [Library]
82
+ # The activated Library object.
83
+ #
84
+ def self.activate(name, constraint=nil) #:yield:
85
+ library = $LEDGER.activate(name, constraint)
86
+ yield(library) if block_given?
87
+ library
88
+ end
89
+
90
+ #
91
+ # Like `#new`, but adds library to library ledger.
92
+ #
93
+ # @todo Better name for this method?
94
+ #
95
+ # @return [Library] The new library.
96
+ #
97
+ def self.add(location)
98
+ $LEDGER.add_location(location)
99
+
100
+ #library = new(location)
101
+ #$LEDGER.add_library(library)
102
+ #library
103
+ end
104
+
105
+ #
106
+ # New Library object.
107
+ #
108
+ # If data is given it must have `:name` and `:version`. It can
109
+ # also have `:loadpath`, `:date`, and `:omit`.
110
+ #
111
+ # @param location [String]
112
+ # Expanded file path to library's root directory.
113
+ #
114
+ # @param metadata [Hash]
115
+ # Overriding matadata (to circumvent loading it from `.ruby` file).
116
+ #
117
+ def initialize(location, metadata={})
118
+ raise TypeError, "not a directory - #{location}" unless File.directory?(location)
119
+
120
+ @location = location
121
+ @metadata = Metadata.new(location, metadata)
122
+
123
+ raise ValidationError, "Non-conforming library (missing name) -- `#{location}'" unless name
124
+ raise ValidationError, "Non-conforming library (missing version) -- `#{location}'" unless version
125
+ end
126
+
127
+ #
128
+ # Activate a library.
129
+ #
130
+ # @return [true,false] Has the library has been activated?
131
+ #
132
+ def activate
133
+ current = $LEDGER[name]
134
+
135
+ if Library === current
136
+ raise VersionConflict.new(self, current) if current != self
137
+ else
138
+ ## NOTE: we are only doing this for the sake of autoload
139
+ ## which does not honor a customized require method.
140
+ #if Library.autoload_hack?
141
+ # absolute_loadpath.each do |path|
142
+ # $LOAD_PATH.unshift(path)
143
+ # end
144
+ #end
145
+ $LEDGER[name] = self
146
+ end
147
+
148
+ # TODO: activate runtime requirements?
149
+ #verify
150
+ end
151
+
152
+ #
153
+ # Is this library active in global ledger?
154
+ #
155
+ def active?
156
+ $LEDGER[name] == self
157
+ end
158
+
159
+ #
160
+ # Location of library files on disc.
161
+ #
162
+ def location
163
+ @location
164
+ end
165
+
166
+ #
167
+ # Access to library metadata. Metadata is gathered from
168
+ # the `.ruby` file or a `.gemspec` file.
169
+ #
170
+ # @return [Metadata] metadata object
171
+ #
172
+ def metadata
173
+ @metadata
174
+ end
175
+
176
+ #
177
+ # Library's "unixname".
178
+ #
179
+ # @return [String] name of library
180
+ #
181
+ def name
182
+ @name ||= metadata.name
183
+ end
184
+
185
+ #
186
+ # Library's version number.
187
+ #
188
+ # @return [VersionNumber] version number
189
+ #
190
+ def version
191
+ @version ||= metadata.version
192
+ end
193
+
194
+ #
195
+ # Library's internal load path(s). This will default to `['lib']`
196
+ # if not otherwise given.
197
+ #
198
+ # @return [Array] list of load paths
199
+ #
200
+ def load_path
201
+ metadata.load_path
202
+ end
203
+
204
+ alias_method :loadpath, :load_path
205
+
206
+ #
207
+ # Release date.
208
+ #
209
+ # @return [Time] library's release date
210
+ #
211
+ def date
212
+ metadata.date
213
+ end
214
+
215
+ #
216
+ # Alias for +#date+.
217
+ #
218
+ alias_method :released, :date
219
+
220
+ #
221
+ # Library's requirements. Note that in gemspec terminology these are
222
+ # called *dependencies*.
223
+ #
224
+ # @return [Array] list of requirements
225
+ #
226
+ def requirements
227
+ metadata.requirements
228
+ end
229
+
230
+ #
231
+ # Runtime requirements.
232
+ #
233
+ # @return [Array] list of runtime requirements
234
+ #
235
+ def runtime_requirements
236
+ requirements.select{ |req| !req['development'] }
237
+ end
238
+
239
+ #
240
+ # Omit library form ledger?
241
+ #
242
+ # @return [Boolean] if true, omit library from ledger
243
+ #
244
+ def omit
245
+ @metadata.omit
246
+ end
247
+
248
+ #
249
+ # Same as `#omit`.
250
+ #
251
+ alias_method :omit?, :omit
252
+
253
+ #
254
+ # Returns a list of load paths expand to full path names.
255
+ #
256
+ # @return [Array<String>] list of expanded load paths
257
+ #
258
+ def absolute_loadpath
259
+ loadpath.map{ |lp| ::File.join(location, lp) }
260
+ end
261
+
262
+ #
263
+ # Take requirements and open them. This will reveal any
264
+ # version conflicts or missing dependencies.
265
+ #
266
+ # @param [Boolean] development
267
+ # Include development dependencies?
268
+ #
269
+ def verify(development=false)
270
+ reqs = development ? requirements : runtime_requirements
271
+ reqs.each do |req|
272
+ name, constraint = req['name'], req['version']
273
+ Library.open(name, constraint)
274
+ end
275
+ end
276
+
277
+ #
278
+ # Does a library contain a relative +file+ within it's loadpath.
279
+ # If so return the libary file object for it, otherwise +false+.
280
+ #
281
+ # Note that this method was designed to maximize speed.
282
+ #
283
+ # @param [#to_s] file
284
+ # The relative pathname of the file to find.
285
+ #
286
+ # @param [Hash] options
287
+ # The Hash of optional settings to adjust search behavior.
288
+ #
289
+ # @option options [Boolean] :suffix
290
+ # Automatically try standard extensions if pathname has none.
291
+ #
292
+ # @option options [Boolean] :legacy
293
+ # (deprecated) Do not match within library's +name+ directory, eg. `lib/foo/*`.
294
+ #
295
+ # @return [Feature,nil] The feature, if found.
296
+ #
297
+ def find(pathname, options={})
298
+ main = options[:main]
299
+ #legacy = options[:legacy]
300
+ suffix = options[:suffix] || options[:suffix].nil?
301
+ #suffix = false if options[:load]
302
+ suffix = false if SUFFIXES.include?(::File.extname(pathname))
303
+ if suffix
304
+ loadpath.each do |lpath|
305
+ SUFFIXES.each do |ext|
306
+ f = ::File.join(location, lpath, pathname + ext)
307
+ return feature(lpath, pathname, ext) if ::File.file?(f)
308
+ end
309
+ end #unless legacy
310
+ legacy_loadpath.each do |lpath|
311
+ SUFFIXES.each do |ext|
312
+ f = ::File.join(location, lpath, pathname + ext)
313
+ return feature(lpath, pathname, ext) if ::File.file?(f)
314
+ end
315
+ end unless main
316
+ else
317
+ loadpath.each do |lpath|
318
+ f = ::File.join(location, lpath, pathname)
319
+ return feature(lpath, pathname) if ::File.file?(f)
320
+ end #unless legacy
321
+ legacy_loadpath.each do |lpath|
322
+ f = ::File.join(location, lpath, pathname)
323
+ return feature(lpath, pathname) if ::File.file?(f)
324
+ end unless main
325
+ end
326
+ nil
327
+ end
328
+
329
+ #
330
+ # Alias for #find.
331
+ #
332
+ alias_method :include?, :find
333
+
334
+ #
335
+ #
336
+ #
337
+ def legacy?
338
+ !legacy_loadpath.empty?
339
+ end
340
+
341
+ #
342
+ # What is `legacy_loadpath`? Well, library doesn't require you to put your
343
+ # library's scripts in a named lib path, e.g. `lib/foo/`. Instead one can
344
+ # just put them in `lib/` b/c Library keeps things indexed by honest to
345
+ # goodness library names. The `legacy_path` then is used to handle these
346
+ # old style paths along with the new.
347
+ #
348
+ def legacy_loadpath
349
+ @legacy_loadpath ||= (
350
+ path = []
351
+ loadpath.each do |lp|
352
+ llp = File.join(lp, name)
353
+ dir = File.join(location, llp)
354
+ path << llp if File.directory?(dir)
355
+ end
356
+ path
357
+ )
358
+ end
359
+
360
+ #
361
+ # Create a new Feature object from +lpath+, +pathname+ and +ext+.
362
+ #
363
+ def feature(lpath, pathname, ext=nil)
364
+ Feature.new(self, lpath, pathname, ext)
365
+ end
366
+
367
+ #
368
+ # Requre feature from library.
369
+ #
370
+ def require(pathname, options={})
371
+ if feature = find(pathname, options)
372
+ feature.require(options)
373
+ else
374
+ raise LoadError.new(path, name) # TODO: silently?
375
+ end
376
+ end
377
+
378
+ #
379
+ # Load feature form library.
380
+ #
381
+ def load(pathname, options={})
382
+ #options[:load] = true
383
+ if feature = find(pathname, options)
384
+ feature.load(options)
385
+ else
386
+ raise LoadError.new(pathname, self.name)
387
+ end
388
+ end
389
+
390
+ #
391
+ # Inspect library instance.
392
+ #
393
+ def inspect
394
+ if version
395
+ %[#<Library #{name}/#{version} @location="#{location}">]
396
+ else
397
+ %[#<Library #{name} @location="#{location}">]
398
+ end
399
+ end
400
+
401
+ #
402
+ # Same as #inspect.
403
+ #
404
+ def to_s
405
+ inspect
406
+ end
407
+
408
+ #
409
+ # Compare by version.
410
+ #
411
+ def <=>(other)
412
+ version <=> other.version
413
+ end
414
+
415
+ #
416
+ # Return default feature. This is the feature that has same name as
417
+ # the library itself.
418
+ #
419
+ def default
420
+ @default ||= find(name, :main=>true)
421
+ end
422
+
423
+ #--
424
+ # # List of subdirectories that are searched when loading.
425
+ # #--
426
+ # # This defualts to ['lib/{name}', 'lib']. The first entry is
427
+ # # usually proper location; the latter is added for default
428
+ # # compatability with the traditional require system.
429
+ # #++
430
+ # def libdir
431
+ # loadpath.map{ |path| ::File.join(location, path) }
432
+ # end
433
+ #
434
+ # # Does the library have any lib directories?
435
+ # def libdir?
436
+ # lib.any?{ |d| ::File.directory?(d) }
437
+ # end
438
+ #++
439
+
440
+ #
441
+ # Location of executable. This is alwasy bin/. This is a fixed
442
+ # convention, unlike lib/ which needs to be more flexable.
443
+ #
444
+ def bindir
445
+ ::File.join(location, 'bin')
446
+ end
447
+
448
+ #
449
+ # Is there a `bin/` location?
450
+ #
451
+ def bindir?
452
+ ::File.exist?(bindir)
453
+ end
454
+
455
+ #
456
+ # Location of library system configuration files.
457
+ # This is alwasy the `etc/` directory.
458
+ #
459
+ def confdir
460
+ ::File.join(location, 'etc')
461
+ end
462
+
463
+ #
464
+ # Is there a `etc/` location?
465
+ #
466
+ def confdir?
467
+ ::File.exist?(confdir)
468
+ end
469
+
470
+ # Location of library shared data directory.
471
+ # This is always the `data/` directory.
472
+ def datadir
473
+ ::File.join(location, 'data')
474
+ end
475
+
476
+ # Is there a `data/` location?
477
+ def datadir?
478
+ ::File.exist?(datadir)
479
+ end
480
+
481
+ #
482
+ #def to_rb
483
+ # to_h.inspect
484
+ #end
485
+
486
+ #
487
+ # Convert to hash.
488
+ #
489
+ # @return [Hash] The library metadata in a hash.
490
+ #
491
+ def to_h
492
+ {
493
+ :location => location,
494
+ :name => name,
495
+ :version => version.to_s,
496
+ :loadpath => loadpath,
497
+ :date => date.to_s,
498
+ :requirements => requirements
499
+ }
500
+ end
501
+
502
+ module ::Kernel
503
+ #
504
+ # In which library is the current file participating?
505
+ #
506
+ # @return [Library] The library currently loading features.
507
+ #
508
+ def __LIBRARY__
509
+ $LOAD_STACK.last.library
510
+ end
511
+
512
+ #
513
+ # Activate a library, same as `Library.instance` but will raise and error
514
+ # if the library is not found. This can also take a block to yield on the
515
+ # library.
516
+ #
517
+ # @param name [String]
518
+ # The library's name.
519
+ #
520
+ # @param constraint [String]
521
+ # A valid version constraint.
522
+ #
523
+ # @return [Library] The Library instance.
524
+ #
525
+ def library(name, constraint=nil, &block) #:yield:
526
+ Library.activate(name, constraint, &block)
527
+ end
528
+
529
+ module_function :library
530
+ end
531
+
532
+ end