yake 0.7.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b15fb667d8aba0f2fed790898bac47dc745883203f5cc7adda48e5f9c1c58bd
4
- data.tar.gz: e07bd79d34cb1a6e841eda84df0b392d8419e0ed3bcbcdb5bf49d2319b47b3c7
3
+ metadata.gz: d0272be54a9cf2f3b94764ac4c87db1f6047b9fd2e8b13286a8be939adde1387
4
+ data.tar.gz: 9c82744536dd4147039bdf6d3ef8d3e6b395c28ce1d2f64e8999d4a0c80a0a79
5
5
  SHA512:
6
- metadata.gz: 26e801e5d27b2a8c0241d465f7507cae64913e05e67d91a085ee179e8ec675c06d7e058013464e152e8255343a1790c4a9b7a1c2db45a74461c5a46524549687
7
- data.tar.gz: 272b1c2ee937e87fdce222ad8228893614c18b4dd01072b050ce3ba24095c577a8ee6a40988ca00968156d916d87b0b0a9da04a668c2efde79c8ec798721dd94
6
+ metadata.gz: 835f4171028f915170c3a548b175e6e5ee3a1d57162b4b9d6bbb7a33537fc599e9fd535a925a7b7e3b871d507707757d508f8dadcbe4b1368b47b3000a2cfc8f
7
+ data.tar.gz: 8ecc31882ad76a1d999f7e5ad1ab3f1ecbe141041f091a12f5dcfefb728416391dfa14d0632345e9da8e3de6bf66b3372b704ea73c3fbb40365181ec1bb8c808
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # λake
2
2
 
3
- ![gem](https://img.shields.io/gem/v/yake?color=crimson&logo=rubygems&logoColor=eee&style=flat-square)
4
- [![rspec](https://img.shields.io/github/workflow/status/amancevice/yake/RSpec?logo=github&style=flat-square)](https://github.com/amancevice/yake/actions)
3
+ [![gem](https://img.shields.io/gem/v/yake?color=crimson&logo=rubygems&logoColor=eee&style=flat-square)](https://rubygems.org/gems/yake)
4
+ [![rspec](https://img.shields.io/github/actions/workflow/status/amancevice/yake/rspec.yml?logo=github&style=flat-square)](https://github.com/amancevice/yake/actions/workflows/rspec.yml)
5
5
  [![coverage](https://img.shields.io/codeclimate/coverage/amancevice/yake?logo=code-climate&style=flat-square)](https://codeclimate.com/github/amancevice/yake/test_coverage)
6
6
  [![maintainability](https://img.shields.io/codeclimate/maintainability/amancevice/yake?logo=code-climate&style=flat-square)](https://codeclimate.com/github/amancevice/yake/maintainability)
7
7
 
8
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/smallweirdnumber)
9
+
8
10
  Write your AWS Lambda function handlers using a Rake-like declarative syntax:
9
11
 
10
12
  ```ruby
@@ -77,7 +79,7 @@ INFO RequestId: 149c500f-028a-4b57-8977-0ef568cf8caf EVENT { … }
77
79
 
78
80
  INFO RequestId: 149c500f-028a-4b57-8977-0ef568cf8caf RETURN { … }
79
81
  END RequestId: 149c500f-028a-4b57-8977-0ef568cf8caf
80
- REPORT RequestId: 149c500f-028a-4b57-8977-0ef568cf8caf Duration: 43.97 ms Billed Duration: 44 ms Memory Size: 128 MB Max Memory Used: 77 MB
82
+ REPORT RequestId: 149c500f-028a-4b57-8977-0ef568cf8caf Duration: 43.97 ms Billed Duration: 44 ms Memory Size: 128 MB Max Memory Used: 77 MB
81
83
  ```
82
84
 
83
85
  Logging the request ID in this way makes gathering logs lines for a particular execution in CloudWatch much easier.
@@ -208,6 +210,11 @@ MyObject.new.try(:some_method)
208
210
  { a: { b: 'c', d: 'e' }, f: 'g' }.deep_keys
209
211
  # => [:a, :b, :d, :f]
210
212
 
213
+ left = { a: 'b', c: { d: %w[e] } }
214
+ right = { a: 'a', c: { d: %w[d] } }
215
+ left.deep_merge(right)
216
+ # => { :a => "a", :c => { :d => ["e", "d"] } }
217
+
211
218
  { a: { b: 'c', d: 'e' }, f: 'g' }.deep_transform_keys(&:to_s)
212
219
  # => { "a" => { "b" => "c", "d" => "e" }, "f" => "g" }
213
220
 
@@ -244,6 +251,12 @@ hash.deep_transform_keys!(&:to_s)
244
251
 
245
252
  { f: 'g', a: { d: 'e', b: 'c' } }.to_deep_struct
246
253
  # => #<OpenStruct f="g", a=#<OpenStruct d="e", b="c">>
254
+
255
+ { a: { b: 'c', d: 'e' }, f: 'g' }.to_dynamodb
256
+ # => { :a => { :M => { :b => { :S => "c" }, :d => { :S => "e" } } }, :f => { :S => "g" } }
257
+
258
+ { a: { M: { b: { S: 'c' }, d: { S: 'e' } } }, f: { S: 'g' } }.to_h_from_dynamodb
259
+ # => { :a => { :b => "c", :d => "e" }, :f => "g" }
247
260
  ```
248
261
 
249
262
  `Integer` helpers:
@@ -331,6 +344,8 @@ UTC.now
331
344
 
332
345
  As of `~> 0.4`, `yake` comes with a helper for writing Lambdas that integrate with Datadog's `datadog-ruby` gem.
333
346
 
347
+ As of `~> 0.8`, `yake` uses the v2 Datadog Lambda gem.
348
+
334
349
  Creating a Lambda handler that wraps the Datadog tooling is easy:
335
350
 
336
351
  ```ruby
@@ -338,7 +353,7 @@ require 'aws-sdk-someservice'
338
353
  require 'yake/datadog'
339
354
 
340
355
  # Configure Datadog to use AWS tracing
341
- Datadog::Lambda.configure_apm { |config| config.use :aws }
356
+ Datadog::Lambda.configure_apm { |c| c.tracing.instrument :aws }
342
357
 
343
358
  datadog :handler do |event|
344
359
  # …
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ require 'datadog/lambda'
6
+ require 'yake'
7
+
8
+ module Yake
9
+ module Datadog
10
+ class Formatter < ::Logger::Formatter
11
+ Format = "[%s] %s %s %s %s\n"
12
+
13
+ def call(severity, time, progname, msg)
14
+ Format % [
15
+ severity,
16
+ time.utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
17
+ progname.nil? ? '-' : progname.split.last,
18
+ ::Datadog.tracer.active_correlation,
19
+ msg2str(msg).strip,
20
+ ]
21
+ end
22
+ end
23
+
24
+ class MockContext < Struct.new(
25
+ :clock_diff,
26
+ :deadline_ms,
27
+ :aws_request_id,
28
+ :invoked_function_arn,
29
+ :log_group_name,
30
+ :log_stream_name,
31
+ :function_name,
32
+ :memory_limit_in_mb,
33
+ :function_version)
34
+
35
+ def invoked_function_arn
36
+ @invoked_function_arn ||= begin
37
+ region = ENV['AWS_REGION'] || ENV['AWS_DEFAULT_REGION'] || 'us-east-1'
38
+ "arn:aws:lambda:#{region}:123456789012:function-name"
39
+ end
40
+ end
41
+ end
42
+
43
+ module DSL
44
+ include Yake::DSL
45
+
46
+ ##
47
+ # Datadog handler wrapper
48
+ def datadog(name, &block)
49
+ define_method(name) do |event:nil, context:nil|
50
+ context ||= MockContext.new
51
+ ::Datadog::Lambda.wrap(event, context) do
52
+ Yake.wrap(event, context, &block)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ logger.formatter = Datadog::Formatter.new
60
+ end
61
+
62
+ extend Yake::Datadog::DSL
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ require 'datadog/lambda'
6
+ require 'yake'
7
+
8
+ module Yake
9
+ module Datadog
10
+ class Formatter < ::Logger::Formatter
11
+ Format = "[%s] %s %s %s %s\n"
12
+
13
+ def call(severity, time, progname, msg)
14
+ Format % [
15
+ severity,
16
+ time.utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
17
+ progname.nil? ? '-' : progname.split.last,
18
+ ::Datadog::Tracing.log_correlation,
19
+ msg2str(msg).strip,
20
+ ]
21
+ end
22
+ end
23
+
24
+ class MockContext < Struct.new(
25
+ :clock_diff,
26
+ :deadline_ms,
27
+ :aws_request_id,
28
+ :invoked_function_arn,
29
+ :log_group_name,
30
+ :log_stream_name,
31
+ :function_name,
32
+ :memory_limit_in_mb,
33
+ :function_version)
34
+
35
+ def invoked_function_arn
36
+ @invoked_function_arn ||= begin
37
+ region = ENV['AWS_REGION'] || ENV['AWS_DEFAULT_REGION'] || 'us-east-1'
38
+ "arn:aws:lambda:#{region}:123456789012:function-name"
39
+ end
40
+ end
41
+ end
42
+
43
+ module DSL
44
+ include Yake::DSL
45
+
46
+ ##
47
+ # Datadog handler wrapper
48
+ def datadog(name, &block)
49
+ define_method(name) do |event:nil, context:nil|
50
+ context ||= MockContext.new
51
+ ::Datadog::Lambda.wrap(event, context) do
52
+ Yake.wrap(event, context, &block)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ logger.formatter = Datadog::Formatter.new
60
+ end
61
+
62
+ extend Yake::Datadog::DSL
data/lib/yake/datadog.rb CHANGED
@@ -1,61 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'logger'
3
2
 
4
3
  require 'datadog/lambda'
5
- require 'yake'
6
-
7
- module Yake
8
- module Datadog
9
- class Formatter < ::Logger::Formatter
10
- Format = "[%s] %s %s %s %s\n"
11
-
12
- def call(severity, time, progname, msg)
13
- Format % [
14
- severity,
15
- time.utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
16
- progname.nil? ? '-' : progname.split.last,
17
- ::Datadog.tracer.active_correlation,
18
- msg2str(msg).strip,
19
- ]
20
- end
21
- end
22
-
23
- class MockContext < Struct.new(
24
- :clock_diff,
25
- :deadline_ms,
26
- :aws_request_id,
27
- :invoked_function_arn,
28
- :log_group_name,
29
- :log_stream_name,
30
- :function_name,
31
- :memory_limit_in_mb,
32
- :function_version)
33
-
34
- def invoked_function_arn
35
- @invoked_function_arn ||= begin
36
- region = ENV['AWS_REGION'] || ENV['AWS_DEFAULT_REGION'] || 'us-east-1'
37
- "arn:aws:lambda:#{region}:123456789012:function-name"
38
- end
39
- end
40
- end
41
-
42
- module DSL
43
- include Yake::DSL
44
-
45
- ##
46
- # Datadog handler wrapper
47
- def datadog(name, &block)
48
- define_method(name) do |event:nil, context:nil|
49
- context ||= MockContext.new
50
- ::Datadog::Lambda.wrap(event, context) do
51
- Yake.wrap(event, context, &block)
52
- end
53
- end
54
- end
55
- end
56
- end
57
-
58
- logger.formatter = Datadog::Formatter.new
59
- end
60
-
61
- extend Yake::Datadog::DSL
4
+ require_relative "datadog/v#{Datadog::Lambda::VERSION::MAJOR}"
data/lib/yake/dsl.rb CHANGED
@@ -33,6 +33,19 @@ module Yake
33
33
  end
34
34
  end
35
35
  end
36
+
37
+ class << self
38
+ def wrap(event = nil, context = nil, &block)
39
+ original_progname = logger.progname
40
+ logger.progname = context&.aws_request_id
41
+ jsonify = -> (obj) { pretty? ? JSON.pretty_generate(obj) : obj.to_json }
42
+ log_return = -> (res) { logger.info("RETURN #{ jsonify === res }") }
43
+ logger.info("EVENT #{ jsonify === event }")
44
+ (yield(event, context) if block_given?).tap(&log_return)
45
+ ensure
46
+ logger.progname = original_progname
47
+ end
48
+ end
36
49
  end
37
50
 
38
51
  extend Yake::DSL
data/lib/yake/logger.rb CHANGED
@@ -36,17 +36,5 @@ module Yake
36
36
  def pretty?
37
37
  @pretty == true
38
38
  end
39
-
40
- def wrap(event = nil, context = nil, &block)
41
- original_progname = logger.progname
42
- logger.progname = context&.aws_request_id
43
- jsonify = -> (obj) { pretty? ? JSON.pretty_generate(obj) : obj.to_json }
44
- logger.info("EVENT #{ jsonify === event }")
45
- yield(event, context).tap do |res|
46
- logger.info("RETURN #{ jsonify === res }")
47
- end
48
- ensure
49
- logger.progname = original_progname
50
- end
51
39
  end
52
40
  end
data/lib/yake/support.rb CHANGED
@@ -1,8 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
  require 'digest'
3
5
  require 'json'
4
6
  require 'time'
5
7
 
8
+ class Array
9
+ def to_dynamodb() { L: map(&:to_dynamodb) } end
10
+ end
11
+
6
12
  class Hash
7
13
  def deep_keys() map { |k,v| v.respond_to?(:deep_keys) ? [k] + v.deep_keys : k }.flatten end
8
14
  def deep_sort() sort.map { |k,v| [ k, v.try(:deep_sort) { |x| x } ] }.to_h end
@@ -17,6 +23,23 @@ class Hash
17
23
  def to_json_sorted() deep_sort.to_json end
18
24
  def to_struct() OpenStruct.new(self) end
19
25
 
26
+ ##
27
+ # Adapted from ActiveSupport Hash#deep_merge
28
+ # https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
29
+ def deep_merge(other, &block)
30
+ merge(other) do |key, a, b|
31
+ if a.is_a?(Hash) && b.is_a?(Hash)
32
+ a.deep_merge(b, &block)
33
+ elsif a.is_a?(Array) && b.is_a?(Array)
34
+ a + b
35
+ elsif block_given?
36
+ yield key, a, b
37
+ else
38
+ b
39
+ end
40
+ end
41
+ end
42
+
20
43
  def deep_transform_keys(&block)
21
44
  deep_transform(:transform_keys, &block)
22
45
  end
@@ -41,6 +64,27 @@ class Hash
41
64
  end
42
65
  end
43
66
 
67
+ def to_dynamodb
68
+ map do |key, val|
69
+ { key => val.is_a?(Hash) ? { M: val.to_dynamodb } : val.to_dynamodb }
70
+ end.reduce(&:merge)
71
+ end
72
+
73
+ def to_h_from_dynamodb
74
+ decode = -> (i) do
75
+ type, val = i.first
76
+ case type.to_sym
77
+ when :S then val
78
+ when :N then val =~ /^[0-9]+$/ ? val.to_i : val.to_f
79
+ when :L then val.map(&decode)
80
+ when :M then val.transform_values(&decode)
81
+ end
82
+ end
83
+ map do |key, val|
84
+ { key => decode === val }
85
+ end.reduce(&:merge)
86
+ end
87
+
44
88
  private def deep_transform(method, &block)
45
89
  f = -> (x) { x.respond_to?(:"deep_#{method}") ? x.send(:"deep_#{method}", &block) : x }
46
90
  block_given? ? send(method, &block).map do |key, val|
@@ -49,6 +93,10 @@ class Hash
49
93
  end
50
94
  end
51
95
 
96
+ class Numeric
97
+ def to_dynamodb() { N: to_s } end
98
+ end
99
+
52
100
  class Integer
53
101
  def weeks() days * 7 end
54
102
  def days() hours * 24 end
@@ -82,6 +130,7 @@ class String
82
130
  def snake_case() gsub(/([a-z])([A-Z])/, '\1_\2').downcase end
83
131
  def strict_decode64() Base64.strict_decode64(self) end
84
132
  def strict_encode64() Base64.strict_encode64(self) end
133
+ def to_dynamodb() { S: self } end
85
134
  def to_h_from_json(**params) JSON.parse(self, **params) end
86
135
  def to_h_from_form() URI.decode_www_form(self).to_h end
87
136
  def utc() UTC.parse(self) end
@@ -90,6 +139,7 @@ end
90
139
  class Symbol
91
140
  def camel_case() to_s.camel_case.to_sym end
92
141
  def snake_case() to_s.snake_case.to_sym end
142
+ def to_dynamodb() { S: to_s } end
93
143
  end
94
144
 
95
145
  class UTC < Time
data/lib/yake/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yake
4
- VERSION = '0.7.0'
4
+ VERSION = '1.0.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Mancevice
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-18 00:00:00.000000000 Z
11
+ date: 2023-05-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -22,6 +22,8 @@ files:
22
22
  - lib/yake.rb
23
23
  - lib/yake/api.rb
24
24
  - lib/yake/datadog.rb
25
+ - lib/yake/datadog/v1.rb
26
+ - lib/yake/datadog/v2.rb
25
27
  - lib/yake/dsl.rb
26
28
  - lib/yake/errors.rb
27
29
  - lib/yake/logger.rb
@@ -46,7 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
48
  - !ruby/object:Gem::Version
47
49
  version: '0'
48
50
  requirements: []
49
- rubygems_version: 3.3.7
51
+ rubygems_version: 3.4.10
50
52
  signing_key:
51
53
  specification_version: 4
52
54
  summary: Rake-like DSL for declaring AWS Lambda function handlers