library 0.1.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/.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