optify-config 0.2.0-arm64-darwin-23 → 0.4.0-arm64-darwin-23
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/optify.rb +6 -4
- data/lib/optify_ruby/base_config.rb +48 -0
- data/lib/optify_ruby/implementation.rb +63 -6
- data/rbi/optify.rbi +71 -0
- metadata +24 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a854df741a2d742bf02aa203680cb8e009d650c94e6df0bd7cb8e56c884c408d
|
4
|
+
data.tar.gz: b77a4cb44c75fb188213b359b22140a26e80540e2795e92d9dd3a26b8faea308
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcf0e1b405a0c949670f13977586305d8ae4e232a976d0be6449d238c1e5850b67fe84c785f661f821f2ad11f5a6df3800e57b19d2e0313c0bdbe00e6464eab3
|
7
|
+
data.tar.gz: 045fc428b2459348d422a8fefaf8a5a5c5d606416a9fbd990fdf44e7e2cb8b1f78bef81d28619b415fa320753fd3555d421c8849712718c537a5fce3a99f6f08
|
data/lib/optify.rb
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
# typed: strict
|
3
3
|
|
4
4
|
# The implementation to use directly Ruby and with types declared.
|
5
|
-
require_relative
|
6
|
-
|
5
|
+
require_relative 'optify_ruby/implementation'
|
7
6
|
|
8
7
|
# The implementation in Rust which redefines some methods.
|
9
8
|
# This yields some warnings, but we should redeclare the methods in Ruby to help with type checking anyway.
|
10
|
-
# Warnings about redefining methods are normal and can be ignored
|
11
|
-
|
9
|
+
# Warnings about redefining methods are normal and can be ignored
|
10
|
+
# because the implementations in Ruby are not implemented and only exist to help with type checking.
|
11
|
+
require_relative 'optify_ruby/optify_ruby'
|
12
|
+
|
13
|
+
require_relative 'optify_ruby/base_config'
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'sorbet-runtime'
|
5
|
+
require 'tapioca'
|
6
|
+
|
7
|
+
module Optify
|
8
|
+
# A base class for classes from configuration files.
|
9
|
+
# Classes that derive from this can easily be used with `Optify::OptionsProvider.get_options`
|
10
|
+
# because they will have an implementation of `from_hash` that works recursively.
|
11
|
+
# This class is a work in progress with minimal error handling
|
12
|
+
# and doesn't handle certain cases such as nilable types yet.
|
13
|
+
# It may be moved to another gem in the future.
|
14
|
+
class BaseConfig
|
15
|
+
extend T::Sig
|
16
|
+
extend T::Helpers
|
17
|
+
abstract!
|
18
|
+
|
19
|
+
# Create a new instance of the class from a hash.
|
20
|
+
#
|
21
|
+
# @param hash [Hash] The hash to create the instance from.
|
22
|
+
# @return The new instance.
|
23
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T.attached_class) }
|
24
|
+
def self.from_hash(hash)
|
25
|
+
result = new
|
26
|
+
|
27
|
+
hash.each do |key, value|
|
28
|
+
# TODO: Might need some error handling here, but it should be fine if type signatures are used.
|
29
|
+
# TODO Handle nilable types.
|
30
|
+
case value
|
31
|
+
when Array
|
32
|
+
sig_return_type = T::Utils.signature_for_method(instance_method(key)).return_type
|
33
|
+
inner_type = sig_return_type.type.raw_type
|
34
|
+
value = value.map { |v| inner_type.from_hash(v) } if inner_type.respond_to?(:from_hash)
|
35
|
+
when Hash
|
36
|
+
sig_return_type = T::Utils.signature_for_method(instance_method(key)).return_type
|
37
|
+
if sig_return_type.respond_to?(:raw_type)
|
38
|
+
type_for_key = sig_return_type.raw_type
|
39
|
+
value = type_for_key.from_hash(value) if type_for_key.respond_to?(:from_hash)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
result.instance_variable_set("@#{key}", value)
|
44
|
+
end
|
45
|
+
result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -2,12 +2,18 @@
|
|
2
2
|
# typed: strict
|
3
3
|
|
4
4
|
require 'json'
|
5
|
-
require 'ostruct'
|
6
5
|
|
7
6
|
require 'sorbet-runtime'
|
8
7
|
|
8
|
+
require_relative './base_config'
|
9
|
+
|
9
10
|
# Tools for working with configurations declared in files.
|
10
11
|
module Optify
|
12
|
+
# Options for caching.
|
13
|
+
# Only enabling or disabling caching is supported for now.
|
14
|
+
class CacheOptions < BaseConfig
|
15
|
+
end
|
16
|
+
|
11
17
|
# Provides configurations based on keys and enabled feature names.
|
12
18
|
class OptionsProvider
|
13
19
|
extend T::Sig
|
@@ -27,11 +33,62 @@ module Optify
|
|
27
33
|
#
|
28
34
|
# @param key [String] the key to fetch options for.
|
29
35
|
# @param feature_names [Array<String>] The enabled feature names to use to build the options.
|
30
|
-
# @
|
31
|
-
|
32
|
-
|
36
|
+
# @param config_class [ConfigType] The class of the configuration to return.
|
37
|
+
# It is recommended to use a class that extends `Optify::BaseConfig` because it implements `from_hash`.
|
38
|
+
# @param cache_options Set this if caching is desired. Only very simple caching is supported for now.
|
39
|
+
# @return [ConfigType] The options.
|
40
|
+
sig do
|
41
|
+
type_parameters(:Config)
|
42
|
+
.params(
|
43
|
+
key: String,
|
44
|
+
feature_names: T::Array[String],
|
45
|
+
config_class: T::Class[T.type_parameter(:Config)],
|
46
|
+
cache_options: T.nilable(CacheOptions)
|
47
|
+
)
|
48
|
+
.returns(T.type_parameter(:Config))
|
49
|
+
end
|
50
|
+
def get_options(key, feature_names, config_class, cache_options = nil)
|
51
|
+
return get_options_with_cache(key, feature_names, config_class, cache_options) if cache_options
|
52
|
+
|
33
53
|
options_json = get_options_json(key, feature_names)
|
34
|
-
JSON.parse(options_json, object_class:
|
54
|
+
h = JSON.parse(options_json, object_class: Hash)
|
55
|
+
unless config_class.respond_to?(:from_hash)
|
56
|
+
raise NotImplementedError,
|
57
|
+
"The provided config class must implement `from_hash` as a class method
|
58
|
+
in order to be converted."
|
59
|
+
end
|
60
|
+
|
61
|
+
T.unsafe(config_class).from_hash(h)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
NOT_FOUND_IN_CACHE_SENTINEL = Object.new
|
67
|
+
|
68
|
+
sig do
|
69
|
+
type_parameters(:Config)
|
70
|
+
.params(
|
71
|
+
key: String,
|
72
|
+
feature_names: T::Array[String],
|
73
|
+
config_class: T::Class[T.type_parameter(:Config)],
|
74
|
+
_cache_options: CacheOptions
|
75
|
+
)
|
76
|
+
.returns(T.type_parameter(:Config))
|
77
|
+
end
|
78
|
+
def get_options_with_cache(key, feature_names, config_class, _cache_options)
|
79
|
+
# Cache directly in Ruby instead of Rust because:
|
80
|
+
# * Avoid any possible conversion overhead.
|
81
|
+
# * Memory management: probably better to do it in Ruby for a Ruby app and avoid memory in Rust.
|
82
|
+
# TODO: Handle aliases. Right now, they are only visible in Rust
|
83
|
+
# and we don't want the cache in Rust because we won't to avoid any conversion overhead.
|
84
|
+
@cache ||= T.let({}, T.nilable(T::Hash[T.untyped, T.untyped]))
|
85
|
+
cache_key = [key, feature_names, config_class]
|
86
|
+
result = @cache.fetch(cache_key, NOT_FOUND_IN_CACHE_SENTINEL)
|
87
|
+
return result unless result.equal?(NOT_FOUND_IN_CACHE_SENTINEL)
|
88
|
+
|
89
|
+
result = get_options(key, feature_names, config_class)
|
90
|
+
|
91
|
+
@cache[cache_key] = result
|
35
92
|
end
|
36
93
|
end
|
37
94
|
|
@@ -56,4 +113,4 @@ module Optify
|
|
56
113
|
raise NotImplementedError
|
57
114
|
end
|
58
115
|
end
|
59
|
-
end
|
116
|
+
end
|
data/rbi/optify.rbi
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: strong
|
3
|
+
|
4
|
+
# Tools for working with configurations declared in files.
|
5
|
+
module Optify
|
6
|
+
# A base class for classes from configuration files.
|
7
|
+
# Classes that derive from this can easily be used with `Optify::OptionsProvider.get_options`
|
8
|
+
# because they will have an implementation of `from_hash` that works recursively.
|
9
|
+
# This class is a work in progress with minimal error handling
|
10
|
+
# and doesn't handle certain cases such as nilable types yet.
|
11
|
+
# It may be moved to another gem in the future.
|
12
|
+
class BaseConfig
|
13
|
+
abstract!
|
14
|
+
|
15
|
+
# Create a new instance of the class from a hash.
|
16
|
+
#
|
17
|
+
# @param hash [Hash] The hash to create the instance from.
|
18
|
+
# @return The new instance.
|
19
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T.attached_class) }
|
20
|
+
def self.from_hash(hash); end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Options for caching.
|
24
|
+
# Only enabling or disabling caching is supported for now.
|
25
|
+
class CacheOptions < BaseConfig
|
26
|
+
end
|
27
|
+
|
28
|
+
# Provides configurations based on keys and enabled feature names.
|
29
|
+
class OptionsProvider
|
30
|
+
# Fetches options based on the provided key and feature names.
|
31
|
+
#
|
32
|
+
# @param key [String] the key to fetch options for.
|
33
|
+
# @param feature_names [Array<String>] The enabled feature names to use to build the options.
|
34
|
+
# @param config_class [ConfigType] The class of the configuration to return.
|
35
|
+
# It is recommended to use a class that extends `Optify::BaseConfig` because it implements `from_hash`.
|
36
|
+
# @return [ConfigType] The options.
|
37
|
+
sig do
|
38
|
+
type_parameters(:Config)
|
39
|
+
.params(
|
40
|
+
key: String,
|
41
|
+
feature_names: T::Array[String],
|
42
|
+
config_class: T::Class[T.type_parameter(:Config)],
|
43
|
+
cache_options: T.nilable(CacheOptions)
|
44
|
+
)
|
45
|
+
.returns(T.type_parameter(:Config))
|
46
|
+
end
|
47
|
+
def get_options(key, feature_names, config_class, cache_options = nil); end
|
48
|
+
|
49
|
+
# Fetches options in JSON format based on the provided key and feature names.
|
50
|
+
#
|
51
|
+
# @param key [String] the key to fetch options for.
|
52
|
+
# @param feature_names [Array<String>] The enabled feature names to use to build the options.
|
53
|
+
# @return [String] the options in JSON.
|
54
|
+
sig { params(key: String, feature_names: T::Array[String]).returns(String) }
|
55
|
+
def get_options_json(key, feature_names); end
|
56
|
+
end
|
57
|
+
|
58
|
+
# A builder for creating an `OptionsProvider` instance.
|
59
|
+
class OptionsProviderBuilder
|
60
|
+
# Adds a directory to the builder.
|
61
|
+
#
|
62
|
+
# @param path [String] The path of the directory to add.
|
63
|
+
# @return [OptionsProviderBuilder] `self`.
|
64
|
+
sig { params(path: String).returns(OptionsProviderBuilder) }
|
65
|
+
def add_directory(path); end
|
66
|
+
|
67
|
+
# @return [OptionsProvider] A newly built `OptionsProvider`.
|
68
|
+
sig { returns(OptionsProvider) }
|
69
|
+
def build; end
|
70
|
+
end
|
71
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: optify-config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: arm64-darwin-23
|
6
6
|
authors:
|
7
7
|
- Justin D. Harris
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-02-
|
11
|
+
date: 2025-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet-runtime
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.5.11796
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.5.11796
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake-compiler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -42,60 +42,63 @@ dependencies:
|
|
42
42
|
name: sorbet
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.5.11796
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.5.11796
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: tapioca
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.16.8
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.16.8
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: test-unit
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 3.6.7
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
-
description:
|
84
|
-
|
82
|
+
version: 3.6.7
|
83
|
+
description: |-
|
84
|
+
Simplifies getting the right configuration options for a process using pre-loaded configurations
|
85
|
+
from files to manage options for experiments or flights.
|
85
86
|
email:
|
86
87
|
executables: []
|
87
88
|
extensions: []
|
88
89
|
extra_rdoc_files: []
|
89
90
|
files:
|
90
91
|
- lib/optify.rb
|
92
|
+
- lib/optify_ruby/base_config.rb
|
91
93
|
- lib/optify_ruby/implementation.rb
|
92
94
|
- lib/optify_ruby/optify_ruby.bundle
|
95
|
+
- rbi/optify.rbi
|
93
96
|
homepage: https://github.com/juharris/optify
|
94
97
|
licenses:
|
95
98
|
- MIT
|
96
99
|
metadata:
|
97
|
-
source_code_uri: https://github.com/juharris/optify
|
98
100
|
bug_tracker_uri: https://github.com/juharris/optify/issues
|
101
|
+
source_code_uri: https://github.com/juharris/optify
|
99
102
|
post_install_message:
|
100
103
|
rdoc_options: []
|
101
104
|
require_paths:
|