lowload 0.5.0 → 0.6.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 +4 -4
- data/lib/adapters/adapter.rb +16 -0
- data/lib/adapters/markdown_adapter.rb +27 -0
- data/lib/adapters/rbx_adapter.rb +80 -0
- data/lib/adapters/ruby_adapter.rb +28 -0
- data/lib/lowload.rb +25 -73
- data/lib/metadata.rb +51 -0
- data/lib/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 47cc7e9bc1bf7d856e12c1a91d6cd4ab388a973d73bb8fb7d2a8498ea3631cf4
|
|
4
|
+
data.tar.gz: '04864e7a3f9ab0644ebf3356095369859eb025f19087892f3c86b5b54bba35ed'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 81e0d64d2f3ab72619663d2f6649c8affe284fe106989aad6c98dd5d7d760b5407f28171af96447c241c55e86cd444fef9f7702b748a35bab1dfa77c408c2497
|
|
7
|
+
data.tar.gz: fed385baed2a6d64c26051f34d42e24d022a78823cbd128790c4cfa90e82b32a07576edb475e3c89c2942dc9950b267d2311b8fa718b81247bd5e063dfda5e80
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'yaml'
|
|
4
|
+
require 'lowkey'
|
|
5
|
+
require_relative 'adapter'
|
|
6
|
+
|
|
7
|
+
module LowLoad
|
|
8
|
+
class MarkdownAdapter < Adapter
|
|
9
|
+
EXTENSIONS = ['md', 'rd', 'markdown', 'raindown']
|
|
10
|
+
|
|
11
|
+
def metadata(file_path:)
|
|
12
|
+
meta_lines = []
|
|
13
|
+
yaml_lines = []
|
|
14
|
+
|
|
15
|
+
File.foreach(file_path).with_index do |line, index|
|
|
16
|
+
if line.strip == '---'
|
|
17
|
+
meta_lines << index + 1
|
|
18
|
+
break if meta_lines.count > 1
|
|
19
|
+
else
|
|
20
|
+
yaml_lines << line
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
YAML.safe_load(yaml_lines.join, symbolize_names: true)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'lowkey'
|
|
4
|
+
require_relative 'adapter'
|
|
5
|
+
require_relative '../loader'
|
|
6
|
+
|
|
7
|
+
def top_level_binding
|
|
8
|
+
binding
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module LowLoad
|
|
12
|
+
class RBXAdapter < Adapter
|
|
13
|
+
EXTENSIONS = ['rbx']
|
|
14
|
+
|
|
15
|
+
# Map all definitions and dependencies.
|
|
16
|
+
def metadata(file_path:)
|
|
17
|
+
Lowkey.load(file_path)
|
|
18
|
+
|
|
19
|
+
{ file_path: }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Then autoload all dependencies for those files.
|
|
23
|
+
def preload(file_path:)
|
|
24
|
+
Loader.add_autoloads(file_proxy: Lowkey[file_path])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Now we can load the file into Ruby.
|
|
28
|
+
def evaluate(file_path:)
|
|
29
|
+
# 1. "File Load" phase.
|
|
30
|
+
file_proxy = Lowkey[file_path] || Lowkey.load(file_path)
|
|
31
|
+
templates = wrap_render_methods(file_proxy:)
|
|
32
|
+
|
|
33
|
+
# 2. "Class Load" phase.
|
|
34
|
+
# Not a security risk because "eval" is equivalent to "load" or "require_relative" in this context.
|
|
35
|
+
eval(file_proxy.export, top_level_binding, file_proxy.file_path, 0) # rubocop:disable Security/Eval
|
|
36
|
+
|
|
37
|
+
# 3. "Runtime" phase (before low nodes are rendered).
|
|
38
|
+
# Templates only exist if antlers gem has been required by another gem (such as LowNode) and the template contains antlers syntax.
|
|
39
|
+
templates.each do |namespace, method_template|
|
|
40
|
+
klass = Object.const_get(namespace)
|
|
41
|
+
method, template = method_template
|
|
42
|
+
# TODO: If params contain "**props" or similar then send that, so that LowNode can replicate it.
|
|
43
|
+
params = method.params.map(&:name)
|
|
44
|
+
|
|
45
|
+
next unless supports_templates?(klass) || raise(UnsupportedTemplate, "Template for '#{namespace}' identified but not implemented")
|
|
46
|
+
|
|
47
|
+
# TODO: Make template engine configurable.
|
|
48
|
+
klass.build_template(template:, params:, engine: Antlers, namespace:)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def supports_templates?(klass)
|
|
55
|
+
klass.respond_to?(:render) && klass.respond_to?(:template) && klass.respond_to?(:build_template)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def wrap_render_methods(file_proxy:)
|
|
59
|
+
# GOAL: Templates could be organised by method and template rendering engine.
|
|
60
|
+
templates = {}
|
|
61
|
+
|
|
62
|
+
file_proxy.definitions.each_value do |class_proxy|
|
|
63
|
+
render_method = class_proxy.respond_to?(:instance_methods) ? class_proxy.instance_methods[:render] : nil
|
|
64
|
+
|
|
65
|
+
next unless render_method
|
|
66
|
+
|
|
67
|
+
render_method_body = render_method.body.export
|
|
68
|
+
|
|
69
|
+
if defined?(Antlers) && ['{', '<{'].any? { |needle| render_method_body.include?(needle) }
|
|
70
|
+
templates[class_proxy.namespace] = [render_method, render_method_body]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Intended to target HTML or Antlers tags. Use HEREDOC "<<~" in a plain Ruby (".rb") file, not RBX.
|
|
74
|
+
render_method.body.wrap(prefix: '%q{', suffix: '}') if render_method_body.strip.start_with?('<')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
templates
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'lowkey'
|
|
4
|
+
require_relative 'adapter'
|
|
5
|
+
require_relative '../loader'
|
|
6
|
+
|
|
7
|
+
module LowLoad
|
|
8
|
+
class RubyAdapter < Adapter
|
|
9
|
+
EXTENSIONS = ['rb']
|
|
10
|
+
|
|
11
|
+
# Map all definitions and dependencies.
|
|
12
|
+
def metadata(file_path:)
|
|
13
|
+
Lowkey.load(file_path)
|
|
14
|
+
|
|
15
|
+
{ file_path: }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Then autoload all dependencies for those files.
|
|
19
|
+
def preload(file_path:)
|
|
20
|
+
Loader.add_autoloads(file_proxy: Lowkey[file_path])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Now we can load the file into Ruby.
|
|
24
|
+
def evaluate(file_path:)
|
|
25
|
+
load(file_path)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/lowload.rb
CHANGED
|
@@ -1,99 +1,51 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
require_relative 'adapters/markdown_adapter'
|
|
4
|
+
require_relative 'adapters/rbx_adapter'
|
|
5
|
+
require_relative 'adapters/ruby_adapter'
|
|
6
6
|
require_relative 'loader'
|
|
7
|
-
|
|
8
|
-
def top_level_binding
|
|
9
|
-
binding
|
|
10
|
-
end
|
|
7
|
+
require_relative 'metadata'
|
|
11
8
|
|
|
12
9
|
module LowLoad
|
|
10
|
+
class UnsupportedFileType < StandardError; end
|
|
13
11
|
class UnsupportedTemplate < StandardError; end
|
|
14
12
|
|
|
15
13
|
class << self
|
|
16
|
-
|
|
14
|
+
ADAPTERS = [MarkdownAdapter.new, RBXAdapter.new, RubyAdapter.new]
|
|
15
|
+
|
|
17
16
|
def dirload(path, pwd = Dir.pwd)
|
|
18
17
|
absolute_path = File.expand_path(path, pwd)
|
|
19
|
-
file_paths = Dir["#{absolute_path}/**/*"]
|
|
18
|
+
file_paths = Dir["#{absolute_path}/**/*"].filter { !File.directory?(it) }
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Lowkey.load(file_path)
|
|
20
|
+
file_path_adapters = file_paths.each_with_object({}) do |file_path, hash|
|
|
21
|
+
hash[file_path] = find_adapter(file_path:)
|
|
24
22
|
end
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
metadata = Metadata.new
|
|
25
|
+
metadata.process(file_path_adapters:)
|
|
26
|
+
step(:preload, file_path_adapters:)
|
|
27
|
+
step(:evaluate, file_path_adapters:)
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
file_paths.each do |file_path| # rubocop:disable Style/CombinableLoops
|
|
33
|
-
lowload(file_path)
|
|
34
|
-
end
|
|
29
|
+
metadata
|
|
35
30
|
end
|
|
36
31
|
|
|
37
|
-
# Dependencies must first be loaded by dirload() or required by the file.
|
|
38
32
|
def lowload(file_path)
|
|
39
|
-
|
|
40
|
-
when 'rb'
|
|
41
|
-
load(file_path)
|
|
42
|
-
when 'rbx'
|
|
43
|
-
load_rbx(file_path)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
def load_rbx(file_path)
|
|
50
|
-
# 1. "File Load" phase.
|
|
51
|
-
file_proxy = Lowkey[file_path] || Lowkey.load(file_path)
|
|
52
|
-
templates = wrap_render_methods(file_proxy:)
|
|
53
|
-
|
|
54
|
-
# 2. "Class Load" phase.
|
|
55
|
-
# Not a security risk because "eval" is equivalent to "load" or "require_relative" in this context.
|
|
56
|
-
eval(file_proxy.export, top_level_binding, file_proxy.file_path, 0) # rubocop:disable Security/Eval
|
|
33
|
+
adapter = find_adapter(file_path:)
|
|
57
34
|
|
|
58
|
-
|
|
59
|
-
# Templates only exist if antlers gem has been required by another gem (such as LowNode) and the template contains antlers syntax.
|
|
60
|
-
templates.each do |namespace, method_template|
|
|
61
|
-
klass = const_get(namespace)
|
|
62
|
-
method, template = method_template
|
|
63
|
-
# TODO: If params contain "**props" or similar then send that, so that LowNode can replicate it.
|
|
64
|
-
params = method.params.map(&:name)
|
|
35
|
+
raise(UnsupportedFileType, "Could not load #{file_path}") if adapter.nil?
|
|
65
36
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
# TODO: Make template engine configurable.
|
|
69
|
-
klass.build_template(template:, params:, engine: Antlers, namespace:)
|
|
70
|
-
end
|
|
37
|
+
adapter.evaluate(file_path:)
|
|
71
38
|
end
|
|
72
39
|
|
|
73
|
-
def
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def wrap_render_methods(file_proxy:)
|
|
78
|
-
# GOAL: Templates could be organised by method and template rendering engine.
|
|
79
|
-
templates = {}
|
|
80
|
-
|
|
81
|
-
file_proxy.definitions.each_value do |class_proxy|
|
|
82
|
-
render_method = class_proxy.respond_to?(:instance_methods) ? class_proxy.instance_methods[:render] : nil
|
|
83
|
-
|
|
84
|
-
next unless render_method
|
|
85
|
-
|
|
86
|
-
render_method_body = render_method.body.export
|
|
87
|
-
|
|
88
|
-
if defined?(Antlers) && ['{', '<{'].any? { |needle| render_method_body.include?(needle) }
|
|
89
|
-
templates[class_proxy.namespace] = [render_method, render_method_body]
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Intended to target HTML or Antlers tags. Use HEREDOC "<<~" in a plain Ruby (".rb") file, not RBX.
|
|
93
|
-
render_method.body.wrap(prefix: '%q{', suffix: '}') if render_method_body.strip.start_with?('<')
|
|
40
|
+
def step(step, file_path_adapters:)
|
|
41
|
+
file_path_adapters.each do |file_path, adapter|
|
|
42
|
+
adapter&.send(step, file_path:)
|
|
94
43
|
end
|
|
44
|
+
end
|
|
95
45
|
|
|
96
|
-
|
|
46
|
+
def find_adapter(file_path:)
|
|
47
|
+
extension = File.extname(file_path).delete_prefix('.')
|
|
48
|
+
ADAPTERS.find { |adapter| adapter.class::EXTENSIONS.include?(extension) }
|
|
97
49
|
end
|
|
98
50
|
end
|
|
99
51
|
end
|
data/lib/metadata.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'adapters/markdown_adapter'
|
|
4
|
+
|
|
5
|
+
module LowLoad
|
|
6
|
+
class Metadata
|
|
7
|
+
EXTENSIONS = [
|
|
8
|
+
*::LowLoad::MarkdownAdapter::EXTENSIONS,
|
|
9
|
+
*::LowLoad::RBXAdapter::EXTENSIONS,
|
|
10
|
+
*::LowLoad::RubyAdapter::EXTENSIONS,
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
attr_accessor :file_paths, :file_types, :tags
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@file_paths = []
|
|
17
|
+
|
|
18
|
+
@file_types = EXTENSIONS.each_with_object({}) do |extension, hash|
|
|
19
|
+
hash[extension] = []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@tags = {}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def process(file_path_adapters:)
|
|
26
|
+
file_path_adapters.each do |file_path, adapter|
|
|
27
|
+
if (metadata = adapter&.metadata(file_path:))
|
|
28
|
+
metadata.merge!({
|
|
29
|
+
file_path:,
|
|
30
|
+
file_type: File.extname(file_path).delete_prefix('.'),
|
|
31
|
+
file_loaded: true,
|
|
32
|
+
})
|
|
33
|
+
else
|
|
34
|
+
metadata = { file_loaded: false }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
append(metadata:)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def append(metadata:)
|
|
42
|
+
@file_paths << metadata[:file_path]
|
|
43
|
+
@file_types[metadata[:file_type]] = metadata[:file_path]
|
|
44
|
+
|
|
45
|
+
metadata[:tags]&.each do |tag|
|
|
46
|
+
@tags[tag] ||= []
|
|
47
|
+
@tags[tag] = metadata[:file_path]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lowload
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- maedi
|
|
@@ -31,8 +31,13 @@ executables: []
|
|
|
31
31
|
extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
|
33
33
|
files:
|
|
34
|
+
- lib/adapters/adapter.rb
|
|
35
|
+
- lib/adapters/markdown_adapter.rb
|
|
36
|
+
- lib/adapters/rbx_adapter.rb
|
|
37
|
+
- lib/adapters/ruby_adapter.rb
|
|
34
38
|
- lib/loader.rb
|
|
35
39
|
- lib/lowload.rb
|
|
40
|
+
- lib/metadata.rb
|
|
36
41
|
- lib/version.rb
|
|
37
42
|
homepage: https://github.com/low-rb/lowload
|
|
38
43
|
licenses: []
|
|
@@ -53,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
53
58
|
- !ruby/object:Gem::Version
|
|
54
59
|
version: '0'
|
|
55
60
|
requirements: []
|
|
56
|
-
rubygems_version: 4.0.
|
|
61
|
+
rubygems_version: 4.0.6
|
|
57
62
|
specification_version: 4
|
|
58
63
|
summary: An autoloader without namespace and folder structure conventions
|
|
59
64
|
test_files: []
|