acls 1.0.1 → 1.1.1
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 +4 -4
- data/README.md +3 -1
- data/lib/acls/loader.rb +81 -0
- data/lib/acls/parser.rb +57 -0
- data/lib/acls/tree.rb +24 -0
- data/lib/acls.rb +3 -89
- metadata +6 -4
- data/lib/module.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 575f79d69190c7e708e4e2609e216cd8db243a6d
|
4
|
+
data.tar.gz: e720eac597e838e00015ba9edb1a104b587142a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1c8381ffe8380021dfc0f430639283a994901e2fb42e2cbce5d396fedac86ed05f5cb06107ff71f8497106b2cfc01f8496c359a0bd98185388e0c14ba9cbd16
|
7
|
+
data.tar.gz: 5569fec00b72b029daec5a6f3ae49d37eb640790a2262504fe2de7e3d0e976c96f187a30c1025b96d0009dc9784e2632bbd40d0d4481f00202cf452c9a1fc076
|
data/README.md
CHANGED
@@ -90,9 +90,11 @@ Options available:
|
|
90
90
|
### Core
|
91
91
|
|
92
92
|
- [X] Generate `autoload` statements based on a set of directory paths.
|
93
|
+
- [ ] Generate static autoload file to be used for quicker application startup
|
94
|
+
in production deployments.
|
93
95
|
|
94
96
|
### Options/Configuration
|
95
97
|
|
96
98
|
- [X] Implement `root_ns`.
|
97
|
-
- [
|
99
|
+
- [X] Implement `exclude`.
|
98
100
|
- [ ] Implement `immediate`.
|
data/lib/acls/loader.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
module ACLS
|
2
|
+
class Loader
|
3
|
+
class << self
|
4
|
+
# Use one or more paths to autoload a set of Ruby source files.
|
5
|
+
def auto(paths, opts={})
|
6
|
+
trees = build_trees(paths, opts)
|
7
|
+
autoload_magic(trees, default_opts.merge(opts))
|
8
|
+
end
|
9
|
+
|
10
|
+
def default_opts
|
11
|
+
{root_ns: false, exclude: [], immediate: []}
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build_trees(paths, opts)
|
17
|
+
if paths.respond_to?(:each)
|
18
|
+
paths.map { |path| build_tree(path, opts) }
|
19
|
+
else
|
20
|
+
[build_tree(paths, opts)]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def build_tree(path, opts)
|
25
|
+
Parser.parse(path)
|
26
|
+
end
|
27
|
+
|
28
|
+
def autoload_statement(tree)
|
29
|
+
"autoload :#{tree.name}, \"#{tree.source}\""
|
30
|
+
end
|
31
|
+
|
32
|
+
def autoload_root(tree, opts)
|
33
|
+
root = Object
|
34
|
+
if opts[:root_ns].is_a?(TrueClass)
|
35
|
+
root = submodule(root, File.basename(tree.directory).camelize)
|
36
|
+
elsif opts[:root_ns].is_a?(String)
|
37
|
+
opts[:root_ns].split('::').each { |ns| root = submodule(root, ns) }
|
38
|
+
end
|
39
|
+
root
|
40
|
+
end
|
41
|
+
|
42
|
+
def autoload_magic(trees, opts)
|
43
|
+
trees.map do |tree|
|
44
|
+
root = autoload_root(tree, opts)
|
45
|
+
tree.children.map do |node|
|
46
|
+
autoload_tree(root, node, opts)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def autoload_tree(mod, tree, opts)
|
52
|
+
unless exclude?(mod, tree, opts)
|
53
|
+
if tree.source
|
54
|
+
mod.module_eval(autoload_statement(tree))
|
55
|
+
else
|
56
|
+
sub = submodule(mod, tree.name)
|
57
|
+
tree.children.map { |child| autoload_tree(sub, child, opts) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def submodule(parent, child)
|
63
|
+
parent.const_get(child, false)
|
64
|
+
rescue NameError
|
65
|
+
parent.const_set(child, Module.new)
|
66
|
+
end
|
67
|
+
|
68
|
+
def exclude?(mod, tree, opts)
|
69
|
+
opts[:exclude].each do |pattern|
|
70
|
+
if pattern.is_a?(String)
|
71
|
+
return true if pattern == tree.name
|
72
|
+
else
|
73
|
+
return true if pattern.match(tree.name)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/acls/parser.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module ACLS
|
2
|
+
class Parser
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def parse(base_dir, namespace=nil)
|
6
|
+
parse_tree(Tree.new(nil, namespace, base_dir))
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def parse_tree(parent)
|
12
|
+
Dir.entries(parent.directory).each do |entry|
|
13
|
+
next if entry[0] == '.'
|
14
|
+
full_path = "#{parent.directory}/#{entry}"
|
15
|
+
name = entry.sub(".rb", "").strip.camelize
|
16
|
+
if File.directory?(full_path)
|
17
|
+
child = parent.make_child(name, full_path)
|
18
|
+
parse_tree(child)
|
19
|
+
else
|
20
|
+
class_name = guess_classname(name, full_path)
|
21
|
+
parent.make_child(class_name, parent.directory, full_path)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
parent
|
25
|
+
end
|
26
|
+
|
27
|
+
def guess_classname(name, file)
|
28
|
+
process_classname_matches( scan_classnames(file), name )
|
29
|
+
end
|
30
|
+
|
31
|
+
def scan_classnames(file)
|
32
|
+
File.read(file).scan(/(class|module)\s+([^\n\r<]+)/)
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_classname_matches(matches, name)
|
36
|
+
if match = best_classname_match(matches, name)
|
37
|
+
base_classname(match[1])
|
38
|
+
else
|
39
|
+
name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def best_classname_match(matches, name)
|
44
|
+
return nil unless matches
|
45
|
+
matches.drop_while { |match| !match_classname(match[1], name) }.first
|
46
|
+
end
|
47
|
+
|
48
|
+
def match_classname(match, name)
|
49
|
+
base_classname(match).downcase == name.downcase
|
50
|
+
end
|
51
|
+
|
52
|
+
def base_classname(name)
|
53
|
+
name.split("::").last.strip
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/acls/tree.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module ACLS
|
2
|
+
class Tree
|
3
|
+
attr_accessor :name, :directory, :source, :parent, :children
|
4
|
+
|
5
|
+
def initialize(parent, name, directory, source=nil)
|
6
|
+
@parent = parent
|
7
|
+
@name = name
|
8
|
+
@directory = directory
|
9
|
+
@source = source
|
10
|
+
@children = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def make_child(name, directory, source=nil)
|
14
|
+
child = Tree.new(self, name, directory, source)
|
15
|
+
@children << child
|
16
|
+
child
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"name: #{@name}, source: #{@source}, directory: #{@directory}, parent: #{@parent}, children: #{@children.length}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/lib/acls.rb
CHANGED
@@ -1,93 +1,7 @@
|
|
1
1
|
require 'active_support/inflector'
|
2
|
-
require_relative './module'
|
3
2
|
|
4
3
|
module ACLS
|
5
|
-
|
6
|
-
|
7
|
-
|
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", "").strip.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.strip
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
4
|
+
require_relative './acls/loader'
|
5
|
+
require_relative './acls/parser'
|
6
|
+
require_relative './acls/tree'
|
93
7
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kolo Rahl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -60,7 +60,9 @@ files:
|
|
60
60
|
- LICENSE
|
61
61
|
- README.md
|
62
62
|
- lib/acls.rb
|
63
|
-
- lib/
|
63
|
+
- lib/acls/loader.rb
|
64
|
+
- lib/acls/parser.rb
|
65
|
+
- lib/acls/tree.rb
|
64
66
|
homepage: https://github.com/kolorahl/acls
|
65
67
|
licenses:
|
66
68
|
- MIT
|
@@ -81,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
83
|
version: '0'
|
82
84
|
requirements: []
|
83
85
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.
|
86
|
+
rubygems_version: 2.5.1
|
85
87
|
signing_key:
|
86
88
|
specification_version: 4
|
87
89
|
summary: ACLS - Automatic Code Loading System
|