configuratrix 0.0.1.alpha
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 +7 -0
- data/lib/configuratrix/errors.rb +101 -0
- data/lib/configuratrix/initialize.rb +5 -0
- data/lib/configuratrix/language-util.rb +65 -0
- data/lib/configuratrix/language.rb +639 -0
- data/lib/configuratrix/schema-util.rb +314 -0
- data/lib/configuratrix/schema.rb +970 -0
- data/lib/configuratrix/sources/command_line.rb +585 -0
- data/lib/configuratrix/sources/environment.rb +60 -0
- data/lib/configuratrix/sources/util.rb +303 -0
- data/lib/configuratrix/sources/yaml_file.rb +506 -0
- data/lib/configuratrix/sources.rb +64 -0
- data/lib/configuratrix/types.rb +121 -0
- data/lib/configuratrix.rb +12 -0
- metadata +59 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 93b3ad072cd0671d44b8070ed2001f10e1908b9fa763accb8c3b0a1f677dc1a0
|
|
4
|
+
data.tar.gz: 1120f79e5e750f1ad4f491dd863cb31652b475f1d529ee903d54d53b019fc57c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: fedc7ec78c63f6742a9ec315df056d7c93a4daef59186813ea80cd144b78235b3a5cc63ff80487dc35ebceb466738f449b591d7ae963ef148d5127fedf4e1498
|
|
7
|
+
data.tar.gz: 365e2c66a76e9d4d469cddcd9afabbbae4983a622ee9248e331a88be76f6f008303fc4c633a46e282b15d3a75628bea526eb9a2dbea7eb71a1a10b71ab2b7ece
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module Configuratrix
|
|
2
|
+
|
|
3
|
+
class Err < StandardError
|
|
4
|
+
# By eliminating newlines in error messages, we can use heredocs in `raise`
|
|
5
|
+
# statements which is nice.
|
|
6
|
+
def initialize(message=nil)
|
|
7
|
+
unless message.nil?
|
|
8
|
+
message = message.lines(chomp: true).join(' ').strip
|
|
9
|
+
end
|
|
10
|
+
super(message)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Allow errors to descend from each other in whatever groupings are useful,
|
|
14
|
+
# while still having them all be defined directly under Err.
|
|
15
|
+
def self.err(name, &block)
|
|
16
|
+
Err.const_set name, Class.new(self, &block)
|
|
17
|
+
end
|
|
18
|
+
private_class_method :err
|
|
19
|
+
|
|
20
|
+
# A value is referenced that has no value, not even nil.
|
|
21
|
+
err :NoSuchValue do
|
|
22
|
+
# A namespace was queried for a name it does not contain.
|
|
23
|
+
err :ValuelessKey
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# A well-formed schema could not be defined as requested.
|
|
27
|
+
err :BadSchema do
|
|
28
|
+
# A name would become ambiguous by referring to multiple values.
|
|
29
|
+
err :NameCollision
|
|
30
|
+
# A name was given that is not acceptable in context.
|
|
31
|
+
err :NameIsInvalid do
|
|
32
|
+
# A reserved name was given to a real value.
|
|
33
|
+
err :WordIsReserved
|
|
34
|
+
end
|
|
35
|
+
# A schema is set up in a way that is not useful and may mask
|
|
36
|
+
# misconfiguration elsewhere.
|
|
37
|
+
err :PathologicalSchema
|
|
38
|
+
# A schema class tried to configure itself with respect to another schema
|
|
39
|
+
# class, but did it wrong.
|
|
40
|
+
err :NoCanToggle
|
|
41
|
+
# The type of a value is unspecified and could not be determined.
|
|
42
|
+
err :TypeUndefined
|
|
43
|
+
# An unmarshalled value was assigned to a field (e.g. as the default
|
|
44
|
+
# value), but it is not a value of the field's value_type.
|
|
45
|
+
err :ValueUnrecognized
|
|
46
|
+
# Wrong number of values: An unmarshalled value was assigned to a field
|
|
47
|
+
# (e.g. as the default value), but the plurality of the value is not
|
|
48
|
+
# appropriate for the arity of the field.
|
|
49
|
+
err :ArityMismatch
|
|
50
|
+
# When an existing schema is reopened for further editing to find that it's
|
|
51
|
+
# the wrong kind of schema for the context.
|
|
52
|
+
err :UnsafeReopen
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Though the schema is well-formed, a config could not be created from it.
|
|
56
|
+
err :BadConfig do
|
|
57
|
+
# An input could not be understood within the schema.
|
|
58
|
+
err :SchemaViolation do
|
|
59
|
+
# The configuration does not contain a value that the schema requires it
|
|
60
|
+
# to.
|
|
61
|
+
err :RequirementUnmet
|
|
62
|
+
# The configuration refers to a field not defined in the schema.
|
|
63
|
+
err :NoSuchField
|
|
64
|
+
# The configuration refers to a source not defined in the schema.
|
|
65
|
+
err :NoSuchSource
|
|
66
|
+
# The configuration refers to a value type not defined in the schema.
|
|
67
|
+
err :NoSuchType
|
|
68
|
+
# The value specified for a field was not usable by that field.
|
|
69
|
+
err :MarshalUnacceptable
|
|
70
|
+
end
|
|
71
|
+
# A source encountered a problem with its input other than a violation of
|
|
72
|
+
# the schema.
|
|
73
|
+
err :SourceRejected do
|
|
74
|
+
# The source's input text was in some way not well-formed
|
|
75
|
+
err :BadSyntax
|
|
76
|
+
# The field was specified in a source in a context not appropriate for
|
|
77
|
+
# the field's value type. Contrast this to MarshalUnacceptable: a Type
|
|
78
|
+
# with no #affirm specified is not applicable to an implicit command line
|
|
79
|
+
# specification like `--field`. There's not even a value to deem
|
|
80
|
+
# unacceptable.
|
|
81
|
+
err :FieldNotApplicable
|
|
82
|
+
# A reference was made to a field, but it can't be told which one.
|
|
83
|
+
err :AmbiguousName
|
|
84
|
+
# A value was given when no more were expected.
|
|
85
|
+
err :DanglingValue
|
|
86
|
+
# A value was neither omitted from a source, nor fully specified.
|
|
87
|
+
err :IncompleteValue
|
|
88
|
+
# The source needed to resolve a reference within the source text, but
|
|
89
|
+
# couldn't.
|
|
90
|
+
err :BadReference
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Like the ruby's ArgumentError, but plays nice with heredoc messages.
|
|
95
|
+
err :BadArgument
|
|
96
|
+
|
|
97
|
+
# Testing only: an error that will never be raised.
|
|
98
|
+
err :UnusedError
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Configuratrix
|
|
2
|
+
module Internal
|
|
3
|
+
|
|
4
|
+
module ConfigSchemaLanguageUtil
|
|
5
|
+
# Facilitate the slick no-default/default commaless syntax for minimally
|
|
6
|
+
# specifying a field.
|
|
7
|
+
# field :has_no_default
|
|
8
|
+
# vs.
|
|
9
|
+
# field defaults_to: :a_value
|
|
10
|
+
#
|
|
11
|
+
# Returns a triple of [name, has_default, default_value (if applicable)]
|
|
12
|
+
def self.unpack_field_args(name, kwargs, declaring: :field)
|
|
13
|
+
case kwargs.size
|
|
14
|
+
in 0
|
|
15
|
+
if name.nil?
|
|
16
|
+
raise Err::BadArgument, <<~END
|
|
17
|
+
#{declaring} declaration requires a name
|
|
18
|
+
END
|
|
19
|
+
end
|
|
20
|
+
[name.to_sym, false]
|
|
21
|
+
in 1
|
|
22
|
+
unless name.nil?
|
|
23
|
+
raise Err::BadArgument, <<~END
|
|
24
|
+
#{declaring} declaration can't mix positional and keyword
|
|
25
|
+
arguments
|
|
26
|
+
END
|
|
27
|
+
end
|
|
28
|
+
[kwargs.keys.first.to_sym, true, kwargs.values.first]
|
|
29
|
+
in (2...)
|
|
30
|
+
raise Err::BadArgument, <<~END
|
|
31
|
+
#{declaring} declaration takes no extra keywords
|
|
32
|
+
END
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Fetch (or create) the named field within the config schema.
|
|
37
|
+
def self.field_by_name(name, schema:)
|
|
38
|
+
NestingSchemaUtil.absent_local_or_remote(
|
|
39
|
+
name,
|
|
40
|
+
schema.method(:fields),
|
|
41
|
+
absent: -> { schema.field_add Field.nested_class!(name, under: schema) },
|
|
42
|
+
local: -> { schema.field_get name },
|
|
43
|
+
remote: -> { schema.field_lift name },
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.resolve_file_source_schema(filename, format)
|
|
48
|
+
return format if format .is_a? Class
|
|
49
|
+
|
|
50
|
+
format ||= filename.split('.').last
|
|
51
|
+
source_name = (format.to_s.capitalize << "File").to_sym
|
|
52
|
+
|
|
53
|
+
unless Mutable::DefaultSources.const_defined? source_name
|
|
54
|
+
raise Err::ValuelessKey, <<~END
|
|
55
|
+
#{source_name} does not name a Source!
|
|
56
|
+
END
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
Mutable::DefaultSources.const_get source_name
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
end
|