prmd 0.7.0 → 0.7.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +21 -4
  4. data/docs/schemata.md +4 -0
  5. data/lib/prmd/core/combiner.rb +4 -34
  6. data/lib/prmd/core/reference_localizer.rb +93 -0
  7. data/lib/prmd/load_schema_file.rb +3 -14
  8. data/lib/prmd/multi_loader.rb +2 -0
  9. data/lib/prmd/multi_loader/json.rb +19 -0
  10. data/lib/prmd/multi_loader/loader.rb +128 -0
  11. data/lib/prmd/multi_loader/toml.rb +19 -0
  12. data/lib/prmd/multi_loader/yajl.rb +19 -0
  13. data/lib/prmd/multi_loader/yaml.rb +19 -0
  14. data/lib/prmd/multi_loader/yml.rb +2 -0
  15. data/lib/prmd/rake_tasks/base.rb +33 -5
  16. data/lib/prmd/rake_tasks/combine.rb +20 -4
  17. data/lib/prmd/rake_tasks/doc.rb +24 -8
  18. data/lib/prmd/rake_tasks/verify.rb +17 -5
  19. data/lib/prmd/schema.rb +5 -1
  20. data/lib/prmd/templates/combine_head.json +3 -3
  21. data/lib/prmd/templates/init_default.json +5 -3
  22. data/lib/prmd/templates/init_resource.json.erb +18 -1
  23. data/lib/prmd/templates/schemata.md.erb +3 -0
  24. data/lib/prmd/templates/schemata/helper.erb +20 -0
  25. data/lib/prmd/templates/schemata/link.md.erb +11 -1
  26. data/lib/prmd/templates/schemata/link_curl_example.md.erb +8 -5
  27. data/lib/prmd/version.rb +1 -1
  28. data/test/commands/render_test.rb +60 -0
  29. data/test/core/reference_localizer_test.rb +65 -0
  30. data/test/helpers.rb +25 -3
  31. data/test/multi_loader/common.rb +35 -0
  32. data/test/multi_loader/json_test.rb +14 -0
  33. data/test/multi_loader/toml_test.rb +18 -0
  34. data/test/multi_loader/yajl_test.rb +18 -0
  35. data/test/multi_loader/yaml_test.rb +14 -0
  36. data/test/rake_tasks/combine_test.rb +38 -0
  37. data/test/rake_tasks/doc_test.rb +31 -0
  38. data/test/rake_tasks/verify_test.rb +23 -0
  39. data/test/schemata/data/test.json +6 -0
  40. data/test/schemata/data/test.toml +4 -0
  41. data/test/schemata/data/test.yaml +3 -0
  42. data/test/schemata/input/rake-meta.json +9 -0
  43. data/test/schemata/input/rake_combine/post.json +100 -0
  44. data/test/schemata/input/rake_combine/user.json +100 -0
  45. data/test/schemata/input/rake_doc.json +223 -0
  46. data/test/schemata/input/rake_verify.json +223 -0
  47. metadata +44 -3
  48. data/Gemfile.lock +0 -23
@@ -0,0 +1,19 @@
1
+ require 'prmd/multi_loader/loader'
2
+ require 'yajl'
3
+
4
+ module Prmd #:nodoc:
5
+ module MultiLoader #:nodoc:
6
+ # JSON MultiLoader using Yajl
7
+ module Yajl
8
+ extend Prmd::MultiLoader::Loader
9
+
10
+ # @see (Prmd::MultiLoader::Loader#load_data)
11
+ def self.load_data(data)
12
+ ::Yajl::Parser.parse(data)
13
+ end
14
+
15
+ # register this loader for all .json files
16
+ extensions '.json'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'prmd/multi_loader/loader'
2
+ require 'yaml'
3
+
4
+ module Prmd #:nodoc:
5
+ module MultiLoader #:nodoc:
6
+ # YAML MultiLoader
7
+ module Yaml
8
+ extend Prmd::MultiLoader::Loader
9
+
10
+ # @see (Prmd::MultiLoader::Loader#load_data)
11
+ def self.load_data(data)
12
+ ::YAML.load(data)
13
+ end
14
+
15
+ # register this loader for all .yaml and .yml files
16
+ extensions '.yaml', '.yml'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ # alias for yaml
2
+ require 'prmd/multi_loader/yaml'
@@ -14,20 +14,48 @@ module Prmd
14
14
  attr_accessor :name
15
15
 
16
16
  # Options to pass to command
17
- # @return [Hash<Symbol, Object>] the options passed to the command
17
+ # @return [Hash<Symbol, Object>] the options passed to the Prmd command
18
18
  attr_accessor :options
19
19
 
20
20
  # Creates a new task with name +name+.
21
21
  #
22
- # @param [String, Symbol] name the name of the rake task
23
- def initialize(name)
24
- @name = name
25
- @options = {}
22
+ # @param [Hash<Symbol, Object>] options
23
+ # .option [String, Symbol] name the name of the rake task
24
+ # .option [String, Symbol] options options to pass to the Prmd command
25
+ def initialize(options = {})
26
+ @name = options.fetch(:name, default_name)
27
+ @options = options.fetch(:options) { {} }
26
28
 
27
29
  yield self if block_given?
28
30
 
29
31
  define
30
32
  end
33
+
34
+ private
35
+
36
+ # This method will be removed in the future
37
+ # @api private
38
+ def legacy_parameters(*args)
39
+ if args.size == 0
40
+ return {}
41
+ else
42
+ arg, = *args
43
+ case arg
44
+ when String, Symbol
45
+ warn "#{self.class}.new(name) has been deprecated, use .new(name: name) instead"
46
+ return { name: arg }
47
+ else
48
+ return arg
49
+ end
50
+ end
51
+ end
52
+
53
+ # Default name of the rake task
54
+ #
55
+ # @return [Symbol]
56
+ def default_name
57
+ :base
58
+ end
31
59
  end
32
60
  end
33
61
  end
@@ -24,10 +24,26 @@ module Prmd
24
24
 
25
25
  # Creates a new task with name +name+.
26
26
  #
27
- # @param [String, Symbol] name the name of the rake task
28
- def initialize(name = :combine)
29
- @paths = []
30
- super
27
+ # @overload initialize(name)
28
+ # @param [String]
29
+ # @overload initialize(options)
30
+ # @param [Hash<Symbol, Object>] options
31
+ # .option [String] output_file
32
+ # .option [Array<String>] paths
33
+ def initialize(*args, &block)
34
+ options = legacy_parameters(*args)
35
+ @paths = options.fetch(:paths) { [] }
36
+ @output_file = options[:output_file]
37
+ super options, &block
38
+ end
39
+
40
+ private
41
+
42
+ # Default name of the rake task
43
+ #
44
+ # @return [Symbol]
45
+ def default_name
46
+ :combine
31
47
  end
32
48
 
33
49
  protected
@@ -15,21 +15,33 @@ module Prmd
15
15
  # t.files = { 'schema/api.json' => 'schema/api.md' }
16
16
  # end
17
17
  class Doc < Base
18
- # Schema files that should be verified
18
+ # Schema files that should be rendered
19
19
  # @return [Array<String>, Hash<String, String>] list of files
20
20
  attr_accessor :files
21
21
 
22
22
  # Creates a new task with name +name+.
23
23
  #
24
- # @param [String, Symbol] name the name of the rake task
25
- def initialize(name = :doc, &block)
26
- @files = []
27
- super name, &block
24
+ # @overload initialize(name)
25
+ # @param [String]
26
+ # @overload initialize(options)
27
+ # @param [Hash<Symbol, Object>] options
28
+ # .option [Array<String>, Hash<String, String>] files schema files
29
+ def initialize(*args, &block)
30
+ options = legacy_parameters(*args)
31
+ @files = options.fetch(:files) { [] }
32
+ super options, &block
28
33
  @options[:template] ||= Prmd::Template.template_dirname
29
34
  end
30
35
 
31
36
  private
32
37
 
38
+ # Default name of the rake task
39
+ #
40
+ # @return [Symbol]
41
+ def default_name
42
+ :doc
43
+ end
44
+
33
45
  # Render file to markdown
34
46
  #
35
47
  # @param [String] filename
@@ -40,13 +52,17 @@ module Prmd
40
52
  Prmd.render(schema, options)
41
53
  end
42
54
 
55
+ # Render +infile+ to +outfile+
56
+ #
43
57
  # @param [String] infile
44
58
  # @param [String] outfile
45
59
  # @return [void]
46
60
  def render_to_file(infile, outfile)
47
61
  result = render_file(infile)
48
- File.open(outfile, 'w') do |file|
49
- file.write(result)
62
+ if outfile
63
+ File.open(outfile, 'w') do |file|
64
+ file.write(result)
65
+ end
50
66
  end
51
67
  end
52
68
 
@@ -55,7 +71,7 @@ module Prmd
55
71
  # Defines the rake task
56
72
  # @return [void]
57
73
  def define
58
- desc 'Verifying schemas' unless Rake.application.last_comment
74
+ desc 'Generate documentation' unless Rake.application.last_comment
59
75
  task(name) do
60
76
  if files.is_a?(Hash)
61
77
  files.each do |infile, outfile|
@@ -19,14 +19,26 @@ module Prmd
19
19
 
20
20
  # Creates a new task with name +name+.
21
21
  #
22
- # @param [String, Symbol] name the name of the rake task
23
- def initialize(name = :verify)
24
- @files = []
25
- super
22
+ # @overload initialize(name)
23
+ # @param [String]
24
+ # @overload initialize(options)
25
+ # @param [Hash<Symbol, Object>] options
26
+ # .option [Array<String>] files schema files to verify
27
+ def initialize(*args, &block)
28
+ options = legacy_parameters(*args)
29
+ @files = options.fetch(:files) { [] }
30
+ super options, &block
26
31
  end
27
32
 
28
33
  private
29
34
 
35
+ # Default name of the rake task
36
+ #
37
+ # @return [Symbol]
38
+ def default_name
39
+ :verify
40
+ end
41
+
30
42
  # Defines the rake task
31
43
  #
32
44
  # @param [String] filename
@@ -46,7 +58,7 @@ module Prmd
46
58
  # Defines the rake task
47
59
  # @return [void]
48
60
  def define
49
- desc 'Verifying schemas' unless Rake.application.last_comment
61
+ desc 'Verify schemas' unless Rake.application.last_comment
50
62
  task(name) do
51
63
  all_errors = []
52
64
  files.each do |filename|
@@ -103,7 +103,11 @@ module Prmd
103
103
  elsif value.key?('items') # array of objects
104
104
  _, items = dereference(value['items'])
105
105
  if value['items'].key?('example')
106
- [items['example']]
106
+ if items["example"].is_a?(Array)
107
+ items["example"]
108
+ else
109
+ [items['example']]
110
+ end
107
111
  else
108
112
  [schema_example(items)]
109
113
  end
@@ -1,6 +1,6 @@
1
1
  {
2
- "$schema": "http://json-schema.org/draft-04/hyper-schema",
2
+ "$schema": "http://interagent.github.io/interagent-hyper-schema",
3
+ "type": ["object"],
3
4
  "definitions": {},
4
- "properties": {},
5
- "type": ["object"]
5
+ "properties": {}
6
6
  }
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-04/hyper-schema",
3
3
  "title": "FIXME",
4
- "definitions": {},
5
4
  "description": "FIXME",
5
+ "stability": "prototype",
6
+ "strictProperties": true,
7
+ "type": ["object"],
8
+ "definitions": {},
6
9
  "links": [],
7
- "properties": {},
8
- "type": ["object"]
10
+ "properties": {}
9
11
  }
@@ -5,11 +5,25 @@
5
5
  "id": {
6
6
  "description": "unique identifier of <%= resource %>",
7
7
  "example": "01234567-89ab-cdef-0123-456789abcdef",
8
+ "readOnly": true,
8
9
  "format": "uuid",
9
10
  "type": ["string"]
10
11
  },
12
+ "name": {
13
+ "description": "unique name of <%= resource %>",
14
+ "example": "name",
15
+ "readOnly": true,
16
+ "type": ["string"]
17
+ },
11
18
  "identity": {
12
- "$ref": "/schemata/<%= resource %>#/definitions/id"
19
+ "anyOf": [
20
+ {
21
+ "$ref": "/schemata/<%= resource %>#/definitions/id"
22
+ },
23
+ {
24
+ "$ref": "/schemata/<%= resource %>#/definitions/name"
25
+ }
26
+ ]
13
27
  },
14
28
  "created_at": {
15
29
  "description": "when <%= resource %> was created",
@@ -31,6 +45,9 @@
31
45
  "id": {
32
46
  "$ref": "/schemata/<%= resource %>#/definitions/id"
33
47
  },
48
+ "name": {
49
+ "$ref": "/schemata/<%= resource %>#/definitions/name"
50
+ },
34
51
  "updated_at": {
35
52
  "$ref": "/schemata/<%= resource %>#/definitions/updated_at"
36
53
  }
@@ -12,16 +12,19 @@
12
12
  -%>
13
13
  <%- unless options[:doc][:disable_title_and_description] %>
14
14
  ## <%= title %>
15
+
15
16
  <%= schemata['description'] %>
16
17
  <%- end -%>
17
18
 
18
19
  <%- if schemata['properties'] && !schemata['properties'].empty? %>
19
20
  ### Attributes
21
+
20
22
  | Name | Type | Description | Example |
21
23
  | ------- | ------- | ------- | ------- |
22
24
  <%- extract_attributes(schema, schemata['properties']).each do |(key, type, description, example)| %>
23
25
  | **<%= key %>** | *<%= type %>* | <%= description %> | <%= example %> |
24
26
  <%- end %>
27
+
25
28
  <%- end %>
26
29
  <%- schemata['links'].each do |link, datum| %>
27
30
  <%=
@@ -2,6 +2,8 @@
2
2
  def extract_attributes(schema, properties)
3
3
  attributes = []
4
4
 
5
+ _, properties = schema.dereference(properties)
6
+
5
7
  properties.each do |key, value|
6
8
  # found a reference to another element:
7
9
  _, value = schema.dereference(value)
@@ -85,6 +87,24 @@
85
87
  description += "<br/> **pattern:** <code>#{value['pattern'].gsub /\|/, '&#124;'}</code>"
86
88
  end
87
89
 
90
+ if value['minLength'] || value['maxLength']
91
+ description += "<br/> **Length:** `"
92
+ if value['minLength']
93
+ description += "#{value['minLength'].to_json}"
94
+ end
95
+ unless value['minLength'] == value['maxLength']
96
+ if value['maxLength']
97
+ unless value['minLength']
98
+ description += "0"
99
+ end
100
+ description += "..#{value['maxLength'].to_json}"
101
+ else
102
+ description += "..∞"
103
+ end
104
+ end
105
+ description += "`"
106
+ end
107
+
88
108
  if value.has_key?('example')
89
109
  example = if value['example'].is_a?(Hash) && value['example'].has_key?('oneOf')
90
110
  value['example']['oneOf'].map { |e| "`#{e.to_json}`" }.join(" or ")
@@ -4,6 +4,7 @@
4
4
  link_schema_properties_template = Prmd::Template.load_template('link_schema_properties.md.erb', options[:template])
5
5
  -%>
6
6
  ### <%= title %> <%= link['title'] %>
7
+
7
8
  <%= link['description'] %>
8
9
 
9
10
  ```
@@ -18,16 +19,19 @@
18
19
  %>
19
20
  <%- unless required.empty? %>
20
21
  #### Required Parameters
22
+
21
23
  <%= link_schema_properties_template.result(params: required, schema: schema, options: options) %>
22
24
 
23
25
  <%- end %>
24
26
  <%- unless optional.empty? %>
25
27
  #### Optional Parameters
28
+
26
29
  <%= link_schema_properties_template.result(params: optional, schema: schema, options: options) %>
27
30
  <%- end %>
28
31
  <%- end %>
29
32
 
30
33
  #### Curl Example
34
+
31
35
  <%=
32
36
  curl_options = options.dup
33
37
  http_header = link['http_header'] || {}
@@ -43,6 +47,7 @@
43
47
  %>
44
48
 
45
49
  #### Response Example
50
+
46
51
  ```
47
52
  <%- if response_example %>
48
53
  <%= response_example['head'] %>
@@ -58,13 +63,18 @@ HTTP/1.1 <%=
58
63
  end %>
59
64
  <%- end %>
60
65
  ```
66
+
61
67
  ```json
62
68
  <%- if response_example %>
63
69
  <%= response_example['body'] %>
64
70
  <%- else %>
65
71
  <%- if link['rel'] == 'empty' %>
66
72
  <%- elsif link.has_key?('targetSchema') %>
67
- <%= JSON.pretty_generate(schema.schema_example(link['targetSchema'])) %>
73
+ <%- if link['targetSchema']['type'] == 'array' -%>
74
+ <%= JSON.pretty_generate(schema.schema_example(link['targetSchema'])) %>
75
+ <%- else -%>
76
+ <%= JSON.pretty_generate([schema.schema_example(link['targetSchema'])]) %>
77
+ <%- end -%>
68
78
  <%- elsif link['rel'] == 'instances' %>
69
79
  <%= JSON.pretty_generate([schema.schemata_example(resource)]) %>
70
80
  <%- else %>
@@ -1,13 +1,13 @@
1
1
  ```bash
2
2
  <%-
3
- data = {}
3
+ data = nil
4
4
  path = path.gsub(/{([^}]*)}/) {|match| '$' + match.gsub(/[{}]/, '').upcase}
5
5
  get_params = []
6
6
 
7
7
  if link.has_key?('schema')
8
- data.merge!(schema.schema_example(link['schema']))
8
+ data = schema.schema_example(link['schema'])
9
9
 
10
- if link['method'].upcase == 'GET' && !data.empty?
10
+ if link['method'].upcase == 'GET' && !data.nil?
11
11
  get_params << Prmd::UrlGenerator.new({schema: schema, link: link, options: options}).url_params
12
12
  end
13
13
  end
@@ -16,14 +16,17 @@
16
16
  options[:http_header] = { 'Content-Type' => options[:content_type] }.merge(options[:http_header])
17
17
  end
18
18
  %>
19
+ <%- if link['method'].upcase != 'GET' %>
19
20
  $ curl -n -X <%= link['method'] %> <%= schema.href %><%= path -%><%- unless options[:http_header].empty? %> \<%- end %>
21
+ <%- else %>
22
+ $ curl -n <%= schema.href %><%= path -%><%- unless options[:http_header].empty? %> \<%- end %>
23
+ <%- end %>
20
24
  <%- options[:http_header].each do |key, value| %>
21
25
  -H "<%= key %>: <%= value %>" \
22
26
  <%- end %>
23
- <%- if !data.empty? && link['method'].upcase != 'GET' %> \
27
+ <%- if !data.nil? && link['method'].upcase != 'GET' %> \
24
28
  -d '<%= JSON.pretty_generate(data) %>'
25
29
  <%- elsif !get_params.empty? && link['method'].upcase == 'GET' %> -G \
26
30
  -d <%= get_params.join(" \\\n -d ") %>
27
31
  <%- end %>
28
-
29
32
  ```