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 +57 -0
- data/.yardopts +6 -0
- data/COPYING.rdoc +30 -0
- data/HISTORY.rdoc +13 -0
- data/README.md +177 -0
- data/lib/library.rb +532 -0
- data/lib/library/autoload.rb +14 -0
- data/lib/library/core_ext.rb +34 -0
- data/lib/library/domain.rb +244 -0
- data/lib/library/errors.rb +49 -0
- data/lib/library/feature.rb +207 -0
- data/lib/library/kernel.rb +81 -0
- data/lib/library/ledger.rb +642 -0
- data/lib/library/metadata.rb +398 -0
- data/lib/library/rbconfig.rb +65 -0
- data/lib/library/rubygems.rb +19 -0
- data/lib/library/rubylib.rb +206 -0
- data/lib/library/version.rb +387 -0
- data/lib/ubylibs.rb +8 -0
- data/qed/01_loading.rdoc +14 -0
- data/qed/02_library.rdoc +55 -0
- data/qed/03_ledger.rdoc +30 -0
- data/qed/04_version.rdoc +101 -0
- data/qed/applique/check.rb +11 -0
- data/qed/applique/project.rb +34 -0
- data/qed/fixtures/foo/.ruby +5 -0
- data/qed/fixtures/foo/lib/foo.rb +1 -0
- data/qed/fixtures/tryme/1.0/.ruby +6 -0
- data/qed/fixtures/tryme/1.0/lib/tryme.rb +1 -0
- data/qed/fixtures/tryme/1.1/.ruby +7 -0
- data/qed/fixtures/tryme/1.1/lib/tryme.rb +1 -0
- data/qed/helpers/new_project.rdoc +29 -0
- data/qed/helpers/projects.rdoc +56 -0
- data/test/case_ledger.rb +23 -0
- data/test/case_library.rb +13 -0
- data/test/case_version.rb +89 -0
- data/test/fixture/.ruby +56 -0
- data/test/fixture/lib/foo.rb +7 -0
- data/test/helper.rb +2 -0
- metadata +144 -0
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'
|
data/.yardopts
ADDED
data/COPYING.rdoc
ADDED
@@ -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
|
+
|
data/HISTORY.rdoc
ADDED
@@ -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
|
+
|
data/README.md
ADDED
@@ -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
|
+
|
data/lib/library.rb
ADDED
@@ -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
|