acls 1.0.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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +98 -0
- data/lib/acls.rb +93 -0
- data/lib/module.rb +9 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8368c41a5c809253d8edd299e4979988e71dc6f
|
4
|
+
data.tar.gz: 3add1931cdb2b571757adf3e7fa84ae223c38eea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af956f49b047caa81da85e43368f854dd316cf22bb8e930278226071a9e4b9230db0b431a735858f9626ee591a9b4b57bc7d7582b7cb8b70860ed7e90117dc84
|
7
|
+
data.tar.gz: 92564464ccf52966c6cd764ee13b426c946e11eb2f62e5b4b3f3ec21a9fff7f511b55317068703da641c17a8f162438cdf27e0130719808222e5128dd029bccb
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Tyler Margison
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# automatic code loading system (acls)
|
2
|
+
|
3
|
+
[](https://semaphoreci.com/kolorahl/acls)
|
4
|
+
|
5
|
+
## What is it?
|
6
|
+
|
7
|
+
The Automatic Code Loading System (ACLS) is a Ruby library intended to help
|
8
|
+
speed up and simplify development time by allowing developers to define pathes
|
9
|
+
and patterns of files that should be autoloaded when their application runs.
|
10
|
+
|
11
|
+
## How does it work?
|
12
|
+
|
13
|
+
Rails does something like this. In a Rails application you would change your
|
14
|
+
autoloading paths as such:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
config.autoload_paths += ['lib', 'other/lib', 'etc'].map { |folder| "#{config.root}/#{folder}" }
|
18
|
+
```
|
19
|
+
|
20
|
+
Rails will then look for all Ruby files in those directory trees and load them
|
21
|
+
for immediate use into your application. However, Rails does this in a very
|
22
|
+
complex manner by taking over the flow for when a constant isn't found. ACLS
|
23
|
+
does **not** do that. I have chosen a more straight-forward solution, which
|
24
|
+
simply generates an `autoload` statement for all Ruby files in a set of paths.
|
25
|
+
|
26
|
+
As an example, assume the following directory structure:
|
27
|
+
|
28
|
+
```
|
29
|
+
- lib
|
30
|
+
| - one.rb
|
31
|
+
| - two.rb
|
32
|
+
| - sub
|
33
|
+
| | - three.rb
|
34
|
+
- other
|
35
|
+
| - four.rb
|
36
|
+
```
|
37
|
+
|
38
|
+
Pass in the desired directory paths into the ACLS module:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
ACLS::Loader.auto(['lib', 'other'])
|
42
|
+
```
|
43
|
+
|
44
|
+
That one line with ACLS is equivalent to hand-writing the following Ruby code:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
autoload :One, 'lib/one.rb'
|
48
|
+
autoload :Two, 'lib/two.rb'
|
49
|
+
module Sub
|
50
|
+
autoload :Three, 'lib/sub/three.rb'
|
51
|
+
end
|
52
|
+
autoload :Four, 'other/four.rb'
|
53
|
+
```
|
54
|
+
|
55
|
+
## Using it
|
56
|
+
|
57
|
+
The simplest way is to use:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
ACLS::Loader.auto(['path', 'to/one/or/more', 'directories'])
|
61
|
+
```
|
62
|
+
|
63
|
+
ACLS will automatically generate new module constants if it needs to. This
|
64
|
+
method of autoloading, however, makes assumptions about the directory
|
65
|
+
structure. The top-level directory is assumed to carry no namespace but every
|
66
|
+
sub-directory under that *does* imply a namespace. To customize bits of the
|
67
|
+
behavior, an options hash can be passed in as a second argument:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
ACLS::Loader.auto('lib', {root_ns: true})
|
71
|
+
```
|
72
|
+
|
73
|
+
Options available:
|
74
|
+
|
75
|
+
- `root_ns`: When `true`, this will use the top-level directory name as the root
|
76
|
+
namespace for all files and folders in the tree. When a string is supplied,
|
77
|
+
this will use the string as the name of the root namespace. For all other
|
78
|
+
values, the root directory is not a namespace and everything falls under the
|
79
|
+
`Object` namespace.
|
80
|
+
- `exclude`: Must be a collection of strings and/or regexps. For each string in
|
81
|
+
the collection, files are excluded from autoloading if they match the string
|
82
|
+
exactly. For each regexp in the collection, files are excluded from
|
83
|
+
autoloading if the path results in a successful match on the regexp.
|
84
|
+
- `immediate`: Must be a collection of strings and/or regexps. Follows the same
|
85
|
+
conditional pattern as `exclude`, but on a match this will immediate load the
|
86
|
+
file via `load` instead of deferring it using `autoload`.
|
87
|
+
|
88
|
+
## Feature List
|
89
|
+
|
90
|
+
### Core
|
91
|
+
|
92
|
+
- [X] Generate `autoload` statements based on a set of directory paths.
|
93
|
+
|
94
|
+
### Options/Configuration
|
95
|
+
|
96
|
+
- [X] Implement `root_ns`.
|
97
|
+
- [ ] Implement `exclude`.
|
98
|
+
- [ ] Implement `immediate`.
|
data/lib/acls.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
require_relative './module'
|
3
|
+
|
4
|
+
module ACLS
|
5
|
+
class Loader
|
6
|
+
class << self
|
7
|
+
# Use one or more paths to autoload a set of Ruby source files.
|
8
|
+
def auto(paths, opts={})
|
9
|
+
if paths.respond_to?(:each)
|
10
|
+
paths.each { |path| autoload_path(path, opts) }
|
11
|
+
else
|
12
|
+
autoload_path(paths, opts)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def get_root_ns(path, opts)
|
19
|
+
root_ns = opts[:root_ns]
|
20
|
+
root = Object
|
21
|
+
if root_ns.is_a?(TrueClass)
|
22
|
+
root = root.submodule(File.basename(path).camelize)
|
23
|
+
elsif root_ns.is_a?(String)
|
24
|
+
root_ns.split('::').each { |ns| root = root.submodule(ns) }
|
25
|
+
end
|
26
|
+
root
|
27
|
+
end
|
28
|
+
|
29
|
+
def autoload_path(path, opts)
|
30
|
+
if File.directory?(path)
|
31
|
+
root_ns = get_root_ns(path, opts)
|
32
|
+
autoload_magic(root_ns, path, opts)
|
33
|
+
else
|
34
|
+
raise Errno::ENOENT.new(path)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def autoload_magic(mod, path, opts)
|
39
|
+
# TODO: Add opts usage
|
40
|
+
Dir.entries(path).each do |entry|
|
41
|
+
next if entry[0] == '.'
|
42
|
+
full_path = "#{path}/#{entry}"
|
43
|
+
name = entry.sub(".rb", "").camelize
|
44
|
+
if File.directory?(full_path)
|
45
|
+
sub_mod = mod.submodule(name)
|
46
|
+
autoload_magic(sub_mod, full_path, opts)
|
47
|
+
else
|
48
|
+
autoload_for(mod, full_path, name)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def autoload_for(mod, path, name)
|
54
|
+
klass = guess_classname(path, name)
|
55
|
+
code = "autoload :#{klass}, \"#{path}\""
|
56
|
+
if mod.nil?
|
57
|
+
eval(code)
|
58
|
+
else
|
59
|
+
mod.module_eval(code)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def guess_classname(file, name)
|
64
|
+
process_classname_matches( scan_classnames(file), name )
|
65
|
+
end
|
66
|
+
|
67
|
+
def scan_classnames(file)
|
68
|
+
File.read(file).scan(/(class|module)\s+([^\n\r<]+)/)
|
69
|
+
end
|
70
|
+
|
71
|
+
def process_classname_matches(matches, name)
|
72
|
+
if match = best_classname_match(matches, name)
|
73
|
+
base_classname(match[1])
|
74
|
+
else
|
75
|
+
name
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def best_classname_match(matches, name)
|
80
|
+
return nil unless matches
|
81
|
+
matches.drop_while { |match| !match_classname(match[1], name) }.first
|
82
|
+
end
|
83
|
+
|
84
|
+
def match_classname(match, name)
|
85
|
+
base_classname(match).downcase == name.downcase
|
86
|
+
end
|
87
|
+
|
88
|
+
def base_classname(name)
|
89
|
+
name.split("::").last
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/module.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acls
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kolo Rahl
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.2'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.2.5
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.2'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.2.5
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.4'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 3.4.0
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '3.4'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 3.4.0
|
53
|
+
description: ACLS is a library for autoloading Ruby source files in one or more directory
|
54
|
+
trees.
|
55
|
+
email: kolorahl@gmail.com
|
56
|
+
executables: []
|
57
|
+
extensions: []
|
58
|
+
extra_rdoc_files: []
|
59
|
+
files:
|
60
|
+
- LICENSE
|
61
|
+
- README.md
|
62
|
+
- lib/acls.rb
|
63
|
+
- lib/module.rb
|
64
|
+
homepage: https://github.com/kolorahl/acls
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.4.6
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: ACLS - Automatic Code Loading System
|
88
|
+
test_files: []
|
89
|
+
has_rdoc:
|