zenaton 0.4.2 → 0.5.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/.circleci/config.yml +79 -52
- data/.gitignore +7 -0
- data/.rubocop.yml +4 -0
- data/Appraisals +13 -0
- data/CHANGELOG.md +17 -1
- data/Gemfile.lock +17 -8
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5.0.gemfile +7 -0
- data/gemfiles/rails_5.1.gemfile +7 -0
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/lib/zenaton/client.rb +63 -0
- data/lib/zenaton/contexts.rb +7 -0
- data/lib/zenaton/contexts/task.rb +33 -0
- data/lib/zenaton/contexts/workflow.rb +17 -0
- data/lib/zenaton/engine.rb +16 -0
- data/lib/zenaton/interfaces/task.rb +30 -1
- data/lib/zenaton/interfaces/workflow.rb +15 -0
- data/lib/zenaton/refinements.rb +16 -0
- data/lib/zenaton/refinements/big_decimal.rb +25 -0
- data/lib/zenaton/refinements/class.rb +21 -0
- data/lib/zenaton/refinements/complex.rb +22 -0
- data/lib/zenaton/refinements/date.rb +26 -0
- data/lib/zenaton/refinements/date_time.rb +40 -0
- data/lib/zenaton/refinements/exception.rb +24 -0
- data/lib/zenaton/refinements/object.rb +15 -0
- data/lib/zenaton/refinements/open_struct.rb +26 -0
- data/lib/zenaton/refinements/range.rb +21 -0
- data/lib/zenaton/refinements/rational.rb +22 -0
- data/lib/zenaton/refinements/regexp.rb +22 -0
- data/lib/zenaton/refinements/struct.rb +24 -0
- data/lib/zenaton/refinements/symbol.rb +21 -0
- data/lib/zenaton/refinements/time.rb +32 -0
- data/lib/zenaton/services/graphql.rb +71 -0
- data/lib/zenaton/services/http.rb +14 -9
- data/lib/zenaton/services/properties.rb +11 -57
- data/lib/zenaton/services/serializer.rb +2 -0
- data/lib/zenaton/traits/with_timestamp.rb +4 -2
- data/lib/zenaton/traits/zenatonable.rb +9 -0
- data/lib/zenaton/version.rb +1 -1
- data/zenaton.gemspec +2 -0
- metadata +54 -2
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Struct do
|
7
|
+
def to_zenaton
|
8
|
+
class_name = self.class.name.to_s
|
9
|
+
error_message = 'Only named structs are supported'
|
10
|
+
raise ArgumentError, error_message if class_name.empty?
|
11
|
+
{
|
12
|
+
'v' => values
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Reimplements `json/add/struct`
|
20
|
+
class Struct
|
21
|
+
def self.from_zenaton(props)
|
22
|
+
new(*props['v'])
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Symbol do
|
7
|
+
def to_zenaton
|
8
|
+
{
|
9
|
+
's' => to_s
|
10
|
+
}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Reimplements `json/add/symbol`
|
17
|
+
class Symbol
|
18
|
+
def self.from_zenaton(props)
|
19
|
+
props['s'].to_sym
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zenaton
|
4
|
+
# :nodoc
|
5
|
+
module Refinements
|
6
|
+
refine Time do
|
7
|
+
def to_zenaton
|
8
|
+
nanoseconds = [tv_usec * 1000]
|
9
|
+
respond_to?(:tv_nsec) && nanoseconds << tv_nsec
|
10
|
+
nanoseconds = nanoseconds.max
|
11
|
+
{
|
12
|
+
's' => tv_sec,
|
13
|
+
'n' => nanoseconds
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Reimplements `json/add/time`
|
21
|
+
class Time
|
22
|
+
def self.from_zenaton(props)
|
23
|
+
if (usec = props.delete('u')) # used to be tv_usec -> tv_nsec
|
24
|
+
props['n'] = usec * 1000
|
25
|
+
end
|
26
|
+
if method_defined?(:tv_nsec)
|
27
|
+
at(props['s'], Rational(props['n'], 1000))
|
28
|
+
else
|
29
|
+
at(props['s'], props['n'] / 1000)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'zenaton/exceptions'
|
4
|
+
|
5
|
+
module Zenaton
|
6
|
+
# Collection of utility classes for the Zenaton library
|
7
|
+
module Services
|
8
|
+
# Service that:
|
9
|
+
# - handles graphql calls
|
10
|
+
# - translates exceptions into Zenaton specific ones
|
11
|
+
class GraphQL
|
12
|
+
CREATE_WORKFLOW_SCHEDULE = <<-'GRAPHQL'
|
13
|
+
mutation ($createWorkflowScheduleInput: CreateWorkflowScheduleInput!) {
|
14
|
+
createWorkflowSchedule(input: $createWorkflowScheduleInput) {
|
15
|
+
schedule {
|
16
|
+
id
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
GRAPHQL
|
21
|
+
|
22
|
+
CREATE_TASK_SCHEDULE = <<-'GRAPHQL'
|
23
|
+
mutation ($createTaskScheduleInput: CreateTaskScheduleInput!) {
|
24
|
+
createTaskSchedule(input: $createTaskScheduleInput) {
|
25
|
+
schedule {
|
26
|
+
id
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
GRAPHQL
|
31
|
+
|
32
|
+
def initialize(http:)
|
33
|
+
@http = http
|
34
|
+
end
|
35
|
+
|
36
|
+
# Makes a GRAPHQL request with some data and sets the correct headers
|
37
|
+
#
|
38
|
+
# @param url [String] the url for the request
|
39
|
+
# @param body [Hash] the payload to send with the request
|
40
|
+
# @return [Hash] the parsed json response
|
41
|
+
def request(url, query, variables = nil, headers = {})
|
42
|
+
body = { 'query' => query }
|
43
|
+
body['variables'] = variables if variables
|
44
|
+
|
45
|
+
res_body = @http.post(url, body, headers)
|
46
|
+
handle_response_body(res_body)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def handle_response_body(response_body)
|
52
|
+
if external_error?(response_body)
|
53
|
+
raise Zenaton::ExternalError, format_external_error(response_body)
|
54
|
+
end
|
55
|
+
|
56
|
+
response_body && response_body['data']
|
57
|
+
end
|
58
|
+
|
59
|
+
def external_error?(response_body)
|
60
|
+
response_body&.key?('errors')
|
61
|
+
end
|
62
|
+
|
63
|
+
def format_external_error(response_body)
|
64
|
+
response_body['errors'].map do |error|
|
65
|
+
path = error['path'] ? "- #{error['path']}: " : ''
|
66
|
+
"#{path}#{error['message']}"
|
67
|
+
end.join("\n")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
3
4
|
require 'net/http'
|
4
5
|
require 'zenaton/exceptions'
|
6
|
+
require 'json'
|
5
7
|
|
6
8
|
module Zenaton
|
7
9
|
# Collection of utility classes for the Zenaton library
|
@@ -37,11 +39,12 @@ module Zenaton
|
|
37
39
|
#
|
38
40
|
# @param url [String] the url for the request
|
39
41
|
# @param body [Hash] the payload to send with the request
|
42
|
+
# @param headers [Hash] additional headers to send with the request
|
40
43
|
# @return [Hash] the parsed json response
|
41
|
-
def post(url, body)
|
44
|
+
def post(url, body, headers = {})
|
42
45
|
parsed_url = parse_url(url)
|
43
46
|
request = Net::HTTP::Post.new(parsed_url[:uri])
|
44
|
-
set_body_and_headers(request, post_options(body))
|
47
|
+
set_body_and_headers(request, post_options(body, headers))
|
45
48
|
make_request(request, parsed_url)
|
46
49
|
end
|
47
50
|
|
@@ -49,11 +52,12 @@ module Zenaton
|
|
49
52
|
#
|
50
53
|
# @param url [String] the url for the request
|
51
54
|
# @param body [Hash] the payload to send with the request
|
55
|
+
# @param headers [Hash] additional headers to send with the request
|
52
56
|
# @return [Hash] the parsed json response
|
53
|
-
def put(url, body)
|
57
|
+
def put(url, body, headers = {})
|
54
58
|
parsed_url = parse_url(url)
|
55
59
|
request = Net::HTTP::Put.new(parsed_url[:uri])
|
56
|
-
set_body_and_headers(request, put_options(body))
|
60
|
+
set_body_and_headers(request, put_options(body, headers))
|
57
61
|
make_request(request, parsed_url)
|
58
62
|
end
|
59
63
|
|
@@ -104,13 +108,14 @@ module Zenaton
|
|
104
108
|
}
|
105
109
|
end
|
106
110
|
|
107
|
-
def post_options(body)
|
111
|
+
def post_options(body, headers)
|
112
|
+
default_post_headers = {
|
113
|
+
'Accept' => 'application/json',
|
114
|
+
'Content-Type' => 'application/json'
|
115
|
+
}
|
108
116
|
{
|
109
117
|
body: body,
|
110
|
-
headers:
|
111
|
-
'Accept' => 'application/json',
|
112
|
-
'Content-Type' => 'application/json'
|
113
|
-
}
|
118
|
+
headers: default_post_headers.merge(headers)
|
114
119
|
}
|
115
120
|
end
|
116
121
|
alias put_options post_options
|
@@ -1,37 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'singleton'
|
4
|
-
require '
|
5
|
-
require 'json/add/date_time'
|
6
|
-
require 'json/add/exception'
|
7
|
-
require 'json/add/range'
|
8
|
-
require 'json/add/regexp'
|
9
|
-
require 'json/add/struct'
|
10
|
-
require 'json/add/time'
|
11
|
-
require 'json/add/rational'
|
12
|
-
require 'json/add/complex'
|
13
|
-
require 'json/add/bigdecimal'
|
14
|
-
require 'json/add/ostruct'
|
4
|
+
require 'zenaton/refinements'
|
15
5
|
|
16
6
|
module Zenaton
|
17
7
|
module Services
|
18
8
|
# Wrapper class to read instance variables from an object and
|
19
9
|
# to create new objects with a given set of instance variables.
|
20
10
|
class Properties
|
21
|
-
|
22
|
-
SPECIAL_CASES = [
|
23
|
-
::Complex,
|
24
|
-
::Date,
|
25
|
-
::DateTime,
|
26
|
-
::Range,
|
27
|
-
::Rational,
|
28
|
-
::Regexp,
|
29
|
-
::Symbol,
|
30
|
-
::Time,
|
31
|
-
defined?(::OpenStruct) ? ::OpenStruct : nil,
|
32
|
-
defined?(::BigDecimal) ? ::BigDecimal : nil
|
33
|
-
].compact.freeze
|
34
|
-
|
11
|
+
using Zenaton::Refinements
|
35
12
|
# Handle blank object instantiation differently for these classes
|
36
13
|
NUMERIC_INITIALIATION = [
|
37
14
|
::Rational,
|
@@ -59,11 +36,7 @@ module Zenaton
|
|
59
36
|
# @param object [Object] the object to be read
|
60
37
|
# @return [Hash]
|
61
38
|
def from(object)
|
62
|
-
|
63
|
-
object.instance_variables.map do |ivar|
|
64
|
-
value = object.instance_variable_get(ivar)
|
65
|
-
[ivar, value]
|
66
|
-
end.to_h
|
39
|
+
object.to_zenaton
|
67
40
|
end
|
68
41
|
|
69
42
|
# Returns the given object with the properties as instance variables
|
@@ -71,11 +44,10 @@ module Zenaton
|
|
71
44
|
# @param properties [Hash] the properties to be written
|
72
45
|
# @return [Object]
|
73
46
|
def set(object, properties)
|
74
|
-
|
75
|
-
properties
|
76
|
-
|
77
|
-
|
78
|
-
object
|
47
|
+
klass = object.class
|
48
|
+
return klass.from_zenaton(properties) if defined?(klass.from_zenaton)
|
49
|
+
|
50
|
+
fallback_set(object, properties)
|
79
51
|
end
|
80
52
|
|
81
53
|
# Given a class name and a set of properties, return a new instance of the
|
@@ -102,29 +74,11 @@ module Zenaton
|
|
102
74
|
super_class.nil? || object.is_a?(super_class)
|
103
75
|
end
|
104
76
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
else
|
109
|
-
JSON.parse(object.to_json).tap do |attributes|
|
110
|
-
attributes.delete('json_class')
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def set_complex_type(object, props)
|
116
|
-
if object.is_a?(Symbol)
|
117
|
-
props['s'].to_sym
|
118
|
-
else
|
119
|
-
props['json_class'] = object.class.name
|
120
|
-
JSON(props.to_json)
|
77
|
+
def fallback_set(object, properties)
|
78
|
+
properties.each do |ivar, value|
|
79
|
+
object.instance_variable_set(ivar, value)
|
121
80
|
end
|
122
|
-
|
123
|
-
|
124
|
-
def special_case?(object)
|
125
|
-
SPECIAL_CASES.include?(object.class) \
|
126
|
-
|| object.is_a?(Struct) \
|
127
|
-
|| object.is_a?(Exception)
|
81
|
+
object
|
128
82
|
end
|
129
83
|
end
|
130
84
|
end
|
@@ -69,8 +69,10 @@ module Zenaton
|
|
69
69
|
def _weekday(value, day, now, now_dup)
|
70
70
|
_set_mode(MODE_WEEK_DAY)
|
71
71
|
value -= 1 if later_today?(now, day)
|
72
|
-
|
73
|
-
|
72
|
+
current_day_number = now.wday != 0 ? now.wday - 1 : 6
|
73
|
+
from_now = WEEKDAYS.index(day) - current_day_number
|
74
|
+
from_now += 7 * value unless from_now.positive?
|
75
|
+
now_dup.advance(days: from_now)
|
74
76
|
end
|
75
77
|
|
76
78
|
def _timestamp(timestamp)
|
@@ -22,6 +22,15 @@ module Zenaton
|
|
22
22
|
Engine.instance.dispatch([self])
|
23
23
|
end
|
24
24
|
|
25
|
+
def schedule(cron)
|
26
|
+
if !cron.is_a?(String) || cron.blank?
|
27
|
+
raise InvalidArgumentError,
|
28
|
+
"The cron passed to 'schedule' must be a non empty string"
|
29
|
+
end
|
30
|
+
|
31
|
+
Engine.instance.schedule([self], cron)
|
32
|
+
end
|
33
|
+
|
25
34
|
class_methods do
|
26
35
|
# Search for workflows to interact with.
|
27
36
|
# For available methods, see {Zenaton::Query::Builder}
|
data/lib/zenaton/version.rb
CHANGED
data/zenaton.gemspec
CHANGED
@@ -25,10 +25,12 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_runtime_dependency 'activesupport'
|
26
26
|
spec.add_runtime_dependency 'tzinfo-data'
|
27
27
|
|
28
|
+
spec.add_development_dependency 'appraisal'
|
28
29
|
spec.add_development_dependency 'bundler', '~> 1.16'
|
29
30
|
spec.add_development_dependency 'pry'
|
30
31
|
spec.add_development_dependency 'rake', '~> 10.0'
|
31
32
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
33
|
+
spec.add_development_dependency 'rspec_junit_formatter'
|
32
34
|
spec.add_development_dependency 'rubocop'
|
33
35
|
spec.add_development_dependency 'rubocop-rspec'
|
34
36
|
spec.add_development_dependency 'simplecov'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zenaton
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zenaton
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: appraisal
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +108,20 @@ dependencies:
|
|
94
108
|
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '3.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec_junit_formatter
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: rubocop
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +218,7 @@ files:
|
|
190
218
|
- ".rspec"
|
191
219
|
- ".rubocop.yml"
|
192
220
|
- ".yardopts"
|
221
|
+
- Appraisals
|
193
222
|
- CHANGELOG.md
|
194
223
|
- CODE_OF_CONDUCT.md
|
195
224
|
- Gemfile
|
@@ -199,8 +228,15 @@ files:
|
|
199
228
|
- Rakefile
|
200
229
|
- bin/console
|
201
230
|
- bin/setup
|
231
|
+
- gemfiles/.bundle/config
|
232
|
+
- gemfiles/rails_5.0.gemfile
|
233
|
+
- gemfiles/rails_5.1.gemfile
|
234
|
+
- gemfiles/rails_5.2.gemfile
|
202
235
|
- lib/zenaton.rb
|
203
236
|
- lib/zenaton/client.rb
|
237
|
+
- lib/zenaton/contexts.rb
|
238
|
+
- lib/zenaton/contexts/task.rb
|
239
|
+
- lib/zenaton/contexts/workflow.rb
|
204
240
|
- lib/zenaton/engine.rb
|
205
241
|
- lib/zenaton/exceptions.rb
|
206
242
|
- lib/zenaton/interfaces/event.rb
|
@@ -210,6 +246,22 @@ files:
|
|
210
246
|
- lib/zenaton/parallel.rb
|
211
247
|
- lib/zenaton/processor.rb
|
212
248
|
- lib/zenaton/query/builder.rb
|
249
|
+
- lib/zenaton/refinements.rb
|
250
|
+
- lib/zenaton/refinements/big_decimal.rb
|
251
|
+
- lib/zenaton/refinements/class.rb
|
252
|
+
- lib/zenaton/refinements/complex.rb
|
253
|
+
- lib/zenaton/refinements/date.rb
|
254
|
+
- lib/zenaton/refinements/date_time.rb
|
255
|
+
- lib/zenaton/refinements/exception.rb
|
256
|
+
- lib/zenaton/refinements/object.rb
|
257
|
+
- lib/zenaton/refinements/open_struct.rb
|
258
|
+
- lib/zenaton/refinements/range.rb
|
259
|
+
- lib/zenaton/refinements/rational.rb
|
260
|
+
- lib/zenaton/refinements/regexp.rb
|
261
|
+
- lib/zenaton/refinements/struct.rb
|
262
|
+
- lib/zenaton/refinements/symbol.rb
|
263
|
+
- lib/zenaton/refinements/time.rb
|
264
|
+
- lib/zenaton/services/graphql.rb
|
213
265
|
- lib/zenaton/services/http.rb
|
214
266
|
- lib/zenaton/services/properties.rb
|
215
267
|
- lib/zenaton/services/serializer.rb
|