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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e7b50a3b290ad7e38bb6339dfc30e7ab101b9ae
4
- data.tar.gz: c1e855d4b933d225f1bc248f20ccb734c55f6fea
3
+ metadata.gz: 575f79d69190c7e708e4e2609e216cd8db243a6d
4
+ data.tar.gz: e720eac597e838e00015ba9edb1a104b587142a1
5
5
  SHA512:
6
- metadata.gz: 7bce9645be07a02e44b706ecb0fcc2ecb0350eccae53c985c0c91cd2f3f8fd5a91567e6b144c272c866deab902ef1cec9e2d94d4df0058776fa1e762ab517982
7
- data.tar.gz: c434e2c8fe8b62baea16a6144d473caa509614872283bdaaea8a3442a6c3fcaa340f45766d398d5b829b95a01445ca50534d962a66a12204d6b922fb63016c36
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
- - [ ] Implement `exclude`.
99
+ - [X] Implement `exclude`.
98
100
  - [ ] Implement `immediate`.
@@ -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
@@ -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
- 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", "").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.0.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: 2015-12-18 00:00:00.000000000 Z
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/module.rb
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.4.6
86
+ rubygems_version: 2.5.1
85
87
  signing_key:
86
88
  specification_version: 4
87
89
  summary: ACLS - Automatic Code Loading System
data/lib/module.rb DELETED
@@ -1,9 +0,0 @@
1
- code = <<EOS
2
- def submodule(name)
3
- const_get(name, false)
4
- rescue NameError
5
- const_set(name, Module.new)
6
- end
7
- EOS
8
-
9
- Module.module_eval(code)