build-environment 1.13.0 → 1.13.1
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
- checksums.yaml.gz.sig +0 -0
- data/lib/build/environment/base.rb +53 -23
- data/lib/build/environment/constructor.rb +56 -20
- data/lib/build/environment/evaluator.rb +16 -19
- data/lib/build/environment/flatten.rb +21 -20
- data/lib/build/environment/system.rb +15 -20
- data/lib/build/environment/version.rb +6 -1
- data/lib/build/environment.rb +9 -24
- data/license.md +21 -0
- data/readme.md +35 -0
- data/releases.md +3 -0
- data.tar.gz.sig +0 -0
- metadata +44 -87
- metadata.gz.sig +0 -0
- data/.gitignore +0 -4
- data/.rspec +0 -3
- data/.travis.yml +0 -12
- data/Gemfile +0 -4
- data/README.md +0 -76
- data/Rakefile +0 -6
- data/build-environment.gemspec +0 -24
- data/spec/build/environment/build_spec.rb +0 -50
- data/spec/build/environment/checksum_spec.rb +0 -41
- data/spec/build/environment/constructor_spec.rb +0 -70
- data/spec/build/environment/environment_spec.rb +0 -164
- data/spec/build/environment/evaluator_spec.rb +0 -64
- data/spec/build/environment/flatten_spec.rb +0 -42
- data/spec/build/environment/freeze_spec.rb +0 -54
- data/spec/build/environment/rule.rb +0 -10
- data/spec/build/environment/system_spec.rb +0 -52
- data/spec/build/environment/update_spec.rb +0 -50
- data/spec/spec_helper.rb +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7d02cb9b10eb8b64658e32892a64fd230b19240b1cba5dd9929f7279b561efde
|
|
4
|
+
data.tar.gz: 689ed69086ed05c58e918b92ee1a77aa2075cd63edcf0b2d4c1cd6d7b298b95f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5cfbe57694c3411f2ea33e5a76c9ff45af79632a4b2eeccf92c458793cdcf6217e46615c467b2045d7b79284a04224d22479224f622da609dfbe6ea2fdf61d90
|
|
7
|
+
data.tar.gz: 6f12270f025151f6df8723d89cab367af5e4fa95f0d45a19f046551ed672cfc74a4b78a1fbde9225ea10b769ee2d3cf3079852ed0c33edb52da150611c70c49c
|
checksums.yaml.gz.sig
ADDED
|
Binary file
|
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
20
2
|
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2015-2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
# @namespace
|
|
21
7
|
module Build
|
|
22
|
-
#
|
|
8
|
+
# Represents a layered build environment, implemented as a linked list of hashes. It is primarily used for organising build configurations across a wide range of different sub-systems, e.g. platform configuration, target configuration, local project configuration, etc.
|
|
23
9
|
class Environment
|
|
10
|
+
# Initialize a new environment with an optional parent, initial values, name, and update block.
|
|
11
|
+
# @parameter parent [Environment | Nil] The parent environment to inherit values from.
|
|
12
|
+
# @parameter values [Hash | Nil] The initial key-value pairs for this layer.
|
|
13
|
+
# @parameter name [String | Nil] An optional name for this environment.
|
|
14
|
+
# @parameter block [Proc] An optional block applied when constructing the environment.
|
|
24
15
|
def initialize(parent = nil, values = nil, name: nil, &block)
|
|
25
16
|
@parent = parent
|
|
26
17
|
@values = (values || {}).to_h
|
|
@@ -29,6 +20,9 @@ module Build
|
|
|
29
20
|
@name = name
|
|
30
21
|
end
|
|
31
22
|
|
|
23
|
+
# Compare this environment with another for equality.
|
|
24
|
+
# @parameter other [Environment] The environment to compare against.
|
|
25
|
+
# @returns [Boolean] `true` if both environments have the same parent, values, update, and name.
|
|
32
26
|
def == other
|
|
33
27
|
self.equal?(other) or
|
|
34
28
|
self.class == other.class and
|
|
@@ -38,10 +32,15 @@ module Build
|
|
|
38
32
|
@name == other.name
|
|
39
33
|
end
|
|
40
34
|
|
|
35
|
+
# Check equality using the `==` operator.
|
|
36
|
+
# @parameter other [Environment] The environment to compare against.
|
|
37
|
+
# @returns [Boolean] `true` if the environments are equal.
|
|
41
38
|
def eql?(other)
|
|
42
39
|
self == other
|
|
43
40
|
end
|
|
44
41
|
|
|
42
|
+
# Compute a hash value for this environment based on its parent, values, update, and name.
|
|
43
|
+
# @returns [Integer] The computed hash value.
|
|
45
44
|
def hash
|
|
46
45
|
@parent.hash ^ @values.hash ^ @update.hash ^ @name.hash
|
|
47
46
|
end
|
|
@@ -51,10 +50,18 @@ module Build
|
|
|
51
50
|
attr :update
|
|
52
51
|
attr :name
|
|
53
52
|
|
|
53
|
+
# Create a duplicate of this environment, optionally overriding parent, values, update, or name.
|
|
54
|
+
# @parameter parent [Environment | Nil] The parent for the duplicate.
|
|
55
|
+
# @parameter values [Hash] The values for the duplicate.
|
|
56
|
+
# @parameter update [Proc | Nil] The update block for the duplicate.
|
|
57
|
+
# @parameter name [String | Nil] The name for the duplicate.
|
|
58
|
+
# @returns [Environment] A new environment with the given attributes.
|
|
54
59
|
def dup(parent: @parent, values: @values, update: @update, name: @name)
|
|
55
60
|
self.class.new(parent, values.dup, name: name, &update)
|
|
56
61
|
end
|
|
57
62
|
|
|
63
|
+
# Freeze this environment and its entire parent chain, making it immutable.
|
|
64
|
+
# @returns [Environment] The frozen environment.
|
|
58
65
|
def freeze
|
|
59
66
|
return self if frozen?
|
|
60
67
|
|
|
@@ -65,6 +72,9 @@ module Build
|
|
|
65
72
|
super
|
|
66
73
|
end
|
|
67
74
|
|
|
75
|
+
# Find the environment layer that contains the given key.
|
|
76
|
+
# @parameter name [Symbol] The key to search for.
|
|
77
|
+
# @returns [Environment | Nil] The environment layer containing the key, or `nil` if not found.
|
|
68
78
|
def lookup(name)
|
|
69
79
|
if @values.include? name
|
|
70
80
|
self
|
|
@@ -73,6 +83,9 @@ module Build
|
|
|
73
83
|
end
|
|
74
84
|
end
|
|
75
85
|
|
|
86
|
+
# Check whether the key exists in this environment or any parent layer.
|
|
87
|
+
# @parameter key [Symbol] The key to check.
|
|
88
|
+
# @returns [Boolean | Nil] `true` if the key exists, `nil` otherwise.
|
|
76
89
|
def include?(key)
|
|
77
90
|
if @values.include?(key)
|
|
78
91
|
true
|
|
@@ -81,10 +94,19 @@ module Build
|
|
|
81
94
|
end
|
|
82
95
|
end
|
|
83
96
|
|
|
97
|
+
alias :key? :include?
|
|
98
|
+
|
|
99
|
+
# Count the total number of key-value pairs across all layers.
|
|
100
|
+
# @returns [Integer] The total size.
|
|
84
101
|
def size
|
|
85
102
|
@values.size + (@parent ? @parent.size : 0)
|
|
86
103
|
end
|
|
87
104
|
|
|
105
|
+
# Retrieve the value for a key, with support for a default value or block.
|
|
106
|
+
# @parameter key [Symbol] The key to look up.
|
|
107
|
+
# @parameter default [Array] An optional default value.
|
|
108
|
+
# @raises [KeyError] If the key is not found and no default or block is given.
|
|
109
|
+
# @returns [Object] The value associated with the key, or the default.
|
|
88
110
|
def fetch(key, *default, &block)
|
|
89
111
|
if environment = lookup(key)
|
|
90
112
|
return environment.values[key]
|
|
@@ -97,28 +119,36 @@ module Build
|
|
|
97
119
|
end
|
|
98
120
|
end
|
|
99
121
|
|
|
122
|
+
# Retrieve the value for a key, returning `nil` if not found.
|
|
123
|
+
# @parameter key [Symbol] The key to look up.
|
|
124
|
+
# @returns [Object | Nil] The value, or `nil` if the key does not exist.
|
|
100
125
|
def [](key)
|
|
101
126
|
environment = lookup(key)
|
|
102
127
|
|
|
103
128
|
environment ? environment.values[key] : nil
|
|
104
129
|
end
|
|
105
130
|
|
|
131
|
+
# Set the value for a key in the current environment layer.
|
|
132
|
+
# @parameter key [Symbol] The key to set.
|
|
133
|
+
# @parameter value [Object] The value to assign.
|
|
106
134
|
def []=(key, value)
|
|
107
135
|
@values[key] = value
|
|
108
136
|
end
|
|
109
137
|
|
|
138
|
+
# Return a human-readable string representation of this environment.
|
|
139
|
+
# @returns [String] A string showing the class, name, update source location, and values.
|
|
110
140
|
def to_s
|
|
111
141
|
buffer = String.new("\#<#{self.class} ")
|
|
112
142
|
|
|
113
143
|
if @name
|
|
114
|
-
buffer << @name.inspect <<
|
|
144
|
+
buffer << @name.inspect << " "
|
|
115
145
|
end
|
|
116
146
|
|
|
117
147
|
if @update
|
|
118
|
-
buffer << @update.source_location.join(
|
|
148
|
+
buffer << @update.source_location.join(":") << " "
|
|
119
149
|
end
|
|
120
150
|
|
|
121
|
-
buffer << @values.to_s <<
|
|
151
|
+
buffer << @values.to_s << ">"
|
|
122
152
|
|
|
123
153
|
return buffer
|
|
124
154
|
end
|
|
@@ -1,40 +1,33 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
20
2
|
|
|
21
|
-
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2015-2026, by Samuel Williams.
|
|
22
5
|
|
|
23
6
|
module Build
|
|
24
7
|
class Environment
|
|
25
8
|
Default = Struct.new(:value)
|
|
26
9
|
Replace = Struct.new(:value)
|
|
27
10
|
|
|
11
|
+
# Represents a deferred class instantiation, binding a class and a configuration block to an environment key.
|
|
28
12
|
class Define < Struct.new(:klass, :block)
|
|
13
|
+
# Initialize a define with a class and an optional configuration block.
|
|
14
|
+
# @parameter klass [Class] The class to instantiate.
|
|
15
|
+
# @parameter block [Proc] An optional block used to configure the instance.
|
|
29
16
|
def initialize(klass, &block)
|
|
30
17
|
super klass, block
|
|
31
18
|
end
|
|
32
19
|
|
|
20
|
+
# Return a string representation of this define.
|
|
21
|
+
# @returns [String] A string showing the class and block source location.
|
|
33
22
|
def to_s
|
|
34
23
|
"#<#{klass} #{block ? block.source_location.join(':') : 'unknown'}>"
|
|
35
24
|
end
|
|
36
25
|
end
|
|
37
26
|
|
|
27
|
+
# Apply a block to this environment using a {Constructor} proxy, then return the environment.
|
|
28
|
+
# @parameter proxy [Object | Nil] An optional proxy object to delegate unknown method calls to.
|
|
29
|
+
# @parameter arguments [Array] Arguments forwarded to the block.
|
|
30
|
+
# @returns [Environment] The updated environment.
|
|
38
31
|
def construct!(proxy, *arguments, &block)
|
|
39
32
|
constructor = Constructor.new(self, proxy)
|
|
40
33
|
|
|
@@ -45,16 +38,29 @@ module Build
|
|
|
45
38
|
return self
|
|
46
39
|
end
|
|
47
40
|
|
|
41
|
+
# Represents a DSL proxy used to populate an environment using a block-based interface.
|
|
48
42
|
class Constructor
|
|
43
|
+
# Initialize the constructor with an environment and an optional proxy object.
|
|
44
|
+
# @parameter environment [Environment] The environment to populate.
|
|
45
|
+
# @parameter proxy [Object | Nil] An optional proxy for delegating unknown method calls.
|
|
49
46
|
def initialize(environment, proxy = nil)
|
|
50
47
|
@environment = environment
|
|
51
48
|
@proxy = proxy
|
|
52
49
|
end
|
|
53
50
|
|
|
51
|
+
# Check whether the constructor responds to the given method name.
|
|
52
|
+
# @parameter name [Symbol] The method name to check.
|
|
53
|
+
# @parameter include_private [Boolean] Whether to include private methods.
|
|
54
|
+
# @returns [Boolean] `true` if the environment includes the key or the proxy responds to the method.
|
|
54
55
|
def respond_to?(name, include_private = false)
|
|
55
56
|
@environment.include?(name) || @proxy&.respond_to?(name, include_private) || super
|
|
56
57
|
end
|
|
57
58
|
|
|
59
|
+
# Dynamically set environment keys or delegate to the proxy object.
|
|
60
|
+
# @parameter name [Symbol] The key name or proxy method name.
|
|
61
|
+
# @parameter args [Array] Positional arguments: a single value, multiple values, or none (with a block).
|
|
62
|
+
# @parameter options [Hash] Keyword arguments forwarded to the proxy.
|
|
63
|
+
# @parameter block [Proc] A block used as the value when no positional arguments are given.
|
|
58
64
|
def method_missing(name, *args, **options, &block)
|
|
59
65
|
if options.empty?
|
|
60
66
|
if args.empty? and block_given?
|
|
@@ -84,40 +90,64 @@ module Build
|
|
|
84
90
|
end
|
|
85
91
|
end
|
|
86
92
|
|
|
93
|
+
# Delegate `respond_to` to the proxy if available.
|
|
94
|
+
# @returns [Boolean] `true` if the constructor or proxy responds to the given arguments.
|
|
87
95
|
def respond_to(*args)
|
|
88
96
|
super or @proxy&.respond_to(*args)
|
|
89
97
|
end
|
|
90
98
|
|
|
99
|
+
# Retrieve the value of a key from the underlying environment.
|
|
100
|
+
# @parameter key [Symbol] The key to look up.
|
|
101
|
+
# @returns [Object | Nil] The value associated with the key.
|
|
91
102
|
def [] key
|
|
92
103
|
@environment[key]
|
|
93
104
|
end
|
|
94
105
|
|
|
106
|
+
# Return the parent of the underlying environment.
|
|
107
|
+
# @returns [Environment | Nil] The parent environment.
|
|
95
108
|
def parent
|
|
96
109
|
@environment.parent
|
|
97
110
|
end
|
|
98
111
|
|
|
112
|
+
# Create an `OpenStruct` from the given keyword options.
|
|
113
|
+
# @parameter options [Hash] The key-value pairs for the struct.
|
|
114
|
+
# @returns [OpenStruct] A new struct with the given options.
|
|
99
115
|
def hash(**options)
|
|
100
116
|
OpenStruct.new(options)
|
|
101
117
|
end
|
|
102
118
|
|
|
119
|
+
# Mark the current value of a key as the default, wrapping it in a `Default` struct.
|
|
120
|
+
# @parameter name [Symbol] The key whose value should be treated as a default.
|
|
121
|
+
# @returns [Symbol] The key name.
|
|
103
122
|
def default(name)
|
|
104
123
|
@environment[name] = Default.new(@environment[name])
|
|
105
124
|
|
|
106
125
|
return name
|
|
107
126
|
end
|
|
108
127
|
|
|
128
|
+
# Mark the current value of a key for replacement, wrapping it in a `Replace` struct.
|
|
129
|
+
# @parameter name [Symbol] The key whose value should be replaced.
|
|
130
|
+
# @returns [Symbol] The key name.
|
|
109
131
|
def replace(name)
|
|
110
132
|
@environment[name] = Replace.new(@environment[name])
|
|
111
133
|
|
|
112
134
|
return name
|
|
113
135
|
end
|
|
114
136
|
|
|
137
|
+
# Convert the current value of a key to an array to allow appending.
|
|
138
|
+
# @parameter name [Symbol] The key whose value should be converted to an array.
|
|
139
|
+
# @returns [Symbol] The key name.
|
|
115
140
|
def append(name)
|
|
116
141
|
@environment[name] = Array(@environment[name])
|
|
117
142
|
|
|
118
143
|
return name
|
|
119
144
|
end
|
|
120
145
|
|
|
146
|
+
# Associate a class and configuration block with a key as a `Define` struct.
|
|
147
|
+
# @parameter klass [Class] The class to associate with the key.
|
|
148
|
+
# @parameter name [Symbol] The key to define.
|
|
149
|
+
# @parameter block [Proc] A block used to configure the class instance.
|
|
150
|
+
# @returns [Symbol] The key name.
|
|
121
151
|
def define(klass, name, &block)
|
|
122
152
|
@environment[name] = Define.new(klass, &block)
|
|
123
153
|
|
|
@@ -138,6 +168,10 @@ module Build
|
|
|
138
168
|
end
|
|
139
169
|
end
|
|
140
170
|
|
|
171
|
+
# Create a new child environment inheriting from this one, with optional keyword options and block.
|
|
172
|
+
# @parameter options [Hash] Options forwarded to the new environment's constructor.
|
|
173
|
+
# @parameter block [Proc] An optional update block for the new environment.
|
|
174
|
+
# @returns [Environment] A new environment with `self` as the parent.
|
|
141
175
|
def merge(**options, &block)
|
|
142
176
|
self.class.new(self, **options, &block)
|
|
143
177
|
end
|
|
@@ -151,6 +185,8 @@ module Build
|
|
|
151
185
|
return flat
|
|
152
186
|
end
|
|
153
187
|
|
|
188
|
+
# Recursively collect this environment and its ancestors into an array, parent first.
|
|
189
|
+
# @parameter array [Array] The array to append environments into.
|
|
154
190
|
def flatten_to_array(array)
|
|
155
191
|
if @parent
|
|
156
192
|
@parent.flatten_to_array(array)
|
|
@@ -1,31 +1,21 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2015-2026, by Samuel Williams.
|
|
20
5
|
|
|
21
6
|
module Build
|
|
22
7
|
class Environment
|
|
8
|
+
# Represents a lazy evaluator that resolves and caches environment values on demand.
|
|
23
9
|
class Evaluator
|
|
10
|
+
# Initialize the evaluator with an environment.
|
|
11
|
+
# @parameter environment [Environment] The environment whose values will be evaluated.
|
|
24
12
|
def initialize(environment)
|
|
25
13
|
@environment = environment
|
|
26
14
|
@cache = {}
|
|
27
15
|
end
|
|
28
16
|
|
|
17
|
+
# Copy the environment reference and cache when duplicating.
|
|
18
|
+
# @parameter other [Evaluator] The evaluator being duplicated.
|
|
29
19
|
def initialize_dup(other)
|
|
30
20
|
@environment = other.instance_variable_get(:@environment)
|
|
31
21
|
@cache = other.instance_variable_get(:@cache).dup
|
|
@@ -33,10 +23,17 @@ module Build
|
|
|
33
23
|
super
|
|
34
24
|
end
|
|
35
25
|
|
|
26
|
+
# Check whether the evaluator responds to a given method name.
|
|
27
|
+
# @parameter name [Symbol] The method name to check.
|
|
28
|
+
# @parameter include_private [Boolean] Whether to include private methods.
|
|
29
|
+
# @returns [Boolean] `true` if the environment contains the key or the evaluator responds via `super`.
|
|
36
30
|
def respond_to?(name, include_private = false)
|
|
37
31
|
@environment.include?(name) || super
|
|
38
32
|
end
|
|
39
33
|
|
|
34
|
+
# Evaluate and cache the value for the named key.
|
|
35
|
+
# @parameter name [Symbol] The key to resolve from the environment.
|
|
36
|
+
# @returns [Object] The resolved and cached value.
|
|
40
37
|
def method_missing(name)
|
|
41
38
|
@cache[name] ||= object_value(@environment[name])
|
|
42
39
|
end
|
|
@@ -1,27 +1,15 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
20
2
|
|
|
21
|
-
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2015-2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
require "digest/md5"
|
|
7
|
+
require "ostruct"
|
|
22
8
|
|
|
23
9
|
module Build
|
|
24
10
|
class Environment
|
|
11
|
+
# Evaluate all environment layers into a single flat hash with all values resolved.
|
|
12
|
+
# @returns [Hash] A hash mapping all keys to their fully evaluated values.
|
|
25
13
|
def to_h
|
|
26
14
|
hash = {}
|
|
27
15
|
|
|
@@ -35,14 +23,22 @@ module Build
|
|
|
35
23
|
Hash[hash.map{|key, value| [key, evaluator.object_value(value)]}]
|
|
36
24
|
end
|
|
37
25
|
|
|
26
|
+
# Create a new {Evaluator} for this environment.
|
|
27
|
+
# @returns [Evaluator] An evaluator backed by this environment.
|
|
38
28
|
def evaluator
|
|
39
29
|
Evaluator.new(self)
|
|
40
30
|
end
|
|
41
31
|
|
|
32
|
+
# Flatten and evaluate all values, returning a new single-layer environment.
|
|
33
|
+
# @parameter options [Hash] Options forwarded to the new environment's constructor.
|
|
34
|
+
# @returns [Environment] A new environment with all values fully evaluated.
|
|
42
35
|
def evaluate(**options)
|
|
43
36
|
self.class.new(nil, self.to_h, **options)
|
|
44
37
|
end
|
|
45
38
|
|
|
39
|
+
# Merge all environment layers into a single-level environment without evaluating values.
|
|
40
|
+
# @parameter options [Hash] Options forwarded to the new environment's constructor.
|
|
41
|
+
# @returns [Environment] A flat environment containing the merged but unevaluated values.
|
|
46
42
|
def flatten(**options)
|
|
47
43
|
hash = {}
|
|
48
44
|
|
|
@@ -53,10 +49,15 @@ module Build
|
|
|
53
49
|
return self.class.new(nil, hash, **options)
|
|
54
50
|
end
|
|
55
51
|
|
|
52
|
+
# Return all key-value pairs in the current layer whose values are `Define` instances.
|
|
53
|
+
# @returns [Hash] A hash of keys mapped to their `Define` values.
|
|
56
54
|
def defined
|
|
57
55
|
@values.select{|name,value| Define === value}
|
|
58
56
|
end
|
|
59
57
|
|
|
58
|
+
# Compute a hex digest checksum of the environment's content.
|
|
59
|
+
# @parameter digester [Digest] The digest algorithm to use.
|
|
60
|
+
# @returns [String] The hexadecimal digest string.
|
|
60
61
|
def checksum(digester: Digest::SHA1.new)
|
|
61
62
|
checksum_recursively(digester)
|
|
62
63
|
|
|
@@ -1,36 +1,28 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2015-2026, by Samuel Williams.
|
|
20
5
|
|
|
21
6
|
module Build
|
|
22
7
|
class Environment
|
|
8
|
+
# Provides utilities for converting environment values to shell-compatible strings.
|
|
23
9
|
module System
|
|
10
|
+
# Escape a value for safe use in a shell command string.
|
|
11
|
+
# @parameter value [String | Array] The value to escape.
|
|
12
|
+
# @returns [String] The shell-escaped string.
|
|
24
13
|
def self.shell_escape(value)
|
|
25
14
|
case value
|
|
26
15
|
when Array
|
|
27
|
-
value.flatten.collect{|argument| shell_escape(argument)}.join(
|
|
16
|
+
value.flatten.collect{|argument| shell_escape(argument)}.join(" ")
|
|
28
17
|
else
|
|
29
18
|
# Ensure that any whitespace has been escaped:
|
|
30
19
|
value.to_s.gsub(/ /, '\ ')
|
|
31
20
|
end
|
|
32
21
|
end
|
|
33
22
|
|
|
23
|
+
# Check whether a value is suitable for export to a shell environment.
|
|
24
|
+
# @parameter value [Object] The value to check.
|
|
25
|
+
# @returns [Boolean] `true` if the value can be exported, `false` otherwise.
|
|
34
26
|
def self.valid_for_export(value)
|
|
35
27
|
case value
|
|
36
28
|
when Array
|
|
@@ -50,6 +42,9 @@ module Build
|
|
|
50
42
|
end
|
|
51
43
|
end
|
|
52
44
|
|
|
45
|
+
# Convert an environment to a shell-compatible hash with uppercase string keys and escaped string values.
|
|
46
|
+
# @parameter environment [Environment] The environment to convert.
|
|
47
|
+
# @returns [Hash] A hash of uppercase string keys mapped to shell-escaped string values.
|
|
53
48
|
def self.convert_to_shell(environment)
|
|
54
49
|
values = environment.values.select{|key, value| valid_for_export(value)}
|
|
55
50
|
|
data/lib/build/environment.rb
CHANGED
|
@@ -1,25 +1,10 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
|
11
|
-
# all copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
-
# THE SOFTWARE.
|
|
1
|
+
# frozen_string_literal: true
|
|
20
2
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
require_relative
|
|
25
|
-
require_relative
|
|
3
|
+
# Released under the MIT License.
|
|
4
|
+
# Copyright, 2015-2026, by Samuel Williams.
|
|
5
|
+
|
|
6
|
+
require_relative "environment/base"
|
|
7
|
+
require_relative "environment/constructor"
|
|
8
|
+
require_relative "environment/evaluator"
|
|
9
|
+
require_relative "environment/flatten"
|
|
10
|
+
require_relative "environment/system"
|
data/license.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright, 2015-2026, by Samuel Williams.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/readme.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Build::Environment
|
|
2
|
+
|
|
3
|
+
Build::Environment provides a nested hash data structure which can contain lambdas for evaluating environments for generating appropriate build environments.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/ioquatix/build-environment/actions?workflow=Test)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
Please see the [project documentation](https://ioquatix.github.io/build-environment) for more details.
|
|
10
|
+
|
|
11
|
+
- [Getting Started](https://ioquatix.github.io/build-environmentguides/getting-started/index) - This guide explains how to get started with `build-environment`, a nested key-value data structure for organising build configurations.
|
|
12
|
+
|
|
13
|
+
## Releases
|
|
14
|
+
|
|
15
|
+
Please see the [project releases](https://ioquatix.github.io/build-environmentreleases/index) for all releases.
|
|
16
|
+
|
|
17
|
+
### v1.13.1
|
|
18
|
+
|
|
19
|
+
## Contributing
|
|
20
|
+
|
|
21
|
+
We welcome contributions to this project.
|
|
22
|
+
|
|
23
|
+
1. Fork it.
|
|
24
|
+
2. Create your feature branch (`git checkout -b my-new-feature`).
|
|
25
|
+
3. Commit your changes (`git commit -am 'Add some feature'`).
|
|
26
|
+
4. Push to the branch (`git push origin my-new-feature`).
|
|
27
|
+
5. Create new Pull Request.
|
|
28
|
+
|
|
29
|
+
### Developer Certificate of Origin
|
|
30
|
+
|
|
31
|
+
In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
|
|
32
|
+
|
|
33
|
+
### Community Guidelines
|
|
34
|
+
|
|
35
|
+
This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
|
data/releases.md
ADDED
data.tar.gz.sig
ADDED
|
Binary file
|