minimum-term 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8b2676a106025dc8b1940e68c3c711b82c77fda
4
- data.tar.gz: 562cea8babc12813ac818aaa140ec5df1d24e865
3
+ metadata.gz: 30209807ad2ee5a4eaf45521202334f1eca06c5c
4
+ data.tar.gz: 568caddb9d7f929e9dfba7b6b27b2840c36ad302
5
5
  SHA512:
6
- metadata.gz: 8b3072fecfb406b52f68f26d1085496cb33fc09a07dc64c42ca73d904c6576bf70efb8d92bb50af1807f5d7696fe1400874dac9a830aedc7bf9d137bc1c95167
7
- data.tar.gz: d6621d9603a127b7b50169f258f22512f794232e40cd8c6daa751c00d8ad2ed30e2676ccd0164387c5e3aa78587a7228db132bbd122f25089847e9935a1f847f
6
+ metadata.gz: 0cb4f3aa6c7f29d4a2f05f82a961a298943801a528da3915e77d7fd1fc5ab85a514427da879520b1d6e844457b91f6fb7f61017feb43f898d0e0d8648f145f97
7
+ data.tar.gz: d782d81469c340aa3cd3016b4e83041eaf45f3ff1d14201471a7aec1ab3d696f4ec83490cf82bc75aa0c08e4882b752c20dc2c00fdf55659a4d3f3885e66ecdf
data/.gitignore CHANGED
@@ -7,3 +7,4 @@ gems.tags
7
7
  coverage
8
8
  **/*.gem
9
9
  Gemfile.lock
10
+ tmp/
data/README.markdown CHANGED
@@ -1,41 +1,26 @@
1
+ [![Circle CI](https://circleci.com/gh/moviepilot/minimum-term/tree/master.svg?style=svg)](https://circleci.com/gh/moviepilot/minimum-term/tree/master) [![Coverage Status](https://coveralls.io/repos/moviepilot/minimum-term/badge.svg?branch=master&service=github)](https://coveralls.io/github/moviepilot/minimum-term?branch=master) [![Code Climate](https://codeclimate.com/github/moviepilot/minimum-term/badges/gpa.svg)](https://codeclimate.com/github/moviepilot/minimum-term)
1
2
  # Minimum term
2
3
 
3
- This shall be a framework so that in each of our services one can define what messages it publishes and what messages it consumes. That way when changing what one service publishes or consumes, one can immediately see the effects on our other services.
4
+ This gem can:
4
5
 
6
+ - convert MSON to JSON Schema files
7
+ - read a directory which contains one directory per service
8
+ - read a publish.mson and a consume.mson from each service
9
+ - build a model of your infrastructure knowing
10
+ - which services publishes what to which other service
11
+ - which service consumes what from which other service
12
+ - if all services consume and publish conforming to their contracts.
5
13
 
6
- ## Prerequesites
14
+ You likely don't want to use it on its own but head on over to the [Old Maid](https://github.com/moviepilot/old-maid) gem which explains things in more detail. If you're just looking for ONE way to transform MSON files into JSON Schema, read on:
7
15
 
8
- - install drafter via `brew install --HEAD
9
- https://raw.github.com/apiaryio/drafter/master/tools/homebrew/drafter.rb`
10
- - run `bundle`
11
-
12
- ## Tests and development
13
- - run `guard` in a spare terminal which will run the tests,
14
- install gems, and so forth
15
- - run `rspec spec` to run all the tests
16
- - check out `open coverage/index.html` or `open coverage/rcov/index.html`
17
- - run `bundle console` to play around with a console
18
-
19
- ## Structure
20
- - Infrastructure
21
- - Service
22
- - Contracts
23
- - Publish contract
24
- - PublishedObjects
25
- - Consume contract
26
- - ConsumedObjects
27
-
28
-
29
- ## Convert MSON to JSON Schema files
16
+ ## Getting started
30
17
  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:
31
18
 
32
19
  ![API Blueprint map](https://raw.githubusercontent.com/apiaryio/api-blueprint/master/assets/map.png)
33
20
 
34
21
  You can see that their structure covers a full API use case with resource groups, single resources, actions on those resources including requests and responses. All we want, though, is the little red top level branch called `Data structures`.
35
22
 
36
- In theory, we'd use a ruby gem called [RedSnow](https://github.com/apiaryio/redsnow), which has bindings to [SnowCrash](https://github.com/apiaryio/snowcrash) which parses _API Blueprints_ into an AST. Unfortunately, RedSnow ignores that red `Data structures` branch we want (SnowCrash parses it just fine).
37
-
38
- So for now, we use a command line tool called [drafter](https://github.com/apiaryio/drafter) to convert MSON into an _API Blueprint_ AST. From that AST we pic the `Data structures` entry and convert it into [JSON Schema]()s
23
+ We're using a ruby gem called [RedSnow](https://github.com/apiaryio/redsnow), which has bindings to [SnowCrash](https://github.com/apiaryio/snowcrash) which parses _API Blueprints_ into an AST.
39
24
 
40
25
  Luckily, a rake task does all that for you. To convert all `*.mson` files in `contracts/` into `*.schema.json` files,
41
26
 
@@ -56,3 +41,23 @@ OK /home/dev/minimum-term/contracts/missing_required/consume.mson
56
41
  OK /home/dev/minimum-term/contracts/publisher/publish.mson
57
42
  /home/dev/minimum-term$
58
43
  ```
44
+
45
+ ## Tests and development
46
+ - run `bundle` once
47
+ - run `guard` in a spare terminal which will run the tests,
48
+ install gems, and so forth
49
+ - run `rspec spec` to run all the tests
50
+ - check out `open coverage/index.html` or `open coverage/rcov/index.html`
51
+ - run `bundle console` to play around with a console
52
+
53
+ ## Structure
54
+
55
+ By converting all files in a directory this gem will build up the following relationships:
56
+
57
+ - Infrastructure
58
+ - Service
59
+ - Contracts
60
+ - Publish contract
61
+ - PublishedObjects
62
+ - Consume contract
63
+ - ConsumedObjects
data/circle.yml CHANGED
@@ -1,5 +1,3 @@
1
- general:
2
- build_dir: ruby
3
1
  machine:
4
2
  ruby:
5
3
  version: 2.2.1
@@ -2,6 +2,7 @@ require 'fileutils'
2
2
  require 'open3'
3
3
  require 'minimum-term/conversion/apiary_to_json_schema'
4
4
  require 'minimum-term/conversion/error'
5
+ require 'redsnow'
5
6
 
6
7
  module MinimumTerm
7
8
  module Conversion
@@ -23,11 +24,10 @@ module MinimumTerm
23
24
 
24
25
  # Parse MSON to an apiary blueprint AST
25
26
  # (see https://github.com/apiaryio/api-blueprint/wiki/API-Blueprint-Map)
26
- to_ast = mson_to_ast_json(filename)
27
- raise Error, "Error: #{to_ast}" unless to_ast[:status] == 0
27
+ ast_file = mson_to_ast_json(filename)
28
28
 
29
29
  # Pluck out Data structures from it
30
- data_structures = data_structures_from_blueprint_ast(to_ast[:outfile])
30
+ data_structures = data_structures_from_blueprint_ast(ast_file)
31
31
 
32
32
  # Generate json schema from each contained data structure
33
33
  schema = {
@@ -83,9 +83,8 @@ module MinimumTerm
83
83
  # }
84
84
  #
85
85
  data_structures.each do |data|
86
- schema_data = data['content'].select{|d| d['element'] == 'object' }.first
87
- id = schema_data['meta']['id']
88
- json= DataStructure.new(id, schema_data, data_structure_autoscope).to_json
86
+ id = data['name']['literal']
87
+ json= DataStructure.new(id, data, data_structure_autoscope).to_json
89
88
  member = json.delete('title')
90
89
  schema['definitions'][member] = json
91
90
  schema['properties'][member] = {"$ref" => "#/definitions/#{member}"}
@@ -96,12 +95,12 @@ module MinimumTerm
96
95
  File.open(outfile, 'w'){ |f| f.puts JSON.pretty_generate(schema) }
97
96
 
98
97
  # Clean up
99
- FileUtils.rm_f(to_ast[:outfile]) unless keep_intermediary_files
98
+ FileUtils.rm_f(ast_file) unless keep_intermediary_files
100
99
  true
101
100
  end
102
101
 
103
102
  def self.data_structures_from_blueprint_ast(filename)
104
- c = JSON.parse(open(filename).read)['content'].first
103
+ c = JSON.parse(open(filename).read)['ast']['content'].first
105
104
  return [] unless c
106
105
  c['content']
107
106
  end
@@ -110,16 +109,24 @@ module MinimumTerm
110
109
  input = filename
111
110
  output = filename.gsub(/\.\w+$/, '.blueprint-ast.json')
112
111
 
113
- cmd = "drafter -u -f json -o #{Shellwords.escape(output)} #{Shellwords.escape(input)}"
114
- stdin, stdout, status = Open3.capture3(cmd)
115
112
 
116
- {
117
- cmd: cmd,
118
- outfile: output,
119
- stdin: stdin,
120
- stdout: stdout,
121
- status: status
122
- }
113
+ parse_result = FFI::MemoryPointer.new :pointer
114
+ RedSnow::Binding.drafter_c_parse(open(input).read, 0, parse_result)
115
+ parse_result = parse_result.get_pointer(0)
116
+
117
+ status = -1
118
+ result = ''
119
+
120
+ unless parse_result.null?
121
+ status = 0
122
+ result = parse_result.read_string
123
+ end
124
+
125
+ File.open(output, 'w'){ |f| f.puts(result) }
126
+
127
+ output
128
+ ensure
129
+ RedSnow::Memory.free(parse_result)
123
130
  end
124
131
  end
125
132
  end
@@ -26,47 +26,46 @@ module MinimumTerm
26
26
  private
27
27
 
28
28
  def add_description_to_json_schema
29
- return unless @data['meta']
30
- description = @data['meta']['description']
29
+ return unless @data['sections']
30
+ description = @data['sections'].select{|d| d['class'] == 'blockDescription' }.first
31
31
  return unless description
32
- @schema['description'] = description.strip
32
+ @schema['description'] = description['content'].strip
33
33
  end
34
34
 
35
35
  def add_properties_to_json_schema
36
- return unless @data['content']
37
- members = @data['content'].select{|d| d['element'] == 'member' }
36
+ return unless @data['sections']
37
+ members = @data['sections'].select{|d| d['class'] == 'memberType' }.first['content'].select{|d| d['class'] == 'property' }
38
38
  members.each do |s|
39
39
  content = s['content']
40
- type = content['value']['element']
40
+ type_definition = content['valueDefinition']['typeDefinition']
41
+ type = type_definition['typeSpecification']['name']
41
42
 
42
43
  spec = {}
43
- name = s['content']['key']['content'].underscore
44
+ name = content['name']['literal'].underscore
44
45
 
45
46
  # This is either type: primimtive or $ref: reference_name
46
47
  spec.merge!(primitive_or_reference(type))
47
48
 
48
- value_content = content['value']['content']
49
-
50
49
  # We might have a description
51
- spec['description'] = s['meta']['description'] if s['meta']
50
+ spec['description'] = s['description']
52
51
 
53
52
  # If it's an array, we need to pluck out the item types
54
53
  if type == 'array'
55
- nestedTypes = value_content.map{|d| d['element'] }.compact
54
+ nestedTypes = type_definition['typeSpecification']['nestedTypes']
56
55
  spec['items'] = nestedTypes.map{|t| primitive_or_reference(t) }
57
56
 
58
57
  # If it's an object, we need recursion
59
58
  elsif type == 'object'
60
59
  spec['properties'] = {}
61
- value_content.select{|d| d['element'] == 'member'}.each do |data|
62
- data_structure = DataStructure.new('tmp', content['value'], @scope).to_json
60
+ content['sections'].select{|d| d['class'] == 'memberType'}.each do |data|
61
+ data_structure = DataStructure.new('tmp', content, @scope).to_json
63
62
  spec['properties'].merge!(data_structure['properties'])
64
63
  end
65
64
  end
66
65
 
67
66
  @schema['properties'][name] = spec
68
- if attributes = s['attributes']
69
- @schema['required'] << name if attributes['typeAttributes'].include?('required')
67
+ if attributes = type_definition['attributes']
68
+ @schema['required'] << name if attributes.include?('required')
70
69
  end
71
70
  end
72
71
  end
@@ -75,7 +74,7 @@ module MinimumTerm
75
74
  if PRIMITIVES.include?(type)
76
75
  { 'type' => type }
77
76
  else
78
- { '$ref' => "#/definitions/#{self.class.scope(@scope, type)}" }
77
+ { '$ref' => "#/definitions/#{self.class.scope(@scope, type['literal'])}" }
79
78
  end
80
79
  end
81
80
 
@@ -1,3 +1,3 @@
1
1
  module MinimumTerm
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
data/minimum-term.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_runtime_dependency "activesupport", ["~> 4.2"]
23
23
  spec.add_runtime_dependency "rake", ["~> 10.2"]
24
24
  spec.add_runtime_dependency "json-schema", ["~> 2.5"]
25
+ spec.add_runtime_dependency "redsnow", ["~> 0.4"]
25
26
  spec.add_runtime_dependency "colorize"
26
27
 
27
28
  spec.add_development_dependency "bundler", ["~> 1"]
@@ -29,5 +30,6 @@ Gem::Specification.new do |spec|
29
30
  spec.add_development_dependency "guard-ctags-bundler", ["~> 1.4"]
30
31
  spec.add_development_dependency "guard-rspec", ["~> 4.6"]
31
32
  spec.add_development_dependency "rspec", ["~> 3.3"]
32
- spec.add_development_dependency "simplecov-rcov", ["~> 0.2"]
33
+ spec.add_development_dependency "coveralls", ["~> 0.8"]
34
+ spec.add_development_dependency "codeclimate-test-reporter"
33
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minimum-term
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jannis Hermanns
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: redsnow
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.4'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: colorize
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -137,19 +151,33 @@ dependencies:
137
151
  - !ruby/object:Gem::Version
138
152
  version: '3.3'
139
153
  - !ruby/object:Gem::Dependency
140
- name: simplecov-rcov
154
+ name: coveralls
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '0.2'
159
+ version: '0.8'
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '0.2'
166
+ version: '0.8'
167
+ - !ruby/object:Gem::Dependency
168
+ name: codeclimate-test-reporter
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
153
181
  description: Specify which objects your services publish or consume in MSON (markdown)
154
182
  and let this gem validate these contracts.
155
183
  email:
@@ -218,3 +246,4 @@ signing_key:
218
246
  specification_version: 4
219
247
  summary: Markdown publish/consume contract parser and validator
220
248
  test_files: []
249
+ has_rdoc: