stack_master 2.17.0 → 2.18.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 +1 -6
- data/bin/stack_master +3 -5
- data/lib/stack_master/aws_driver/cloud_formation.rb +25 -23
- data/lib/stack_master/aws_driver/s3.rb +24 -17
- data/lib/stack_master/change_set.rb +11 -15
- data/lib/stack_master/cli.rb +53 -32
- data/lib/stack_master/command.rb +1 -5
- data/lib/stack_master/commands/apply.rb +39 -20
- data/lib/stack_master/commands/delete.rb +6 -7
- data/lib/stack_master/commands/drift.rb +11 -12
- data/lib/stack_master/commands/events.rb +4 -6
- data/lib/stack_master/commands/init.rb +21 -20
- data/lib/stack_master/commands/lint.rb +1 -1
- data/lib/stack_master/commands/list_stacks.rb +1 -1
- data/lib/stack_master/commands/nag.rb +0 -1
- data/lib/stack_master/commands/outputs.rb +1 -1
- data/lib/stack_master/commands/resources.rb +9 -1
- data/lib/stack_master/commands/status.rb +4 -4
- data/lib/stack_master/commands/terminal_helper.rb +3 -3
- data/lib/stack_master/commands/tidy.rb +14 -13
- data/lib/stack_master/config.rb +23 -21
- data/lib/stack_master/diff.rb +2 -2
- data/lib/stack_master/identity.rb +2 -1
- data/lib/stack_master/parameter_loader.rb +3 -5
- data/lib/stack_master/parameter_resolver.rb +18 -18
- data/lib/stack_master/parameter_resolvers/acm_certificate.rb +4 -1
- data/lib/stack_master/parameter_resolvers/ami_finder.rb +2 -3
- data/lib/stack_master/parameter_resolvers/ejson.rb +9 -6
- data/lib/stack_master/parameter_resolvers/env.rb +1 -2
- data/lib/stack_master/parameter_resolvers/latest_ami_by_tags.rb +1 -1
- data/lib/stack_master/parameter_resolvers/latest_container.rb +9 -7
- data/lib/stack_master/parameter_resolvers/one_password.rb +11 -7
- data/lib/stack_master/parameter_resolvers/parameter_store.rb +1 -5
- data/lib/stack_master/parameter_resolvers/security_group.rb +1 -1
- data/lib/stack_master/parameter_resolvers/sso_group_id.rb +3 -2
- data/lib/stack_master/parameter_resolvers/stack_output.rb +7 -9
- data/lib/stack_master/parameter_validator.rb +2 -5
- data/lib/stack_master/prompter.rb +11 -10
- data/lib/stack_master/resolver_array.rb +2 -3
- data/lib/stack_master/role_assumer.rb +7 -5
- data/lib/stack_master/security_group_finder.rb +7 -5
- data/lib/stack_master/sns_topic_finder.rb +4 -3
- data/lib/stack_master/sparkle_formation/compile_time/allowed_pattern_validator.rb +2 -3
- data/lib/stack_master/sparkle_formation/compile_time/allowed_values_validator.rb +2 -3
- data/lib/stack_master/sparkle_formation/compile_time/definitions_validator.rb +6 -6
- data/lib/stack_master/sparkle_formation/compile_time/empty_validator.rb +0 -2
- data/lib/stack_master/sparkle_formation/compile_time/max_length_validator.rb +1 -2
- data/lib/stack_master/sparkle_formation/compile_time/max_size_validator.rb +1 -2
- data/lib/stack_master/sparkle_formation/compile_time/min_length_validator.rb +2 -3
- data/lib/stack_master/sparkle_formation/compile_time/min_size_validator.rb +2 -3
- data/lib/stack_master/sparkle_formation/compile_time/number_validator.rb +1 -2
- data/lib/stack_master/sparkle_formation/compile_time/parameters_validator.rb +0 -1
- data/lib/stack_master/sparkle_formation/compile_time/state_builder.rb +0 -2
- data/lib/stack_master/sparkle_formation/compile_time/string_validator.rb +2 -3
- data/lib/stack_master/sparkle_formation/compile_time/value_builder.rb +7 -9
- data/lib/stack_master/sparkle_formation/compile_time/value_validator.rb +3 -6
- data/lib/stack_master/sparkle_formation/compile_time/value_validator_factory.rb +11 -13
- data/lib/stack_master/sparkle_formation/template_file.rb +2 -4
- data/lib/stack_master/sso_group_id_finder.rb +15 -12
- data/lib/stack_master/stack.rb +51 -18
- data/lib/stack_master/stack_definition.rb +6 -5
- data/lib/stack_master/stack_differ.rb +36 -9
- data/lib/stack_master/stack_events/fetcher.rb +3 -1
- data/lib/stack_master/stack_events/presenter.rb +6 -1
- data/lib/stack_master/stack_events/streamer.rb +3 -1
- data/lib/stack_master/stack_status.rb +1 -0
- data/lib/stack_master/template_compilers/json.rb +1 -1
- data/lib/stack_master/template_compilers/sparkle_formation.rb +12 -9
- data/lib/stack_master/template_utils.rb +8 -4
- data/lib/stack_master/test_driver/cloud_formation.rb +34 -9
- data/lib/stack_master/test_driver/s3.rb +2 -3
- data/lib/stack_master/utils.rb +4 -6
- data/lib/stack_master/validator.rb +7 -6
- data/lib/stack_master/version.rb +1 -1
- data/lib/stack_master.rb +3 -1
- metadata +21 -10
- data/lib/stack_master/parameter_resolvers/accounts_by_tags.rb +0 -60
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module StackMaster
|
|
2
2
|
module ParameterResolvers
|
|
3
3
|
class Env < Resolver
|
|
4
|
-
|
|
5
4
|
def initialize(config, stack_definition)
|
|
6
5
|
@config = config
|
|
7
6
|
@stack_definition = stack_definition
|
|
@@ -10,9 +9,9 @@ module StackMaster
|
|
|
10
9
|
def resolve(value)
|
|
11
10
|
environment_variable = ENV[value]
|
|
12
11
|
raise ArgumentError, "The environment variable #{value} is not set" if environment_variable.nil?
|
|
12
|
+
|
|
13
13
|
environment_variable
|
|
14
14
|
end
|
|
15
|
-
|
|
16
15
|
end
|
|
17
16
|
end
|
|
18
17
|
end
|
|
@@ -10,7 +10,7 @@ module StackMaster
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def resolve(value)
|
|
13
|
-
filters = @ami_finder.build_filters_from_string(value, prefix =
|
|
13
|
+
filters = @ami_finder.build_filters_from_string(value, prefix = 'tag')
|
|
14
14
|
@ami_finder.find_latest_ami(filters)&.image_id
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -10,7 +10,7 @@ module StackMaster
|
|
|
10
10
|
|
|
11
11
|
def resolve(parameters)
|
|
12
12
|
if parameters['repository_name'].nil?
|
|
13
|
-
raise ArgumentError,
|
|
13
|
+
raise ArgumentError, 'repository_name parameter is required but was not supplied'
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
@region = parameters['region'] || @stack_definition.region
|
|
@@ -28,7 +28,8 @@ module StackMaster
|
|
|
28
28
|
latest_image = images.first
|
|
29
29
|
|
|
30
30
|
# aws_account_id.dkr.ecr.region.amazonaws.com/repository@sha256:digest
|
|
31
|
-
"#{latest_image.registry_id}.dkr.ecr.#{@region}.amazonaws.com/#{parameters['repository_name']}
|
|
31
|
+
"#{latest_image.registry_id}.dkr.ecr.#{@region}.amazonaws.com/#{parameters['repository_name']}@" \
|
|
32
|
+
"#{latest_image.image_digest}"
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
private
|
|
@@ -36,15 +37,16 @@ module StackMaster
|
|
|
36
37
|
def fetch_images(repository_name, registry_id, ecr)
|
|
37
38
|
images = []
|
|
38
39
|
next_token = nil
|
|
39
|
-
while
|
|
40
|
-
|
|
40
|
+
while resp = ecr.describe_images(
|
|
41
|
+
{
|
|
41
42
|
repository_name: repository_name,
|
|
42
43
|
registry_id: registry_id,
|
|
43
44
|
next_token: next_token,
|
|
44
45
|
filter: {
|
|
45
|
-
tag_status:
|
|
46
|
-
}
|
|
47
|
-
}
|
|
46
|
+
tag_status: 'TAGGED'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
)
|
|
48
50
|
|
|
49
51
|
images += resp.image_details
|
|
50
52
|
next_token = resp.next_token
|
|
@@ -13,15 +13,19 @@ module StackMaster
|
|
|
13
13
|
@stack_definition = stack_definition
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def resolve(params={})
|
|
17
|
-
|
|
16
|
+
def resolve(params = {})
|
|
17
|
+
if ENV.keys.grep(/OP_SESSION_\w+$/).empty?
|
|
18
|
+
raise OnePasswordNotAbleToAuthenticate,
|
|
19
|
+
'1password requires the `OP_SESSION_<name>` to be set, (remember to sign in?)'
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
get_items(params)
|
|
19
23
|
end
|
|
20
24
|
|
|
21
25
|
private
|
|
22
26
|
|
|
23
27
|
def validate_op_installed?
|
|
24
|
-
|
|
28
|
+
`op --version`
|
|
25
29
|
rescue Errno::ENOENT => exception
|
|
26
30
|
raise OnePasswordBinaryNotFound, "The op cli needs to be installed and in the PATH, #{exception}"
|
|
27
31
|
end
|
|
@@ -40,7 +44,7 @@ module StackMaster
|
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
def password_item(data)
|
|
43
|
-
data.details.password
|
|
47
|
+
data.details.password
|
|
44
48
|
end
|
|
45
49
|
|
|
46
50
|
def login_item(data)
|
|
@@ -49,7 +53,7 @@ module StackMaster
|
|
|
49
53
|
|
|
50
54
|
def op_get_item(item, vault)
|
|
51
55
|
validate_op_installed?
|
|
52
|
-
item =
|
|
56
|
+
item = `op get item --vault='#{vault}' '#{item}' 2>&1`
|
|
53
57
|
item if validate_response?(item)
|
|
54
58
|
end
|
|
55
59
|
|
|
@@ -75,9 +79,9 @@ module StackMaster
|
|
|
75
79
|
def get_items(params)
|
|
76
80
|
case params['type']
|
|
77
81
|
when 'password'
|
|
78
|
-
|
|
82
|
+
get_password(params['title'], params['vault'])
|
|
79
83
|
when 'secureNote'
|
|
80
|
-
|
|
84
|
+
get_secure_note(params['title'], params['vault'])
|
|
81
85
|
end
|
|
82
86
|
end
|
|
83
87
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
module StackMaster
|
|
2
2
|
module ParameterResolvers
|
|
3
3
|
class ParameterStore < Resolver
|
|
4
|
-
|
|
5
4
|
ParameterNotFound = Class.new(StandardError)
|
|
6
5
|
|
|
7
6
|
def initialize(config, stack_definition)
|
|
@@ -12,10 +11,7 @@ module StackMaster
|
|
|
12
11
|
def resolve(value)
|
|
13
12
|
begin
|
|
14
13
|
ssm = Aws::SSM::Client.new({ region: @stack_definition.region })
|
|
15
|
-
resp = ssm.get_parameter({
|
|
16
|
-
name: value,
|
|
17
|
-
with_decryption: true
|
|
18
|
-
})
|
|
14
|
+
resp = ssm.get_parameter({ name: value, with_decryption: true })
|
|
19
15
|
rescue Aws::SSM::Errors::ParameterNotFound
|
|
20
16
|
raise ParameterNotFound, "Unable to find #{value} in Parameter Store"
|
|
21
17
|
end
|
|
@@ -17,16 +17,14 @@ module StackMaster
|
|
|
17
17
|
def resolve(value)
|
|
18
18
|
region, stack_name, output_name = parse!(value)
|
|
19
19
|
stack = find_stack(stack_name, region)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
else
|
|
25
|
-
raise StackOutputNotFound, "Stack exists (#{stack_name}), but output does not: #{output_name}"
|
|
26
|
-
end
|
|
27
|
-
else
|
|
28
|
-
raise StackNotFound, "Stack in StackOutput not found: #{value}"
|
|
20
|
+
raise StackNotFound, "Stack in StackOutput not found: #{value}" unless stack
|
|
21
|
+
|
|
22
|
+
output = stack.outputs.find do |stack_output|
|
|
23
|
+
stack_output.output_key == output_name.camelize || stack_output.output_key == output_name
|
|
29
24
|
end
|
|
25
|
+
raise StackOutputNotFound, "Stack exists (#{stack_name}), but output does not: #{output_name}" unless output
|
|
26
|
+
|
|
27
|
+
output.output_value
|
|
30
28
|
end
|
|
31
29
|
|
|
32
30
|
private
|
|
@@ -9,15 +9,12 @@ module StackMaster
|
|
|
9
9
|
|
|
10
10
|
def error_message
|
|
11
11
|
return nil unless missing_parameters?
|
|
12
|
+
|
|
12
13
|
message = "Empty/blank parameters detected. Please provide values for these parameters:\n"
|
|
13
14
|
missing_parameters.each do |parameter_name|
|
|
14
15
|
message << " - #{parameter_name}\n"
|
|
15
16
|
end
|
|
16
|
-
|
|
17
|
-
message << message_for_parameter_globs
|
|
18
|
-
else
|
|
19
|
-
message << message_for_parameter_files
|
|
20
|
-
end
|
|
17
|
+
message << (@stack_definition.parameter_files.empty? ? message_for_parameter_globs : message_for_parameter_files)
|
|
21
18
|
message
|
|
22
19
|
end
|
|
23
20
|
|
|
@@ -4,18 +4,19 @@ module StackMaster
|
|
|
4
4
|
module Prompter
|
|
5
5
|
def ask?(question)
|
|
6
6
|
StackMaster.stdout.print question
|
|
7
|
-
answer =
|
|
8
|
-
if StackMaster.
|
|
9
|
-
StackMaster.stdin.
|
|
7
|
+
answer =
|
|
8
|
+
if StackMaster.interactive?
|
|
9
|
+
if StackMaster.stdin.tty? && StackMaster.stdout.tty?
|
|
10
|
+
StackMaster.stdin.getch.chomp
|
|
11
|
+
else
|
|
12
|
+
StackMaster.stdout.puts
|
|
13
|
+
StackMaster.stdout.puts 'STDOUT or STDIN was not a TTY. Defaulting to no. To force yes use -y'
|
|
14
|
+
'n'
|
|
15
|
+
end
|
|
10
16
|
else
|
|
11
|
-
StackMaster.
|
|
12
|
-
StackMaster.
|
|
13
|
-
'n'
|
|
17
|
+
print StackMaster.non_interactive_answer
|
|
18
|
+
StackMaster.non_interactive_answer
|
|
14
19
|
end
|
|
15
|
-
else
|
|
16
|
-
print StackMaster.non_interactive_answer
|
|
17
|
-
StackMaster.non_interactive_answer
|
|
18
|
-
end
|
|
19
20
|
StackMaster.stdout.puts
|
|
20
21
|
answer == 'y'
|
|
21
22
|
end
|
|
@@ -13,13 +13,13 @@ module StackMaster
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def resolver_class
|
|
16
|
-
|
|
16
|
+
raise "Method resolver_class not implemented on #{self.class}"
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
class Resolver
|
|
21
21
|
def self.array_resolver(options = {})
|
|
22
|
-
resolver_class ||= Object.const_get(
|
|
22
|
+
resolver_class ||= Object.const_get(name)
|
|
23
23
|
array_resolver_class_name = options[:class_name] || resolver_class.to_s.demodulize.pluralize
|
|
24
24
|
|
|
25
25
|
klass = Class.new(ResolverArray) do
|
|
@@ -32,4 +32,3 @@ module StackMaster
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
|
-
|
|
@@ -44,11 +44,13 @@ module StackMaster
|
|
|
44
44
|
def assume_role_credentials(account, role)
|
|
45
45
|
credentials_key = "#{account}:#{role}"
|
|
46
46
|
@credentials.fetch(credentials_key) do
|
|
47
|
-
@credentials[credentials_key] = Aws::AssumeRoleCredentials.new(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
@credentials[credentials_key] = Aws::AssumeRoleCredentials.new(
|
|
48
|
+
{
|
|
49
|
+
region: StackMaster.cloud_formation_driver.region,
|
|
50
|
+
role_arn: "arn:aws:iam::#{account}:role/#{role}",
|
|
51
|
+
role_session_name: 'stack-master-role-assumer'
|
|
52
|
+
}
|
|
53
|
+
)
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
end
|
|
@@ -8,15 +8,17 @@ module StackMaster
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def find(reference)
|
|
11
|
-
|
|
11
|
+
unless reference.is_a?(String) && !reference.empty?
|
|
12
|
+
raise ArgumentError, 'Security group references must be non-empty strings'
|
|
13
|
+
end
|
|
12
14
|
|
|
13
15
|
groups = @resource.security_groups({
|
|
14
16
|
filters: [
|
|
15
17
|
{
|
|
16
|
-
name:
|
|
17
|
-
values: [reference]
|
|
18
|
-
}
|
|
19
|
-
]
|
|
18
|
+
name: 'group-name',
|
|
19
|
+
values: [reference]
|
|
20
|
+
}
|
|
21
|
+
]
|
|
20
22
|
})
|
|
21
23
|
|
|
22
24
|
raise SecurityGroupNotFound, "No security group with name #{reference} found" unless groups.any?
|
|
@@ -7,7 +7,9 @@ module StackMaster
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def find(reference)
|
|
10
|
-
|
|
10
|
+
unless reference.is_a?(String) && !reference.empty?
|
|
11
|
+
raise ArgumentError, 'SNS topic references must be non-empty strings'
|
|
12
|
+
end
|
|
11
13
|
|
|
12
14
|
topic = @resource.topics.detect { |t| topic_name_from_arn(t.arn) == reference }
|
|
13
15
|
|
|
@@ -19,8 +21,7 @@ module StackMaster
|
|
|
19
21
|
private
|
|
20
22
|
|
|
21
23
|
def topic_name_from_arn(arn)
|
|
22
|
-
arn.split(
|
|
24
|
+
arn.split(':')[5]
|
|
23
25
|
end
|
|
24
|
-
|
|
25
26
|
end
|
|
26
27
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class AllowedPatternValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
KEY = :allowed_pattern
|
|
9
8
|
|
|
10
9
|
def initialize(name, definition, parameter)
|
|
@@ -17,18 +16,18 @@ module StackMaster
|
|
|
17
16
|
|
|
18
17
|
def check_is_valid
|
|
19
18
|
return true unless @definition.key?(KEY)
|
|
19
|
+
|
|
20
20
|
invalid_values.empty?
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def invalid_values
|
|
24
24
|
values = build_values(@definition, @parameter)
|
|
25
|
-
values.reject { |value| value.to_s.match(
|
|
25
|
+
values.reject { |value| value.to_s.match(/#{@definition[KEY]}/) }
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def create_error
|
|
29
29
|
"#{@name}:#{invalid_values} does not match #{KEY}:#{@definition[KEY]}"
|
|
30
30
|
end
|
|
31
|
-
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
33
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class AllowedValuesValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
KEY = :allowed_values
|
|
9
8
|
|
|
10
9
|
def initialize(name, definition, parameter)
|
|
@@ -17,20 +16,20 @@ module StackMaster
|
|
|
17
16
|
|
|
18
17
|
def check_is_valid
|
|
19
18
|
return true unless @definition.key?(KEY)
|
|
19
|
+
|
|
20
20
|
invalid_values.empty?
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def invalid_values
|
|
24
24
|
values = build_values(@definition, @parameter)
|
|
25
25
|
values.reject do |value|
|
|
26
|
-
@definition[KEY].any? { |allowed_value| allowed_value.to_s == value.to_s}
|
|
26
|
+
@definition[KEY].any? { |allowed_value| allowed_value.to_s == value.to_s }
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def create_error
|
|
31
31
|
"#{@name}:#{invalid_values} is not in #{KEY}:#{@definition[KEY]}"
|
|
32
32
|
end
|
|
33
|
-
|
|
34
33
|
end
|
|
35
34
|
end
|
|
36
35
|
end
|
|
@@ -4,16 +4,17 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class DefinitionsValidator
|
|
7
|
-
|
|
8
|
-
VALID_TYPES = [:string, :number]
|
|
7
|
+
VALID_TYPES = %i[string number]
|
|
9
8
|
def initialize(definitions)
|
|
10
9
|
@definitions = definitions
|
|
11
10
|
end
|
|
12
11
|
|
|
13
12
|
def validate
|
|
14
|
-
@definitions.each do|name, definition|
|
|
13
|
+
@definitions.each do |name, definition|
|
|
15
14
|
type = definition[:type]
|
|
16
|
-
|
|
15
|
+
unless is_valid(type)
|
|
16
|
+
raise ArgumentError.new "Unknown compile time parameter type: #{create_error(name, type)}"
|
|
17
|
+
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -26,8 +27,7 @@ module StackMaster
|
|
|
26
27
|
def create_error(name, type)
|
|
27
28
|
"#{name}:#{type} valid types are #{VALID_TYPES}"
|
|
28
29
|
end
|
|
29
|
-
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
|
-
end
|
|
33
|
+
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class EmptyValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
def initialize(name, definition, parameter)
|
|
9
8
|
@name = name
|
|
10
9
|
@definition = definition
|
|
@@ -25,7 +24,6 @@ module StackMaster
|
|
|
25
24
|
def create_error
|
|
26
25
|
"#{@name} cannot contain empty parameters:#{@parameter.inspect}"
|
|
27
26
|
end
|
|
28
|
-
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class MaxLengthValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
KEY = :max_length
|
|
9
8
|
|
|
10
9
|
def initialize(name, definition, parameter)
|
|
@@ -18,6 +17,7 @@ module StackMaster
|
|
|
18
17
|
def check_is_valid
|
|
19
18
|
return true unless @definition[:type] == :string
|
|
20
19
|
return true unless @definition.key?(KEY)
|
|
20
|
+
|
|
21
21
|
invalid_values.empty?
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -29,7 +29,6 @@ module StackMaster
|
|
|
29
29
|
def create_error
|
|
30
30
|
"#{@name}:#{invalid_values} must not exceed #{KEY}:#{@definition[KEY]} characters"
|
|
31
31
|
end
|
|
32
|
-
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class MaxSizeValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
KEY = :max_size
|
|
9
8
|
|
|
10
9
|
def initialize(name, definition, parameter)
|
|
@@ -18,6 +17,7 @@ module StackMaster
|
|
|
18
17
|
def check_is_valid
|
|
19
18
|
return true unless @definition[:type] == :number
|
|
20
19
|
return true unless @definition.key?(KEY)
|
|
20
|
+
|
|
21
21
|
invalid_values.empty?
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -29,7 +29,6 @@ module StackMaster
|
|
|
29
29
|
def create_error
|
|
30
30
|
"#{@name}:#{invalid_values} must not be greater than #{KEY}:#{@definition[KEY]}"
|
|
31
31
|
end
|
|
32
|
-
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class MinLengthValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
KEY = :min_length
|
|
9
8
|
|
|
10
9
|
def initialize(name, definition, parameter)
|
|
@@ -18,18 +17,18 @@ module StackMaster
|
|
|
18
17
|
def check_is_valid
|
|
19
18
|
return true unless @definition[:type] == :string
|
|
20
19
|
return true unless @definition.key?(KEY)
|
|
20
|
+
|
|
21
21
|
invalid_values.empty?
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def invalid_values
|
|
25
25
|
values = build_values(@definition, @parameter)
|
|
26
|
-
values.select { |value| value.length < @definition[KEY].to_i}
|
|
26
|
+
values.select { |value| value.length < @definition[KEY].to_i }
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def create_error
|
|
30
30
|
"#{@name}:#{invalid_values} must be at least #{KEY}:#{@definition[KEY]} characters"
|
|
31
31
|
end
|
|
32
|
-
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class MinSizeValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
KEY = :min_size
|
|
9
8
|
|
|
10
9
|
def initialize(name, definition, parameter)
|
|
@@ -18,18 +17,18 @@ module StackMaster
|
|
|
18
17
|
def check_is_valid
|
|
19
18
|
return true unless @definition[:type] == :number
|
|
20
19
|
return true unless @definition.key?(KEY)
|
|
20
|
+
|
|
21
21
|
invalid_values.empty?
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def invalid_values
|
|
25
25
|
values = build_values(@definition, @parameter)
|
|
26
|
-
values.select { |value| value.to_f < @definition[KEY].to_f}
|
|
26
|
+
values.select { |value| value.to_f < @definition[KEY].to_f }
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def create_error
|
|
30
30
|
"#{@name}:#{invalid_values} must not be lesser than #{KEY}:#{@definition[KEY]}"
|
|
31
31
|
end
|
|
32
|
-
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class NumberValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
def initialize(name, definition, parameter)
|
|
9
8
|
@name = name
|
|
10
9
|
@definition = definition
|
|
@@ -15,6 +14,7 @@ module StackMaster
|
|
|
15
14
|
|
|
16
15
|
def check_is_valid
|
|
17
16
|
return true unless @definition[:type] == :number
|
|
17
|
+
|
|
18
18
|
invalid_values.empty?
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -28,7 +28,6 @@ module StackMaster
|
|
|
28
28
|
def create_error
|
|
29
29
|
"#{@name}:#{invalid_values} are not Numbers"
|
|
30
30
|
end
|
|
31
|
-
|
|
32
31
|
end
|
|
33
32
|
end
|
|
34
33
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class StateBuilder
|
|
7
|
-
|
|
8
7
|
def initialize(definitions, parameters)
|
|
9
8
|
@definitions = definitions
|
|
10
9
|
@parameters = parameters
|
|
@@ -25,7 +24,6 @@ module StackMaster
|
|
|
25
24
|
def create_value(definition, parameter)
|
|
26
25
|
ValueBuilder.new(definition, parameter).build
|
|
27
26
|
end
|
|
28
|
-
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
end
|
|
@@ -4,7 +4,6 @@ module StackMaster
|
|
|
4
4
|
module SparkleFormation
|
|
5
5
|
module CompileTime
|
|
6
6
|
class StringValidator < ValueValidator
|
|
7
|
-
|
|
8
7
|
def initialize(name, definition, parameter)
|
|
9
8
|
@name = name
|
|
10
9
|
@definition = definition
|
|
@@ -15,18 +14,18 @@ module StackMaster
|
|
|
15
14
|
|
|
16
15
|
def check_is_valid
|
|
17
16
|
return true unless @definition[:type] == :string
|
|
17
|
+
|
|
18
18
|
invalid_values.empty?
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def invalid_values
|
|
22
22
|
values = build_values(@definition, @parameter)
|
|
23
|
-
values.reject { |value| value.is_a?(String)}
|
|
23
|
+
values.reject { |value| value.is_a?(String) }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def create_error
|
|
27
27
|
"#{@name}:#{invalid_values} are not Strings"
|
|
28
28
|
end
|
|
29
|
-
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
end
|
|
@@ -2,7 +2,6 @@ module StackMaster
|
|
|
2
2
|
module SparkleFormation
|
|
3
3
|
module CompileTime
|
|
4
4
|
class ValueBuilder
|
|
5
|
-
|
|
6
5
|
def initialize(definition, parameter)
|
|
7
6
|
@definition = definition
|
|
8
7
|
@parameter = parameter
|
|
@@ -22,18 +21,17 @@ module StackMaster
|
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
def convert_strings_to_array
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
return unless @definition[:multiple] && @value.is_a?(String)
|
|
25
|
+
|
|
26
|
+
@value = @value.split(',').map(&:strip)
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
def convert_strings_to_numbers
|
|
31
|
-
if @definition[:type]
|
|
32
|
-
@value = @value.to_f if @value.is_a?(String)
|
|
33
|
-
@value = @value.map { |item| item.is_a?(String) ? item.to_f : item } if @value.is_a?(Array)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
30
|
+
return if @definition[:type] != :number
|
|
36
31
|
|
|
32
|
+
@value = @value.to_f if @value.is_a?(String)
|
|
33
|
+
@value = @value.map { |item| item.is_a?(String) ? item.to_f : item } if @value.is_a?(Array)
|
|
34
|
+
end
|
|
37
35
|
end
|
|
38
36
|
end
|
|
39
37
|
end
|