asimov-config 25.0.0.dev.5 → 25.0.0.dev.6

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
  SHA256:
3
- metadata.gz: 82b3c0af7c4d692d74f1119d544bd63059b08f4960bdee86f83831bdb7cb147d
4
- data.tar.gz: a582c8495e6d9d62da3a3fe413690640d6c77e56938fbcb5612ad9c9af701d19
3
+ metadata.gz: fdf9109315728f900b38ace479e7771baa6e8948755648e7950655e3a0d57b1f
4
+ data.tar.gz: dceef3edcb6df12259af3e856abddc8654a3be537fb7784a1867eaf685a32792
5
5
  SHA512:
6
- metadata.gz: 9354be1c6f0dd26d5ab9a74bffbad3de0910b40598a3d4bded9bcbf3443a7171cbb708da6fd780baa259654975af54cb6aa223b4424eef23c81ad5304d72772e
7
- data.tar.gz: bbd27178dadfd2e5f2117e13c0078890cdbb97bc3e6ee6c560f495568f67ad25e277b215b7e210e3923284fc35136a84caf21a5dd7b4d984fe6f6f5d131b8353
6
+ metadata.gz: 8283efc1b79cf70326ba13b57fc122a213544aff1f59048914abfefd877bf2ab242f6ddd3e4ea17b6e70753213afda9618eb75c302ebb383f863be8e21b51bc6
7
+ data.tar.gz: c1342f03f53e1a1cdee6b97a54dc9d05ad1fae432046ccdb584978686abac2a2816c5f3ab65c34a5bfef45ee35ca2bd1249c6b91bb619de5eb513557237cfde4
data/CHANGES.md CHANGED
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 25.0.0.dev.6 - 2025-06-13
9
+ ### Added
10
+ - asimov-config: `ASIMOV::Config::ModuleManifest`
11
+ - asimov-config: `ASIMOV::Config::Resolver`
12
+
8
13
  ## 25.0.0.dev.5 - 2025-06-11
9
14
 
10
15
  ## 25.0.0.dev.4 - 2025-02-15
data/VERSION CHANGED
@@ -1 +1 @@
1
- 25.0.0.dev.5
1
+ 25.0.0.dev.6
@@ -0,0 +1,67 @@
1
+ # This is free and unencumbered software released into the public domain.
2
+
3
+ require 'yaml'
4
+
5
+ module ASIMOV; end
6
+ module ASIMOV::Config; end
7
+
8
+ ##
9
+ # ASIMOV module manifest.
10
+ class ASIMOV::Config::ModuleManifest
11
+ ##
12
+ # @param [Pathname, #to_s] path
13
+ # @return [ModuleManifest]
14
+ def self.load_file(path)
15
+ self.load_yaml(File.read(path.to_s))
16
+ end
17
+
18
+ ##
19
+ # @param [String, #to_s] yaml
20
+ # @return [ModuleManifest]
21
+ def self.load_yaml(yaml_string)
22
+ self.new(YAML.safe_load(yaml_string, symbolize_names: true))
23
+ end
24
+
25
+ ##
26
+ # @return [String]
27
+ attr_reader :name
28
+ def name() @yaml[:name] end
29
+
30
+ ##
31
+ # @return [String]
32
+ attr_reader :label
33
+ def label() @yaml[:label] end
34
+
35
+ ##
36
+ # @return [String]
37
+ attr_reader :summary
38
+ def summary() @yaml[:summary] end
39
+
40
+ ##
41
+ # @return [Array<String>]
42
+ attr_reader :links
43
+ def links() @yaml[:links] end
44
+
45
+ ##
46
+ # @return [Hash{Symbol => Object}]
47
+ attr_reader :provides
48
+ def provides() @yaml[:provides] end
49
+
50
+ ##
51
+ # @return [Hash{Symbol => Object}]
52
+ attr_reader :handles
53
+ def handles() @yaml[:handles] end
54
+
55
+ ##
56
+ # @param [Hash{Symbol => Object}] yaml
57
+ # @return [void]
58
+ def initialize(yaml)
59
+ @yaml = yaml
60
+ end
61
+
62
+ ##
63
+ # @return [Hash{Symbol => Object}]
64
+ def to_h
65
+ @yaml
66
+ end
67
+ end # ASIMOV::Config::ModuleManifest
@@ -0,0 +1,118 @@
1
+ # This is free and unencumbered software released into the public domain.
2
+
3
+ require 'addressable/uri'
4
+
5
+ module ASIMOV; end
6
+ module ASIMOV::Config; end
7
+
8
+ ##
9
+ # ASIMOV resolver.
10
+ class ASIMOV::Config::Resolver
11
+ ##
12
+ # @return [Hash{Symbol, Array<Symbol>}]
13
+ attr_reader :url_protocols
14
+
15
+ ##
16
+ # @return [Hash{Regexp, Array<Symbol>}]
17
+ attr_reader :url_patterns
18
+
19
+ ##
20
+ # @return [Hash{String, Array<Symbol>}]
21
+ attr_reader :url_prefixes
22
+
23
+ ##
24
+ # @return [void]
25
+ def initialize
26
+ @url_protocols = {}
27
+ @url_patterns = {}
28
+ @url_prefixes = {}
29
+ end
30
+
31
+ ##
32
+ # @param [ModuleManifest, #to_h] module_manifest
33
+ # @return [void]
34
+ def register_module!(module_manifest)
35
+ module_manifest = module_manifest.to_h
36
+
37
+ module_name = module_manifest[:name].to_sym
38
+ module_handles = module_manifest[:handles] || {}
39
+
40
+ (module_handles[:url_protocols] || []).each do |url_protocol|
41
+ (@url_protocols[url_protocol.to_sym] ||= []) << module_name
42
+ end
43
+
44
+ (module_handles[:url_patterns] || []).each do |url_pattern|
45
+ url_regexp = compile_url_pattern(url_pattern)
46
+ (@url_patterns[url_regexp] ||= []) << module_name
47
+
48
+ www_pattern = url_pattern.sub('https://', 'https://www.')
49
+ next unless www_pattern != url_pattern
50
+ www_regexp = compile_url_pattern(www_pattern)
51
+ (@url_patterns[www_regexp] ||= []) << module_name
52
+ end
53
+
54
+ (module_handles[:url_prefixes] || []).each do |url_prefix|
55
+ (@url_prefixes[url_prefix] ||= []) << module_name
56
+ www_prefix = url_prefix.sub('https://', 'https://www.')
57
+ (@url_prefixes[www_prefix] ||= []) << module_name
58
+ end
59
+
60
+ self
61
+ end
62
+
63
+ ##
64
+ # @param [Addressable::URI, #to_s] input_url
65
+ # @return [Symbol]
66
+ def resolve_url(input_url)
67
+ input_url_scheme = Addressable::URI.parse(input_url).scheme.to_sym
68
+ input_url_string = input_url.to_s
69
+
70
+ @url_protocols.each do |url_protocol, module_names|
71
+ return module_names.last if url_protocol == input_url_scheme
72
+ end
73
+
74
+ @url_patterns.each do |url_pattern, module_names|
75
+ return module_names.last if url_pattern === input_url_string
76
+ end
77
+
78
+ @url_prefixes.each do |url_prefix, module_names|
79
+ return module_names.last if input_url_string.start_with?(url_prefix)
80
+ end
81
+
82
+ nil # no match
83
+ end
84
+ alias_method :resolve_uri, :resolve_url
85
+
86
+ ##
87
+ # @param [Addressable::URI, #to_s] input_url
88
+ # @return [Array<Symbol>]
89
+ def lookup_url(input_url)
90
+ input_url_scheme = Addressable::URI.parse(input_url).scheme.to_sym
91
+ input_url_string = input_url.to_s
92
+ output_module_names = []
93
+
94
+ @url_protocols.each do |url_protocol, module_names|
95
+ output_module_names += module_names if url_protocol == input_url_scheme
96
+ end
97
+
98
+ @url_patterns.each do |url_pattern, module_names|
99
+ output_module_names += module_names if url_pattern === input_url_string
100
+ end
101
+
102
+ @url_prefixes.each do |url_prefix, module_names|
103
+ output_module_names += module_names if input_url_string.start_with?(url_prefix)
104
+ end
105
+
106
+ output_module_names.uniq
107
+ end
108
+ alias_method :lookup_uri, :lookup_url
109
+
110
+ protected
111
+
112
+ def compile_url_pattern(pattern)
113
+ temp_pattern = pattern.gsub(/:([a-zA-Z_][a-zA-Z0-9_]*)/, 'PLACEHOLDER\1PLACEHOLDER')
114
+ escaped_pattern = Regexp.escape(temp_pattern)
115
+ final_pattern = escaped_pattern.gsub(/PLACEHOLDER([a-zA-Z_][a-zA-Z0-9_]*)PLACEHOLDER/, '(?<\1>[^/]+)')
116
+ Regexp.new("\\A#{final_pattern}\\z")
117
+ end
118
+ end # ASIMOV::Config::Resolver
data/lib/asimov/config.rb CHANGED
@@ -4,6 +4,8 @@ require "pathname"
4
4
 
5
5
  module ASIMOV; end
6
6
 
7
+ ##
8
+ # ASIMOV configuration.
7
9
  module ASIMOV::Config
8
10
  ##
9
11
  # @return [Pathname]
@@ -61,3 +63,6 @@ module ASIMOV::Config
61
63
  end
62
64
  end
63
65
  end # ASIMOV::Config
66
+
67
+ require_relative "config/resolver"
68
+ require_relative "config/module_manifest"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asimov-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 25.0.0.dev.5
4
+ version: 25.0.0.dev.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - ASIMOV Protocol
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-11 00:00:00.000000000 Z
10
+ date: 2025-06-13 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -51,6 +51,20 @@ dependencies:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0.9'
54
+ - !ruby/object:Gem::Dependency
55
+ name: addressable
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.8'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.8'
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: pathname
56
70
  requirement: !ruby/object:Gem::Requirement
@@ -78,6 +92,8 @@ files:
78
92
  - VERSION
79
93
  - lib/asimov-config.rb
80
94
  - lib/asimov/config.rb
95
+ - lib/asimov/config/module_manifest.rb
96
+ - lib/asimov/config/resolver.rb
81
97
  homepage: https://sdk.asimov.so
82
98
  licenses:
83
99
  - Unlicense