klenod-build 0.0.4 → 0.0.5
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 -0
- data/lib/klenod/build/cli/application.rb +7 -1
- data/lib/klenod/build/errors.rb +0 -1
- data/lib/klenod/build/graphviz.rb +95 -24
- data/lib/klenod/build/plugins.rb +0 -1
- data/lib/klenod/build/version.rb +1 -1
- data/lib/klenod/build.rb +0 -2
- metadata +3 -5
- data/lib/klenod/build/plugins/test_plugin.rb +0 -49
- data/lib/klenod/build/test_suite.rb +0 -94
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f7515626d279801c2dfb15f6b0ff7d00b358c4dc20549f21b60730f1ef1307cf
|
|
4
|
+
data.tar.gz: ea285ea5d5d59188defafb4eced0c96ff316fbb67bd2d1cf0de7728f41cda927
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7480460dfbedd0e793ceed82b3142d6ea5750f9c11e6752193745248643c53ff8a804cd1c855b4ffb171c8cdd1872a7aae9e66f15b417f8bc5f15d3d3baa8da6
|
|
7
|
+
data.tar.gz: 743b1821300848721a9208b1e6f59fc2736dc89d99f6e9ff24bb01346e9701645c2c88dc75daf83424f6a1e6ad758f98db7877fbccac2a0670cbf3630f26b19f
|
data/README.md
CHANGED
|
@@ -27,3 +27,6 @@ The CLI can also generate a [Graphviz](https://graphviz.org/) DOT-file from a ge
|
|
|
27
27
|
```sh
|
|
28
28
|
bundle exec klenod graph dist/klenod.bundle > graph.dot
|
|
29
29
|
```
|
|
30
|
+
|
|
31
|
+
Klenod's internal virtual modules are hidden by default. Pass
|
|
32
|
+
`--internal-virtual-modules` to include them in the graph.
|
|
@@ -68,13 +68,19 @@ module Klenod
|
|
|
68
68
|
|
|
69
69
|
options do
|
|
70
70
|
option "--no-assets", "Hide generated asset nodes and edges."
|
|
71
|
+
option "--internal-virtual-modules", "Include Klenod's internal virtual modules."
|
|
71
72
|
end
|
|
72
73
|
|
|
73
74
|
one :bundle_path, "Path to a Klenod runtime bundle.", required: true
|
|
74
75
|
|
|
75
76
|
def call
|
|
76
77
|
bundle = Klenod::Runtime.load_bundle(@bundle_path)
|
|
77
|
-
dot =
|
|
78
|
+
dot =
|
|
79
|
+
Klenod::Build::Graphviz.call(
|
|
80
|
+
bundle,
|
|
81
|
+
include_assets: !@options[:no_assets],
|
|
82
|
+
include_internal_virtual_modules: @options[:internal_virtual_modules]
|
|
83
|
+
)
|
|
78
84
|
output.write(dot)
|
|
79
85
|
dot
|
|
80
86
|
end
|
data/lib/klenod/build/errors.rb
CHANGED
|
@@ -19,13 +19,18 @@ module Klenod
|
|
|
19
19
|
ASSET_STYLE = {fillcolor: "#ffe4d6", color: "#e26d39"}.freeze
|
|
20
20
|
DEFAULT_MODULE_STYLE = {fillcolor: "#f7f7f7", color: "#8a8a8a"}.freeze
|
|
21
21
|
|
|
22
|
-
def self.call(bundle, include_assets: true)
|
|
23
|
-
new(
|
|
22
|
+
def self.call(bundle, include_assets: true, include_internal_virtual_modules: false)
|
|
23
|
+
new(
|
|
24
|
+
bundle,
|
|
25
|
+
include_assets: include_assets,
|
|
26
|
+
include_internal_virtual_modules: include_internal_virtual_modules
|
|
27
|
+
).to_dot
|
|
24
28
|
end
|
|
25
29
|
|
|
26
|
-
def initialize(bundle, include_assets: true)
|
|
30
|
+
def initialize(bundle, include_assets: true, include_internal_virtual_modules: false)
|
|
27
31
|
@bundle = bundle
|
|
28
32
|
@include_assets = include_assets
|
|
33
|
+
@include_internal_virtual_modules = include_internal_virtual_modules
|
|
29
34
|
end
|
|
30
35
|
|
|
31
36
|
def to_dot
|
|
@@ -46,8 +51,15 @@ module Klenod
|
|
|
46
51
|
|
|
47
52
|
private
|
|
48
53
|
|
|
54
|
+
def all_module_ids
|
|
55
|
+
@all_module_ids ||= @bundle.modules.keys.sort
|
|
56
|
+
end
|
|
57
|
+
|
|
49
58
|
def module_ids
|
|
50
|
-
@
|
|
59
|
+
@module_ids ||=
|
|
60
|
+
all_module_ids.reject do |id|
|
|
61
|
+
internal_virtual_module?(id) && !entrypoint?(id) && !@include_internal_virtual_modules
|
|
62
|
+
end
|
|
51
63
|
end
|
|
52
64
|
|
|
53
65
|
def module_node(id)
|
|
@@ -75,7 +87,7 @@ module Klenod
|
|
|
75
87
|
module_ids.flat_map do |id|
|
|
76
88
|
@bundle.modules.fetch(id).imports.values.map do |import|
|
|
77
89
|
import = import_spec(import)
|
|
78
|
-
next unless
|
|
90
|
+
next unless visible_module?(import.target_id)
|
|
79
91
|
|
|
80
92
|
attributes = {
|
|
81
93
|
id: svg_edge_id(id, import.target_id),
|
|
@@ -91,25 +103,71 @@ module Klenod
|
|
|
91
103
|
end
|
|
92
104
|
|
|
93
105
|
def asset_edges
|
|
94
|
-
@bundle.assets.values.sort_by(&:output_path).
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
" #{owner_node_id(owner)} -> #{asset_node_id(asset)} [#{dot_attributes(attributes)}];"
|
|
106
|
+
@bundle.assets.values.sort_by(&:output_path).flat_map do |asset|
|
|
107
|
+
asset_owners(asset).map do |owner|
|
|
108
|
+
attributes = {
|
|
109
|
+
id: svg_edge_id(owner_node_name(owner), asset.output_path),
|
|
110
|
+
class: "edge edge-asset",
|
|
111
|
+
color: "#e26d39",
|
|
112
|
+
style: "dotted",
|
|
113
|
+
label: "asset"
|
|
114
|
+
}
|
|
115
|
+
" #{owner_node_id(owner)} -> #{asset_node_id(asset)} [#{dot_attributes(attributes)}];"
|
|
116
|
+
end
|
|
106
117
|
end
|
|
107
118
|
end
|
|
108
119
|
|
|
109
|
-
def
|
|
110
|
-
|
|
120
|
+
def asset_owners(asset)
|
|
121
|
+
module_id = module_id_for_asset(asset.logical_name)
|
|
122
|
+
return visible_module_owners(module_id) if module_id
|
|
111
123
|
|
|
112
|
-
google_fonts_css_asset_owner(asset)
|
|
124
|
+
[google_fonts_css_asset_owner(asset), *asset_metadata_owners(asset)].compact
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def visible_module_owners(module_id)
|
|
128
|
+
pending = [module_id]
|
|
129
|
+
seen = Set.new
|
|
130
|
+
owners = []
|
|
131
|
+
|
|
132
|
+
until pending.empty?
|
|
133
|
+
current_id = pending.shift
|
|
134
|
+
next unless seen.add?(current_id)
|
|
135
|
+
|
|
136
|
+
if visible_module?(current_id)
|
|
137
|
+
owners << [:module, current_id]
|
|
138
|
+
else
|
|
139
|
+
pending.concat(module_importers.fetch(current_id, []))
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
owners
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def module_importers
|
|
147
|
+
@module_importers ||=
|
|
148
|
+
all_module_ids.each_with_object(Hash.new { |index, id| index[id] = [] }) do |id, index|
|
|
149
|
+
@bundle.modules.fetch(id).imports.each_value do |import|
|
|
150
|
+
target_id = import_spec(import).target_id
|
|
151
|
+
index[target_id] << id if @bundle.modules.key?(target_id)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def module_id_for_asset(logical_name)
|
|
157
|
+
return logical_name if @bundle.modules.key?(logical_name)
|
|
158
|
+
|
|
159
|
+
module_ids_by_source_path.fetch(logical_name, nil) || query_module_ids_by_path.fetch(logical_name, nil)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def module_ids_by_source_path
|
|
163
|
+
@module_ids_by_source_path ||=
|
|
164
|
+
all_module_ids.each_with_object({}) do |id, index|
|
|
165
|
+
source_path = @bundle.modules.fetch(id).source_path
|
|
166
|
+
next unless source_path
|
|
167
|
+
|
|
168
|
+
index[source_path] ||= id
|
|
169
|
+
index[display_path(source_path)] ||= id
|
|
170
|
+
end
|
|
113
171
|
end
|
|
114
172
|
|
|
115
173
|
def google_fonts_css_asset_owner(asset)
|
|
@@ -127,14 +185,18 @@ module Klenod
|
|
|
127
185
|
asset.metadata[:source_url]
|
|
128
186
|
end
|
|
129
187
|
|
|
130
|
-
def
|
|
131
|
-
|
|
132
|
-
|
|
188
|
+
def asset_metadata_owners(asset)
|
|
189
|
+
return [] unless asset.metadata[:javascript_runtime] == :asset_metadata
|
|
190
|
+
|
|
191
|
+
@bundle.assets.values
|
|
192
|
+
.select { it.metadata[:image_metadata] || it.metadata[:svg_metadata] }
|
|
193
|
+
.sort_by(&:output_path)
|
|
194
|
+
.map { [:asset, it] }
|
|
133
195
|
end
|
|
134
196
|
|
|
135
197
|
def query_module_ids_by_path
|
|
136
198
|
@query_module_ids_by_path ||=
|
|
137
|
-
|
|
199
|
+
all_module_ids.each_with_object({}) do |id, index|
|
|
138
200
|
path, query = id.split("?", 2)
|
|
139
201
|
next unless query
|
|
140
202
|
|
|
@@ -218,6 +280,15 @@ module Klenod
|
|
|
218
280
|
["edge", import.eager ? "edge-import" : "edge-import edge-lazy"].join(" ")
|
|
219
281
|
end
|
|
220
282
|
|
|
283
|
+
def internal_virtual_module?(id)
|
|
284
|
+
id.start_with?("virtual:/klenod/", "virtual:klenod/")
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def visible_module?(id)
|
|
288
|
+
@visible_module_ids ||= module_ids.to_set
|
|
289
|
+
@visible_module_ids.include?(id)
|
|
290
|
+
end
|
|
291
|
+
|
|
221
292
|
def entrypoint?(id)
|
|
222
293
|
entrypoint_ids.include?(id)
|
|
223
294
|
end
|
data/lib/klenod/build/plugins.rb
CHANGED
|
@@ -17,7 +17,6 @@ module Klenod
|
|
|
17
17
|
autoload :TomlPlugin, File.expand_path("plugins/data_plugin", __dir__)
|
|
18
18
|
autoload :TextPlugin, File.expand_path("plugins/data_plugin", __dir__)
|
|
19
19
|
autoload :RouterPlugin, File.expand_path("plugins/router_plugin", __dir__)
|
|
20
|
-
autoload :TestPlugin, File.expand_path("plugins/test_plugin", __dir__)
|
|
21
20
|
end
|
|
22
21
|
end
|
|
23
22
|
end
|
data/lib/klenod/build/version.rb
CHANGED
data/lib/klenod/build.rb
CHANGED
|
@@ -9,8 +9,6 @@ module Klenod
|
|
|
9
9
|
|
|
10
10
|
module Build
|
|
11
11
|
autoload :Graphviz, "klenod/build/graphviz"
|
|
12
|
-
autoload :TestSelection, "klenod/build/test_suite"
|
|
13
|
-
autoload :TestSuite, "klenod/build/test_suite"
|
|
14
12
|
autoload :UpdateEvent, "klenod/build/watcher"
|
|
15
13
|
autoload :Watcher, "klenod/build/watcher"
|
|
16
14
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: klenod-build
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrés Alin
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.0.
|
|
18
|
+
version: 0.0.5
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.0.
|
|
25
|
+
version: 0.0.5
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: async
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -272,7 +272,6 @@ files:
|
|
|
272
272
|
- lib/klenod/build/plugins/router_plugin.rb
|
|
273
273
|
- lib/klenod/build/plugins/ruby_plugin.rb
|
|
274
274
|
- lib/klenod/build/plugins/svg_plugin.rb
|
|
275
|
-
- lib/klenod/build/plugins/test_plugin.rb
|
|
276
275
|
- lib/klenod/build/profiler.rb
|
|
277
276
|
- lib/klenod/build/resolution_error_formatter.rb
|
|
278
277
|
- lib/klenod/build/resolver.rb
|
|
@@ -281,7 +280,6 @@ files:
|
|
|
281
280
|
- lib/klenod/build/source_map/editor.rb
|
|
282
281
|
- lib/klenod/build/source_map/map.rb
|
|
283
282
|
- lib/klenod/build/source_map/vlq.rb
|
|
284
|
-
- lib/klenod/build/test_suite.rb
|
|
285
283
|
- lib/klenod/build/transform_result.rb
|
|
286
284
|
- lib/klenod/build/version.rb
|
|
287
285
|
- lib/klenod/build/watched_pattern.rb
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../errors"
|
|
4
|
-
require_relative "../module_id"
|
|
5
|
-
require_relative "../plugin"
|
|
6
|
-
|
|
7
|
-
module Klenod
|
|
8
|
-
module Build
|
|
9
|
-
module Plugins
|
|
10
|
-
module TestPlugin
|
|
11
|
-
def self.new(...)
|
|
12
|
-
Plugin.new(...)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
class Plugin < Klenod::Build::Plugin
|
|
16
|
-
DEFAULT_PATTERN = "**/*.test.rb"
|
|
17
|
-
|
|
18
|
-
def initialize(pattern: DEFAULT_PATTERN)
|
|
19
|
-
@pattern = pattern.to_s
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
attr_reader :pattern
|
|
23
|
-
|
|
24
|
-
def discover(source_dir:)
|
|
25
|
-
root = Pathname.new(source_dir).expand_path
|
|
26
|
-
|
|
27
|
-
root
|
|
28
|
-
.glob(pattern)
|
|
29
|
-
.select(&:file?)
|
|
30
|
-
.map { |path| ModuleId.new(path.relative_path_from(root).to_s.tr("\\", "/"), nil) }
|
|
31
|
-
.sort_by(&:to_s)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def test_module_id?(module_id)
|
|
35
|
-
module_id.scheme == :app && File.fnmatch?(pattern, module_id.relative_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def finalize(module_id, result, resolved_dependencies, _dependency_records, _context)
|
|
39
|
-
imported_test = resolved_dependencies.find { |dependency| test_module_id?(dependency.module_id) }
|
|
40
|
-
return result unless imported_test
|
|
41
|
-
|
|
42
|
-
error = TestImportError.new("Test file #{imported_test.module_id.path.inspect} cannot be imported")
|
|
43
|
-
raise error.with_resolution_context(dependency: imported_test.dependency, importer_id: module_id)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Klenod
|
|
4
|
-
module Build
|
|
5
|
-
TestSelection = Data.define(:test_paths, :removed_test_paths) do
|
|
6
|
-
def empty?
|
|
7
|
-
test_paths.empty? && removed_test_paths.empty?
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
class TestSuite
|
|
12
|
-
def initialize(context:, plugin:)
|
|
13
|
-
@context = context
|
|
14
|
-
@plugin = plugin
|
|
15
|
-
@dependency_ids = {}
|
|
16
|
-
@failed_test_ids = Set.new
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def collect
|
|
20
|
-
test_ids = discover
|
|
21
|
-
test_ids.each { |test_id| index(test_id) }
|
|
22
|
-
selection(test_ids)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def update(event)
|
|
26
|
-
previous_test_ids = @dependency_ids.keys.to_set
|
|
27
|
-
current_test_ids = discover.to_set
|
|
28
|
-
removed_test_ids = previous_test_ids - current_test_ids
|
|
29
|
-
added_test_ids = current_test_ids - previous_test_ids
|
|
30
|
-
affected_module_ids = update_module_ids(event)
|
|
31
|
-
affected_test_ids =
|
|
32
|
-
@dependency_ids.filter_map do |test_id, dependency_ids|
|
|
33
|
-
test_id if current_test_ids.include?(test_id) && dependency_ids.intersect?(affected_module_ids)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
test_ids = (added_test_ids + affected_test_ids + @failed_test_ids).select { |test_id| current_test_ids.include?(test_id) }
|
|
37
|
-
removed_test_ids.each { |test_id| remove(test_id) }
|
|
38
|
-
test_ids.each { |test_id| index(test_id) }
|
|
39
|
-
|
|
40
|
-
selection(test_ids, removed_test_ids)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
attr_reader :context, :plugin
|
|
46
|
-
|
|
47
|
-
def discover
|
|
48
|
-
plugin.discover(source_dir: context.graph.source_dir)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def index(test_id)
|
|
52
|
-
dependency_ids = Set[test_id]
|
|
53
|
-
@dependency_ids[test_id] = dependency_ids
|
|
54
|
-
collect_dependencies(test_id, dependency_ids)
|
|
55
|
-
@failed_test_ids.delete(test_id)
|
|
56
|
-
rescue
|
|
57
|
-
@failed_test_ids << test_id
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def collect_dependencies(module_id, dependency_ids)
|
|
61
|
-
record = context.graph.records[module_id] || context.graph.collect_module(module_id)
|
|
62
|
-
|
|
63
|
-
record.resolved_dependencies.each do |dependency|
|
|
64
|
-
dependency_id = dependency.module_id
|
|
65
|
-
next unless dependency_ids.add?(dependency_id)
|
|
66
|
-
|
|
67
|
-
collect_dependencies(dependency_id, dependency_ids)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def remove(test_id)
|
|
72
|
-
@dependency_ids.delete(test_id)
|
|
73
|
-
@failed_test_ids.delete(test_id)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def update_module_ids(event)
|
|
77
|
-
result = event.result
|
|
78
|
-
Set.new(
|
|
79
|
-
result.changed_module_ids +
|
|
80
|
-
result.removed_module_ids +
|
|
81
|
-
result.reloaded_module_ids +
|
|
82
|
-
result.reevaluated_module_ids
|
|
83
|
-
)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def selection(test_ids, removed_test_ids = [])
|
|
87
|
-
TestSelection.new(
|
|
88
|
-
test_ids.map(&:relative_path).sort.freeze,
|
|
89
|
-
removed_test_ids.map(&:relative_path).sort.freeze
|
|
90
|
-
)
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|