lacerda 0.11.0 → 0.12.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/CHANGELOG.markdown +11 -0
- data/Guardfile +1 -5
- data/README.md +34 -20
- data/lacerda.gemspec +4 -1
- data/lib/lacerda.rb +7 -0
- data/lib/lacerda/compare/json_schema.rb +46 -7
- data/lib/lacerda/consume_specification.rb +42 -6
- data/lib/lacerda/conversion/data_structure.rb +0 -1
- data/lib/lacerda/object_description.rb +4 -1
- data/lib/lacerda/publish_specification.rb +14 -7
- data/lib/lacerda/service.rb +17 -0
- data/lib/lacerda/version.rb +1 -1
- metadata +46 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13bff5451aa612adedb40d0d20a26d6826796546
|
4
|
+
data.tar.gz: 4051b656fe279dea8381b73351b4dbc7a55d0cb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d80147036af1a6424d731c34141d670519996363e3e1234ee5ee6e05393581bf0f07e63ebe6b883e2864851ffd83264ba4e18e26f68041b3cdeb4e385e660298
|
7
|
+
data.tar.gz: fb3ca9e05a706d6bae08d0461f5b6c319724120cb385af737bc25771eb8721934f950a58f76d29abdf066942b5a47e595211cacf25b785a3ff03ac9c98225674
|
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# 0.12.0 (06-Nov-15)
|
2
|
+
- add Lacerda::Service#publishes?(object_name)
|
3
|
+
- add Lacerda::Service#consumes?(object_name)
|
4
|
+
- add Lacerda::Service#consumes_from?(service_name, object_name)
|
5
|
+
- add Lacerda::Service#consume_object_from(service_name, object_name)
|
6
|
+
- load Lacerda::VERSION
|
7
|
+
- add missing json-schema require
|
8
|
+
- fix a typo in the ERR_MISSING_DEFINITION error message
|
9
|
+
- update blumquist
|
10
|
+
- allow top level types without a publishing service prefix in consume specifications
|
11
|
+
|
1
12
|
# 0.11.0 (04-Nov-15)
|
2
13
|
- rename ConsumeContract and PublishContract to ConsumeSpecification and PublishSpecification
|
3
14
|
- omit redundant service name in model names of publish contracts
|
data/Guardfile
CHANGED
@@ -27,14 +27,10 @@ guard 'ctags-bundler', :src_path => ["lib"] do
|
|
27
27
|
watch(/^.+\.gemspec/)
|
28
28
|
end
|
29
29
|
|
30
|
-
guard :rspec, cmd: '
|
30
|
+
guard :rspec, cmd: 'rspec', all_on_start: true do
|
31
31
|
watch(%r{^spec/support/.*\.mson$}) { "spec" }
|
32
32
|
watch(%r{^spec/support/.*\.rb$}) { "spec" }
|
33
33
|
watch('spec/spec_helper.rb') { "spec" }
|
34
|
-
|
35
|
-
# We could run individual specs, sure, but for now I dictate the tests
|
36
|
-
# are only green when we have 100% coverage, so partial runs will never
|
37
|
-
# succeed. Therefore, always run all the things.
|
38
34
|
watch(%r{^(spec/.+_spec\.rb)$}) { "spec" }
|
39
35
|
watch(%r{^lib/(.+)\.rb$}) { "spec" }
|
40
36
|
end
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Lacerda [](https://circleci.com/gh/moviepilot/lacerda/tree/master) [](https://coveralls.io/github/moviepilot/lacerda?branch=master) [](https://codeclimate.com/github/moviepilot/lacerda) [](https://gemnasium.com/moviepilot/lacerda) [](https://badge.fury.io/rb/lacerda)
|
2
2
|
|
3
3
|

|
4
4
|
> «No, no -- we have to go on. We need total coverage.»<sup>[1](#references)</sup>
|
@@ -13,18 +13,15 @@ This gem can:
|
|
13
13
|
- which service consumes what from which other service
|
14
14
|
- if all services consume and publish conforming to their contracts.
|
15
15
|
|
16
|
-
You likely don't want to use it on its own but
|
16
|
+
You likely **don't want to use it on its own** but integrate your infrastructure via
|
17
17
|
|
18
|
-
|
19
|
-
First, check out [this API Blueprint map](https://github.com/apiaryio/api-blueprint/wiki/API-Blueprint-Map) to understand how _API Blueprint_ documents are laid out:
|
18
|
+
⏩[Zeta](https://github.com/moviepilot/zeta) ⏪
|
20
19
|
|
21
|
-
|
20
|
+
. Click the link, it will explains things in more detail. If you're just looking for *one* way to transform MSON files into JSON Schema, read on:
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Luckily, a rake task does all that for you. To convert all `*.mson` files in `contracts/` into `*.schema.json` files,
|
22
|
+
## MSON to JSON schema
|
23
|
+
*Lacerda* offers a rake task that converts MSON files into JSON schemas.
|
24
|
+
To convert all `*.mson` files in `contracts/` into `*.schema.json` files,
|
28
25
|
|
29
26
|
put this in your `Rakefile`:
|
30
27
|
|
@@ -44,17 +41,10 @@ OK /home/dev/lacerda/specifications/publisher/publish.mson
|
|
44
41
|
/home/dev/lacerda$
|
45
42
|
```
|
46
43
|
|
47
|
-
## Tests and development
|
48
|
-
- run `bundle` once
|
49
|
-
- run `guard` in a spare terminal which will run the tests,
|
50
|
-
install gems, and so forth
|
51
|
-
- run `rspec spec` to run all the tests
|
52
|
-
- check out `open coverage/index.html` or `open coverage/rcov/index.html`
|
53
|
-
- run `bundle console` to play around with a console
|
54
|
-
|
55
44
|
## Structure
|
56
45
|
|
57
|
-
By
|
46
|
+
By loading all files in a directory this gem will build up the following
|
47
|
+
relationships:
|
58
48
|
|
59
49
|
- Infrastructure
|
60
50
|
- Service
|
@@ -64,6 +54,30 @@ By converting all files in a directory this gem will build up the following rela
|
|
64
54
|
- Consume specification
|
65
55
|
- ConsumedObjects
|
66
56
|
|
67
|
-
|
57
|
+
## Compatibility
|
58
|
+
|
59
|
+
Until there is a native MSON to JSON schema parser available, we do the
|
60
|
+
conversion ourselves. These features from the MSON specification are currently supported:
|
68
61
|
|
62
|
+
- [x] primitive properties: `string`, `number`, `boolean`, `null`
|
63
|
+
- [x] `object` properties
|
64
|
+
- [x] `array` properties with items of one type
|
65
|
+
- [ ] `array` properties of mixed types
|
66
|
+
- [ ] `array` properties of arrays
|
67
|
+
- [ ] `enum` properties
|
68
|
+
- [ ] `One of` properties mutually exclusive properties
|
69
|
+
- [x] `Referencing`
|
70
|
+
- [ ] `Mixins`
|
71
|
+
- [ ] Variable property names
|
72
|
+
|
73
|
+
|
74
|
+
## Tests and development
|
75
|
+
- run `bundle` once
|
76
|
+
- run `guard` in a spare terminal which will run the tests,
|
77
|
+
install gems, and so forth
|
78
|
+
- run `rspec spec` to run all the tests
|
79
|
+
- check out `open coverage/index.html` or `open coverage/rcov/index.html`
|
80
|
+
- run `bundle console` to play around with a console
|
81
|
+
|
82
|
+
# References
|
69
83
|
[1] This quote in French quotation marks is from "Fear and Loathing in Las Vegas". Since I can't link to the book, a link to the [movie script](http://www.dailyscript.com/scripts/fearandloathing.html) shall suffice.
|
data/lacerda.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency "json-schema", ["~> 2.5"]
|
25
25
|
spec.add_runtime_dependency "redsnow", ["~> 0.4"]
|
26
26
|
spec.add_runtime_dependency "colorize"
|
27
|
-
spec.add_runtime_dependency "blumquist", ["~> 0.
|
27
|
+
spec.add_runtime_dependency "blumquist", ["~> 0.3"]
|
28
28
|
|
29
29
|
spec.add_development_dependency "bundler", ["~> 1"]
|
30
30
|
spec.add_development_dependency "guard-bundler", ["~> 2.1"]
|
@@ -33,4 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency "rspec", ["~> 3.3"]
|
34
34
|
spec.add_development_dependency "coveralls", ["~> 0.8"]
|
35
35
|
spec.add_development_dependency "codeclimate-test-reporter"
|
36
|
+
spec.add_development_dependency 'pry'
|
37
|
+
spec.add_development_dependency 'pry-rescue'
|
38
|
+
spec.add_development_dependency 'pry-stack_explorer'
|
36
39
|
end
|
data/lib/lacerda.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'lacerda/version'
|
1
2
|
require 'lacerda/conversion'
|
2
3
|
require 'lacerda/publish_specification'
|
3
4
|
require 'lacerda/consume_specification'
|
@@ -7,6 +8,7 @@ require 'lacerda/compare/json_schema'
|
|
7
8
|
require 'lacerda/reporter'
|
8
9
|
require 'lacerda/reporters/multi'
|
9
10
|
require 'lacerda/reporters/stdout'
|
11
|
+
require 'active_support/core_ext/string'
|
10
12
|
|
11
13
|
module Lacerda
|
12
14
|
SCOPE_SEPARATOR = '::'
|
@@ -24,4 +26,9 @@ module Lacerda
|
|
24
26
|
.underscore
|
25
27
|
.gsub(/:/, SCOPE_SEPARATOR)
|
26
28
|
end
|
29
|
+
|
30
|
+
# Poor man's deep copy: json 🆗 🆒
|
31
|
+
def self.deep_copy(object)
|
32
|
+
JSON.parse({m: object}.to_json)['m']
|
33
|
+
end
|
27
34
|
end
|
@@ -3,7 +3,7 @@ module Lacerda
|
|
3
3
|
class JsonSchema
|
4
4
|
ERRORS = {
|
5
5
|
:ERR_ARRAY_ITEM_MISMATCH => "The items in the published array don't match the consumer's specification.",
|
6
|
-
:ERR_MISSING_DEFINITION => "The publish specification is missing a type defined in
|
6
|
+
:ERR_MISSING_DEFINITION => "The publish specification is missing a type defined in the consumer's specification.",
|
7
7
|
:ERR_MISSING_POINTER => "A JSON pointer could not be resolved.",
|
8
8
|
:ERR_MISSING_PROPERTY => "The published object is missing a property required by your specification.",
|
9
9
|
:ERR_MISSING_REQUIRED => "The published object has an optional property that you marked as required in your specification.",
|
@@ -22,18 +22,27 @@ module Lacerda
|
|
22
22
|
@errors = []
|
23
23
|
@initial_location = initial_location
|
24
24
|
@contained_schema = contained_schema
|
25
|
-
|
25
|
+
properties_contained?
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def
|
31
|
-
@contained_schema['
|
32
|
-
|
30
|
+
def properties_contained?
|
31
|
+
@contained_schema['properties'].each do |property, contained_property|
|
32
|
+
resolved_contained_property = data_for_pointer(property, @contained_schema)
|
33
|
+
containing_property = @containing_schema['properties'][property]
|
33
34
|
if !containing_property
|
34
35
|
_e(:ERR_MISSING_DEFINITION, [@initial_location, property])
|
35
36
|
else
|
36
|
-
|
37
|
+
resolved_containing_property = data_for_pointer(
|
38
|
+
containing_property,
|
39
|
+
@containing_schema
|
40
|
+
)
|
41
|
+
schema_contains?(
|
42
|
+
resolved_containing_property,
|
43
|
+
resolved_contained_property,
|
44
|
+
[property]
|
45
|
+
)
|
37
46
|
end
|
38
47
|
end
|
39
48
|
@errors.empty?
|
@@ -49,7 +58,7 @@ module Lacerda
|
|
49
58
|
|
50
59
|
# We can only compare types and $refs, so let's make
|
51
60
|
# sure they're there
|
52
|
-
return _e(:ERR_MISSING_TYPE_AND_REF) unless
|
61
|
+
return _e(:ERR_MISSING_TYPE_AND_REF, location) unless
|
53
62
|
(consume['type'] or consume['$ref']) and
|
54
63
|
(publish['type'] or publish['$ref'])
|
55
64
|
|
@@ -117,6 +126,36 @@ module Lacerda
|
|
117
126
|
true
|
118
127
|
end
|
119
128
|
|
129
|
+
# Resolve pointer data idempotent(ally?). It will resolve
|
130
|
+
#
|
131
|
+
# "foobar"
|
132
|
+
#
|
133
|
+
# or
|
134
|
+
#
|
135
|
+
# { "$ref": "#/definitions/foobar" }
|
136
|
+
#
|
137
|
+
# or
|
138
|
+
#
|
139
|
+
# { "type": "whatever", ... }
|
140
|
+
#
|
141
|
+
# to
|
142
|
+
#
|
143
|
+
# { "type" :"whatever", ... }
|
144
|
+
#
|
145
|
+
def data_for_pointer(data_or_pointer, schema)
|
146
|
+
data = nil
|
147
|
+
if data_or_pointer['type']
|
148
|
+
data = data_or_pointer
|
149
|
+
elsif pointer = data_or_pointer['$ref']
|
150
|
+
data = resolve_pointer(pointer, schema)
|
151
|
+
else
|
152
|
+
data = schema['definitions'][data_or_pointer]
|
153
|
+
end
|
154
|
+
data
|
155
|
+
end
|
156
|
+
|
157
|
+
# Looks up a pointer like #/definitions/foobar and return
|
158
|
+
# its definition
|
120
159
|
def resolve_pointer(pointer, schema)
|
121
160
|
type = pointer[/\#\/definitions\/([^\/]+)$/, 1]
|
122
161
|
return false unless type
|
@@ -1,7 +1,34 @@
|
|
1
|
+
require 'json'
|
1
2
|
require 'lacerda/specification'
|
2
3
|
|
3
4
|
module Lacerda
|
4
5
|
class ConsumeSpecification < Lacerda::Specification
|
6
|
+
|
7
|
+
# We will remove any properties from the schema that are not referencing
|
8
|
+
# a published object from another service, but that are just local definitions
|
9
|
+
# i.e.
|
10
|
+
#
|
11
|
+
# {
|
12
|
+
# "type": "object",
|
13
|
+
# "definitions": {
|
14
|
+
# "message_properties": { ...},
|
15
|
+
# "service::message": {...}
|
16
|
+
# "
|
17
|
+
# }
|
18
|
+
# "properties": {
|
19
|
+
# "message_properties": { "$ref": "#/message_properties }, <- remove
|
20
|
+
# "service::message": { "$ref": "#/service::message" } <- keep
|
21
|
+
# }
|
22
|
+
# }
|
23
|
+
#
|
24
|
+
def initialize(service, schema_or_file)
|
25
|
+
super
|
26
|
+
return unless @schema['properties']
|
27
|
+
@schema['properties'] = @schema['properties'].keep_if do |k, v|
|
28
|
+
!!k.index(Lacerda::SCOPE_SEPARATOR)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
5
32
|
def object_description_class
|
6
33
|
Lacerda::ConsumedObject
|
7
34
|
end
|
@@ -9,19 +36,28 @@ module Lacerda
|
|
9
36
|
def scoped_schema(service)
|
10
37
|
service_name_prefix = Lacerda.underscore(service.name + Lacerda::SCOPE_SEPARATOR)
|
11
38
|
|
12
|
-
|
13
|
-
filtered_schema
|
14
|
-
filtered_schema['definitions'].select! do |k|
|
39
|
+
filtered_schema = Lacerda.deep_copy(schema)
|
40
|
+
filtered_schema['properties'].select! do |k|
|
15
41
|
Lacerda.underscore(k).start_with?(service_name_prefix)
|
16
42
|
end
|
17
43
|
filtered_schema
|
18
44
|
end
|
19
45
|
|
46
|
+
def object?(name)
|
47
|
+
underscored_name = Lacerda.underscore(name)
|
48
|
+
!!@schema[:definitions][underscored_name]
|
49
|
+
end
|
50
|
+
|
20
51
|
def object(name)
|
21
52
|
underscored_name = Lacerda.underscore(name)
|
22
|
-
|
23
|
-
raise Lacerda::Service::InvalidObjectTypeError.new(underscored_name) unless
|
24
|
-
|
53
|
+
object_schema = Lacerda.deep_copy(@schema[:definitions][underscored_name])
|
54
|
+
raise Lacerda::Service::InvalidObjectTypeError.new("Invalid object type: #{underscored_name.to_s.to_json}") unless object_schema
|
55
|
+
|
56
|
+
# Copy the definitions of our schema into the schema for the
|
57
|
+
# object in case its properties include json pointers
|
58
|
+
object_schema[:definitions] = Lacerda.deep_copy(@schema[:definitions])
|
59
|
+
|
60
|
+
Lacerda::ConsumedObject.new(service, name, object_schema)
|
25
61
|
end
|
26
62
|
end
|
27
63
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'json-schema'
|
2
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
3
|
+
|
1
4
|
# This represents a description of an Object (as it was in MSON and later
|
2
5
|
# JSON Schema). It can come in two flavors:
|
3
6
|
#
|
@@ -21,7 +24,7 @@ module Lacerda
|
|
21
24
|
@defined_in_service = defined_in_service
|
22
25
|
@scoped_name = scoped_name
|
23
26
|
@name = remove_service_from_scoped_name(scoped_name)
|
24
|
-
@schema = schema
|
27
|
+
@schema = schema.with_indifferent_access
|
25
28
|
end
|
26
29
|
|
27
30
|
def validate_data!(data)
|
@@ -20,14 +20,13 @@ module Lacerda
|
|
20
20
|
result
|
21
21
|
end
|
22
22
|
|
23
|
-
def object(name)
|
24
|
-
scoped_name =
|
25
|
-
|
26
|
-
|
27
|
-
unless scoped_name.start_with?(Lacerda.underscore(service.name))
|
28
|
-
scoped_name = [Lacerda.underscore(service.name), scoped_name].join(Lacerda::SCOPE_SEPARATOR)
|
29
|
-
end
|
23
|
+
def object?(name)
|
24
|
+
scoped_name = scopify_name(name)
|
25
|
+
!!@schema[:definitions][scoped_name]
|
26
|
+
end
|
30
27
|
|
28
|
+
def object(name)
|
29
|
+
scoped_name = scopify_name(name)
|
31
30
|
schema = @schema[:definitions][scoped_name]
|
32
31
|
raise Lacerda::Service::InvalidObjectTypeError.new(scoped_name) unless schema
|
33
32
|
Lacerda::PublishedObject.new(service, scoped_name, schema)
|
@@ -35,6 +34,14 @@ module Lacerda
|
|
35
34
|
|
36
35
|
private
|
37
36
|
|
37
|
+
def scopify_name(name)
|
38
|
+
scoped_name = Lacerda.underscore(name.to_s)
|
39
|
+
|
40
|
+
# Add our own prefix automatically if necessary
|
41
|
+
return scoped_name if scoped_name.start_with?(Lacerda.underscore(service.name))
|
42
|
+
[Lacerda.underscore(service.name), scoped_name].join(Lacerda::SCOPE_SEPARATOR)
|
43
|
+
end
|
44
|
+
|
38
45
|
def object_description_class
|
39
46
|
Lacerda::PublishedObject
|
40
47
|
end
|
data/lib/lacerda/service.rb
CHANGED
@@ -28,10 +28,23 @@ module Lacerda
|
|
28
28
|
|
29
29
|
def consumed_objects(publisher = nil)
|
30
30
|
@consume.objects.select do |o|
|
31
|
+
next if o.publisher_name.blank?
|
31
32
|
publisher.blank? or o.publisher == publisher
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
36
|
+
def publishes?(object_name)
|
37
|
+
@publish.object?(object_name.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
def consumes?(object_name)
|
41
|
+
@consume.object?(object_name.to_s)
|
42
|
+
end
|
43
|
+
|
44
|
+
def consumes_from?(service_name, object_name)
|
45
|
+
@consume.object?([service_name, object_name].join(Lacerda::SCOPE_SEPARATOR))
|
46
|
+
end
|
47
|
+
|
35
48
|
def published_objects
|
36
49
|
@publish.objects
|
37
50
|
end
|
@@ -77,6 +90,10 @@ module Lacerda
|
|
77
90
|
object_description.validate_data!(data)
|
78
91
|
end
|
79
92
|
|
93
|
+
def consume_object_from(service_name, type, data)
|
94
|
+
consume_object([service_name, type].join(Lacerda::SCOPE_SEPARATOR), data)
|
95
|
+
end
|
96
|
+
|
80
97
|
def consume_object(type, data)
|
81
98
|
object_description = @consume.object(type)
|
82
99
|
Blumquist.new(schema: object_description.schema, data: data)
|
data/lib/lacerda/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lacerda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jannis Hermanns
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
89
|
+
version: '0.3'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
96
|
+
version: '0.3'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: bundler
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,6 +192,48 @@ dependencies:
|
|
192
192
|
- - ">="
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: pry
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: pry-rescue
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: pry-stack_explorer
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
195
237
|
description: Specify which objects your services publish or consume in MSON (markdown)
|
196
238
|
and let this gem validate these contracts.
|
197
239
|
email:
|