parameter_substitution 0.3.0.pre.1 → 1.1.0.pre.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.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/lib/parameter_substitution.rb +1 -2
  3. data/lib/parameter_substitution/configuration.rb +39 -0
  4. data/lib/parameter_substitution/context.rb +74 -0
  5. data/lib/parameter_substitution/encoder.rb +86 -0
  6. data/lib/parameter_substitution/expression.rb +146 -0
  7. data/lib/parameter_substitution/formatters/add_prefix.rb +19 -0
  8. data/lib/parameter_substitution/formatters/base.rb +46 -0
  9. data/lib/parameter_substitution/formatters/blank_if_nil.rb +11 -0
  10. data/lib/parameter_substitution/formatters/cgi_unescape.rb +11 -0
  11. data/lib/parameter_substitution/formatters/compare_string.rb +21 -0
  12. data/lib/parameter_substitution/formatters/date_time_custom.rb +22 -0
  13. data/lib/parameter_substitution/formatters/date_time_format.rb +53 -0
  14. data/lib/parameter_substitution/formatters/date_time_iso8601.rb +11 -0
  15. data/lib/parameter_substitution/formatters/date_time_iso8601_zulu.rb +11 -0
  16. data/lib/parameter_substitution/formatters/date_time_strftime.rb +19 -0
  17. data/lib/parameter_substitution/formatters/date_time_unix_timestamp.rb +11 -0
  18. data/lib/parameter_substitution/formatters/date_time_us_all_slashes.rb +11 -0
  19. data/lib/parameter_substitution/formatters/date_time_us_normal.rb +11 -0
  20. data/lib/parameter_substitution/formatters/date_time_us_seconds.rb +11 -0
  21. data/lib/parameter_substitution/formatters/date_time_us_short_am_pm.rb +11 -0
  22. data/lib/parameter_substitution/formatters/date_time_us_short_year.rb +11 -0
  23. data/lib/parameter_substitution/formatters/date_time_utc_year_first_dashes_seconds.rb +11 -0
  24. data/lib/parameter_substitution/formatters/date_us_dashes.rb +11 -0
  25. data/lib/parameter_substitution/formatters/date_us_normal.rb +11 -0
  26. data/lib/parameter_substitution/formatters/date_year_first_dashes.rb +11 -0
  27. data/lib/parameter_substitution/formatters/downcase.rb +11 -0
  28. data/lib/parameter_substitution/formatters/duration_as_seconds.rb +11 -0
  29. data/lib/parameter_substitution/formatters/duration_as_time.rb +11 -0
  30. data/lib/parameter_substitution/formatters/duration_grouped_by_description.rb +23 -0
  31. data/lib/parameter_substitution/formatters/greater_than_value.rb +21 -0
  32. data/lib/parameter_substitution/formatters/if_nil.rb +19 -0
  33. data/lib/parameter_substitution/formatters/if_truthy.rb +36 -0
  34. data/lib/parameter_substitution/formatters/in_timezone.rb +23 -0
  35. data/lib/parameter_substitution/formatters/json_parse.rb +26 -0
  36. data/lib/parameter_substitution/formatters/left.rb +19 -0
  37. data/lib/parameter_substitution/formatters/lookup.rb +19 -0
  38. data/lib/parameter_substitution/formatters/lower.rb +11 -0
  39. data/lib/parameter_substitution/formatters/manager.rb +35 -0
  40. data/lib/parameter_substitution/formatters/md5.rb +11 -0
  41. data/lib/parameter_substitution/formatters/mid.rb +20 -0
  42. data/lib/parameter_substitution/formatters/parse_time.rb +23 -0
  43. data/lib/parameter_substitution/formatters/right.rb +23 -0
  44. data/lib/parameter_substitution/formatters/sha256.rb +11 -0
  45. data/lib/parameter_substitution/formatters/split_after_colon.rb +11 -0
  46. data/lib/parameter_substitution/formatters/split_and_find.rb +20 -0
  47. data/lib/parameter_substitution/formatters/split_before_colon.rb +11 -0
  48. data/lib/parameter_substitution/formatters/time_with_seconds.rb +11 -0
  49. data/lib/parameter_substitution/formatters/trim.rb +11 -0
  50. data/lib/parameter_substitution/formatters/upper.rb +11 -0
  51. data/lib/parameter_substitution/method_call_expression.rb +58 -0
  52. data/lib/parameter_substitution/parse_error.rb +6 -0
  53. data/lib/parameter_substitution/parser.rb +109 -0
  54. data/lib/parameter_substitution/substitution_expression.rb +79 -0
  55. data/lib/parameter_substitution/text_expression.rb +52 -0
  56. data/lib/parameter_substitution/transform.rb +99 -0
  57. data/lib/parameter_substitution/version.rb +5 -0
  58. metadata +117 -10
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'invoca/utils/array'
4
+
5
+ class ParameterSubstitution
6
+ class SubstitutionExpression
7
+ attr_accessor :parameter_name, :method_calls, :context
8
+
9
+ def initialize(parameter_name, method_calls, context)
10
+ @context = context
11
+ @parameter_name, @method_calls = fixup_name_and_method_calls(parameter_name, method_calls)
12
+ end
13
+
14
+ def validate(_inside_quotes)
15
+ # TODO: - Chase down callers who pass allow_nil = false. Can we get rid of them?
16
+ if !@context.allow_nil && @context.mapping_has_key?(@parameter_name) && @context.mapped_value(@parameter_name).nil?
17
+ raise ParameterSubstitution::ParseError, "Replacement parameter '#{@parameter_name}' is nil"
18
+ end
19
+
20
+ method_calls.each(&:validate)
21
+ end
22
+
23
+ def unknown_parameters(inside_quotes)
24
+ if !@context.mapping_has_key?(@parameter_name) && !(@context.destination_encoding == :json && inside_quotes)
25
+ @parameter_name
26
+ end
27
+ end
28
+
29
+ def evaluate(inside_quotes, only_expression: false)
30
+ if @context.mapping_has_key?(@parameter_name)
31
+ formatted_value = format(@context.mapped_value(@parameter_name), inside_quotes)
32
+ if @context.destination_encoding == :raw && formatted_value.nil?
33
+ only_expression ? '' : "#{@context.parameter_start}#{@parameter_name}#{@context.parameter_end}"
34
+ else
35
+ formatted_value
36
+ end
37
+ else
38
+ if @context.destination_encoding == :raw && only_expression
39
+ ''
40
+ else
41
+ "#{@context.parameter_start}#{@parameter_name}#{@context.parameter_end}"
42
+ end
43
+ end
44
+ end
45
+
46
+ def ends_inside_quotes(started_inside_quotes:)
47
+ started_inside_quotes
48
+ end
49
+
50
+ private
51
+
52
+ def fixup_name_and_method_calls(parameter_name, method_calls)
53
+ if args = try_parameter_name(parameter_name, method_calls)
54
+ args
55
+ else
56
+ [parameter_name, method_calls]
57
+ end
58
+ end
59
+
60
+ def try_parameter_name(parameter_name, method_calls)
61
+ if @context.mapping_has_key?(parameter_name)
62
+ [parameter_name, method_calls]
63
+ elsif !method_calls.empty? && method_calls.first.arguments.empty?
64
+ first_method = method_calls.first
65
+ remainder = method_calls[1..-1]
66
+ try_parameter_name(parameter_name + "." + first_method.name, remainder)
67
+ end
68
+ end
69
+
70
+ def format(lookup_value, inside_quotes)
71
+ raw_value = @method_calls.reduce(lookup_value) { |previous_value, method| method.call_method(previous_value) }
72
+ Encoder.encode(raw_value, @context.destination_encoding, source_encoding, @parameter_name, inside_quotes)
73
+ end
74
+
75
+ def source_encoding
76
+ @method_calls.last&.encoding || :text
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ParameterSubstitution
4
+ class TextExpression
5
+ attr_accessor :value
6
+ def initialize(value)
7
+ @value = value
8
+ end
9
+
10
+ def evaluate(_inside_quotes, only_expression: false)
11
+ @value
12
+ end
13
+
14
+ def validate(_inside_quotes); end
15
+
16
+ def parameter_name
17
+ nil
18
+ end
19
+
20
+ def unknown_parameters(_inside_quotes)
21
+ nil
22
+ end
23
+
24
+ def ends_inside_quotes(started_inside_quotes:)
25
+ state = started_inside_quotes ? :InsideString : :OutsideString
26
+
27
+ @value.chars.each do |c|
28
+ case state
29
+
30
+ when :InsideString
31
+ if c == '"'
32
+ state = :OutsideString
33
+ elsif c == '\\'
34
+ state = :InsideStringGotBackslash
35
+ end
36
+
37
+ when :OutsideString
38
+ if c == '"'
39
+ state = :InsideString
40
+ end
41
+
42
+ when :InsideStringGotBackslash
43
+ state = :InsideString
44
+ else
45
+ raise "unexpected #{state}"
46
+ end
47
+ end
48
+
49
+ state != :OutsideString
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parslet'
4
+ #
5
+ # The transform takes the output from the parser and constructs an Abstract Syntax Tree
6
+ # from the result. In this case, the output is a list of either TextExpression or SubstitutionExpressions.
7
+ #
8
+ # See the parslet documentation for more detail.
9
+ #
10
+
11
+ class ParameterSubstitution
12
+ class Transform < Parslet::Transform
13
+ def initialize(context)
14
+ @context = context
15
+ super
16
+ define_instance_rules
17
+ end
18
+
19
+ #
20
+ # Argument lists
21
+ #
22
+ rule float_arg: simple(:float) do
23
+ float.to_f
24
+ end
25
+
26
+ rule int_arg: simple(:int) do
27
+ int.to_i
28
+ end
29
+
30
+ rule string_arg: simple(:string) do
31
+ # Strip all leading slashes.
32
+ ParameterSubstitution::Transform.unescape(string)
33
+ end
34
+
35
+ rule string_arg: sequence(:string) do
36
+ ""
37
+ end
38
+
39
+ rule nil_arg: simple(:_) do
40
+ nil
41
+ end
42
+
43
+ rule arg_list: sequence(:parameters) do
44
+ parameters
45
+ end
46
+
47
+ rule arg_list: simple(:parameter) do
48
+ [parameter]
49
+ end
50
+
51
+ #
52
+ # Method Call
53
+ #
54
+ rule(method_call: simple(:method_call), arg_list: sequence(:arg_list)) do
55
+ MethodCallExpression.new(method_call, arg_list)
56
+ end
57
+
58
+ rule(method_call: simple(:method_calls), arg_list: simple(:arg)) do
59
+ MethodCallExpression.new(method_call, [arg])
60
+ end
61
+
62
+ rule method_call: simple(:method_call) do
63
+ MethodCallExpression.new(method_call, [])
64
+ end
65
+
66
+ #
67
+ # The overall expression
68
+ #
69
+ rule text: simple(:text) do
70
+ TextExpression.new(text.to_s)
71
+ end
72
+
73
+ def self.unescape(string)
74
+ string.to_s.gsub(/\\(.)/) { |v| v[1] }
75
+ end
76
+
77
+ private
78
+
79
+ def define_instance_rules
80
+ # This rule must be defined on the instance so that it can access attributes on the instance.
81
+ # The definition also takes a parameter to the block so that the block is bound to the instance
82
+ rule expression: sequence(:parameters) do |dictionary|
83
+ ParameterSubstitution::Expression.new(dictionary[:parameters], @context)
84
+ end
85
+
86
+ rule raw_expression: sequence(:parameters) do |dictionary|
87
+ ParameterSubstitution::Expression.new(dictionary[:parameters], @context.duplicate_raw)
88
+ end
89
+
90
+ rule parameter_name: simple(:parameter_name), method_calls: sequence(:method_calls) do |dictionary|
91
+ SubstitutionExpression.new(
92
+ ParameterSubstitution::Transform.unescape(dictionary[:parameter_name].to_s),
93
+ dictionary[:method_calls],
94
+ @context
95
+ )
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ParameterSubstitution
4
+ VERSION = "1.1.0.pre.1"
5
+ end
metadata CHANGED
@@ -1,27 +1,135 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parameter_substitution
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0.pre.1
4
+ version: 1.1.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
- - Bob Smith
8
- - James Ebentier
7
+ - Invoca Development
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2020-04-24 00:00:00.000000000 Z
13
- dependencies: []
11
+ date: 2020-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: builder
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: invoca-utils
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: parslet
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
14
69
  description: The substitution can be formatted using a syntax that looks like method
15
70
  calls
16
71
  email:
17
- - bob@invoca.com
18
- - jebentier@invoca.com
19
- - cmcgrath@invoca.com
72
+ - development@invoca.com
20
73
  executables: []
21
74
  extensions: []
22
75
  extra_rdoc_files: []
23
76
  files:
24
77
  - lib/parameter_substitution.rb
78
+ - lib/parameter_substitution/configuration.rb
79
+ - lib/parameter_substitution/context.rb
80
+ - lib/parameter_substitution/encoder.rb
81
+ - lib/parameter_substitution/expression.rb
82
+ - lib/parameter_substitution/formatters/add_prefix.rb
83
+ - lib/parameter_substitution/formatters/base.rb
84
+ - lib/parameter_substitution/formatters/blank_if_nil.rb
85
+ - lib/parameter_substitution/formatters/cgi_unescape.rb
86
+ - lib/parameter_substitution/formatters/compare_string.rb
87
+ - lib/parameter_substitution/formatters/date_time_custom.rb
88
+ - lib/parameter_substitution/formatters/date_time_format.rb
89
+ - lib/parameter_substitution/formatters/date_time_iso8601.rb
90
+ - lib/parameter_substitution/formatters/date_time_iso8601_zulu.rb
91
+ - lib/parameter_substitution/formatters/date_time_strftime.rb
92
+ - lib/parameter_substitution/formatters/date_time_unix_timestamp.rb
93
+ - lib/parameter_substitution/formatters/date_time_us_all_slashes.rb
94
+ - lib/parameter_substitution/formatters/date_time_us_normal.rb
95
+ - lib/parameter_substitution/formatters/date_time_us_seconds.rb
96
+ - lib/parameter_substitution/formatters/date_time_us_short_am_pm.rb
97
+ - lib/parameter_substitution/formatters/date_time_us_short_year.rb
98
+ - lib/parameter_substitution/formatters/date_time_utc_year_first_dashes_seconds.rb
99
+ - lib/parameter_substitution/formatters/date_us_dashes.rb
100
+ - lib/parameter_substitution/formatters/date_us_normal.rb
101
+ - lib/parameter_substitution/formatters/date_year_first_dashes.rb
102
+ - lib/parameter_substitution/formatters/downcase.rb
103
+ - lib/parameter_substitution/formatters/duration_as_seconds.rb
104
+ - lib/parameter_substitution/formatters/duration_as_time.rb
105
+ - lib/parameter_substitution/formatters/duration_grouped_by_description.rb
106
+ - lib/parameter_substitution/formatters/greater_than_value.rb
107
+ - lib/parameter_substitution/formatters/if_nil.rb
108
+ - lib/parameter_substitution/formatters/if_truthy.rb
109
+ - lib/parameter_substitution/formatters/in_timezone.rb
110
+ - lib/parameter_substitution/formatters/json_parse.rb
111
+ - lib/parameter_substitution/formatters/left.rb
112
+ - lib/parameter_substitution/formatters/lookup.rb
113
+ - lib/parameter_substitution/formatters/lower.rb
114
+ - lib/parameter_substitution/formatters/manager.rb
115
+ - lib/parameter_substitution/formatters/md5.rb
116
+ - lib/parameter_substitution/formatters/mid.rb
117
+ - lib/parameter_substitution/formatters/parse_time.rb
118
+ - lib/parameter_substitution/formatters/right.rb
119
+ - lib/parameter_substitution/formatters/sha256.rb
120
+ - lib/parameter_substitution/formatters/split_after_colon.rb
121
+ - lib/parameter_substitution/formatters/split_and_find.rb
122
+ - lib/parameter_substitution/formatters/split_before_colon.rb
123
+ - lib/parameter_substitution/formatters/time_with_seconds.rb
124
+ - lib/parameter_substitution/formatters/trim.rb
125
+ - lib/parameter_substitution/formatters/upper.rb
126
+ - lib/parameter_substitution/method_call_expression.rb
127
+ - lib/parameter_substitution/parse_error.rb
128
+ - lib/parameter_substitution/parser.rb
129
+ - lib/parameter_substitution/substitution_expression.rb
130
+ - lib/parameter_substitution/text_expression.rb
131
+ - lib/parameter_substitution/transform.rb
132
+ - lib/parameter_substitution/version.rb
25
133
  homepage: https://github.com/Invoca/parameter_substitution
26
134
  licenses: []
27
135
  metadata:
@@ -41,8 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
149
  - !ruby/object:Gem::Version
42
150
  version: 1.3.1
43
151
  requirements: []
44
- rubyforge_project:
45
- rubygems_version: 2.6.13
152
+ rubygems_version: 3.0.3
46
153
  signing_key:
47
154
  specification_version: 4
48
155
  summary: Handles parsing an input strings with embedded substitution parameters and