hub_kernel 0.9.0 → 0.10.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/README.md +30 -0
- data/lib/hub_kernel/conformance/crossings.rb +28 -0
- data/lib/hub_kernel/crossings.rb +40 -0
- data/lib/hub_kernel/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 269ad669e7c014af9175190d416dbf7be82bfb8d797eb3a25107bf87b99b1344
|
|
4
|
+
data.tar.gz: 808639ddaca46f8d8cbe9f187a7d59ae9d50b704f773bf4f255bae731d4339a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3c94024970cd0ae83bf695824439a959b6b03061eb39f92268f483ca769fbf323d4210710f805f052028590e65b87a84b43b8801cac1a9b927a9402205f1fd55
|
|
7
|
+
data.tar.gz: 307661997442f598ee6d2e931540336986a567794113298d496864f86d3ac19e2788ee091e75b8bc9434bd1c61bd3aa1df095b71af29d2479b7898869dfd416b
|
data/README.md
CHANGED
|
@@ -134,6 +134,36 @@ end
|
|
|
134
134
|
The test fails and names each problem. A method that takes `**` values accepts any
|
|
135
135
|
values it is listed with, as long as it is listed with each value it requires.
|
|
136
136
|
|
|
137
|
+
### The crossing check
|
|
138
|
+
A host's test can check that no hub's code names a class another hub owns. The host
|
|
139
|
+
passes a map of which classes each hub owns, and the test fails listing each file and
|
|
140
|
+
the class it names:
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
require "hub_kernel/conformance/crossings"
|
|
144
|
+
|
|
145
|
+
class HubCrossingsTest < ActiveSupport::TestCase
|
|
146
|
+
include HubKernel::Conformance::Crossings
|
|
147
|
+
|
|
148
|
+
crossings files: "app/{models,controllers,jobs,views}/shop/**/*.{rb,erb}", except: [ "app/models/shop/hubs.rb" ] do
|
|
149
|
+
HubKernel::Crossings.new(
|
|
150
|
+
owners: { supplies: %w[Shop::Purchase Shop::PurchasesController], finance: %w[Shop::Expense], shop: %w[Shop::Home] },
|
|
151
|
+
shared: %w[Shop::BaseController],
|
|
152
|
+
host_layer: :shop,
|
|
153
|
+
interfaces: { supplies: "Shop::Hubs::Supplies", finance: "Shop::Hubs::Finance" }
|
|
154
|
+
)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- A constant inside another hub's class counts as naming that class.
|
|
160
|
+
- A name no hub owns, such as a namespace, is not a crossing, and neither is a class on
|
|
161
|
+
the `shared` list.
|
|
162
|
+
- A view belongs to the hub that owns its controller, then to the hub that owns the
|
|
163
|
+
record its folder is named after, and otherwise to the `host_layer`.
|
|
164
|
+
- The host's layer may name any hub's interface module, and a hub naming another hub's
|
|
165
|
+
interface module is a crossing.
|
|
166
|
+
|
|
137
167
|
## Installation
|
|
138
168
|
Add this line to your application's Gemfile:
|
|
139
169
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "active_support/concern"
|
|
2
|
+
require "hub_kernel/crossings"
|
|
3
|
+
|
|
4
|
+
module HubKernel
|
|
5
|
+
module Conformance
|
|
6
|
+
module Crossings
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
class_methods do
|
|
10
|
+
def crossings(root: nil, files: "app/**/*.{rb,erb}", except: [], &block)
|
|
11
|
+
define_method(:the_crossings, &block)
|
|
12
|
+
define_method(:crossing_root) { root || Rails.root }
|
|
13
|
+
define_method(:crossing_files) { files }
|
|
14
|
+
define_method(:crossing_exceptions) { except }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
included do
|
|
19
|
+
test "no file names a class another hub owns" do
|
|
20
|
+
found = (Dir.glob(crossing_files, base: crossing_root) - crossing_exceptions).sort.flat_map do |path|
|
|
21
|
+
the_crossings.in(path, File.read(File.join(crossing_root, path))).map { |name| "#{path} names #{name}" }
|
|
22
|
+
end
|
|
23
|
+
flunk found.join("\n") if found.any?
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "active_support/core_ext/string/inflections"
|
|
2
|
+
|
|
3
|
+
module HubKernel
|
|
4
|
+
class Crossings
|
|
5
|
+
def initialize(owners:, shared: [], host_layer: nil, interfaces: {})
|
|
6
|
+
@owners = owners
|
|
7
|
+
@shared = shared
|
|
8
|
+
@host_layer = host_layer
|
|
9
|
+
@interfaces = interfaces
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def in(path, source)
|
|
13
|
+
hub = owner_of_file(path)
|
|
14
|
+
source.scan(/[A-Z]\w*(?:::[A-Z]\w*)*/).filter_map { |name| owned_class_in(name) }.uniq.select { |name| crossing?(name, hub) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def crossing?(name, hub)
|
|
20
|
+
return false if @shared.include?(name) || owner_of(name) == hub
|
|
21
|
+
|
|
22
|
+
!(hub == @host_layer && @interfaces.value?(name))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def owned_class_in(name)
|
|
26
|
+
parts = name.split("::")
|
|
27
|
+
parts.size.downto(1).map { |size| parts.first(size).join("::") }.find { |candidate| owner_of(candidate) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def owner_of(class_name) = @interfaces.key(class_name) || @owners.find { |_hub, classes| classes.include?(class_name) }&.first
|
|
31
|
+
|
|
32
|
+
def owner_of_file(path)
|
|
33
|
+
return owner_of_view_folder(File.dirname(path.delete_prefix("app/views/")).camelize) if path.start_with?("app/views/")
|
|
34
|
+
|
|
35
|
+
owner_of(path.sub(%r{\Aapp/[^/]+/}, "").delete_suffix(".rb").camelize)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def owner_of_view_folder(folder) = owner_of("#{folder}Controller") || owner_of(folder) || @host_layer
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/hub_kernel/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hub_kernel
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tylercschneider
|
|
@@ -42,10 +42,12 @@ files:
|
|
|
42
42
|
- lib/hub_kernel/answer.rb
|
|
43
43
|
- lib/hub_kernel/authz.rb
|
|
44
44
|
- lib/hub_kernel/conformance/action.rb
|
|
45
|
+
- lib/hub_kernel/conformance/crossings.rb
|
|
45
46
|
- lib/hub_kernel/conformance/exposed.rb
|
|
46
47
|
- lib/hub_kernel/conformance/hub.rb
|
|
47
48
|
- lib/hub_kernel/conformance/partial.rb
|
|
48
49
|
- lib/hub_kernel/context.rb
|
|
50
|
+
- lib/hub_kernel/crossings.rb
|
|
49
51
|
- lib/hub_kernel/engine.rb
|
|
50
52
|
- lib/hub_kernel/exposes.rb
|
|
51
53
|
- lib/hub_kernel/follow_up.rb
|