prmd 0.6.2 → 0.7.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.
Files changed (63) hide show
  1. checksums.yaml +5 -13
  2. data/CONTRIBUTORS.md +8 -0
  3. data/Gemfile.lock +6 -6
  4. data/README.md +57 -8
  5. data/Rakefile +4 -4
  6. data/bin/prmd +3 -117
  7. data/docs/schemata.md +11 -11
  8. data/lib/prmd.rb +7 -18
  9. data/lib/prmd/cli.rb +108 -0
  10. data/lib/prmd/cli/base.rb +151 -0
  11. data/lib/prmd/cli/combine.rb +42 -0
  12. data/lib/prmd/cli/doc.rb +69 -0
  13. data/lib/prmd/cli/generate.rb +44 -0
  14. data/lib/prmd/cli/render.rb +48 -0
  15. data/lib/prmd/cli/verify.rb +49 -0
  16. data/lib/prmd/commands.rb +4 -0
  17. data/lib/prmd/commands/combine.rb +85 -58
  18. data/lib/prmd/commands/init.rb +30 -98
  19. data/lib/prmd/commands/render.rb +30 -17
  20. data/lib/prmd/commands/verify.rb +78 -35
  21. data/lib/prmd/core/combiner.rb +91 -0
  22. data/lib/prmd/core/generator.rb +27 -0
  23. data/lib/prmd/core/renderer.rb +56 -0
  24. data/lib/prmd/core/schema_hash.rb +47 -0
  25. data/lib/prmd/core_ext/optparse.rb +6 -0
  26. data/lib/prmd/hash_helpers.rb +38 -0
  27. data/lib/prmd/load_schema_file.rb +25 -0
  28. data/lib/prmd/rake_tasks/base.rb +33 -0
  29. data/lib/prmd/rake_tasks/combine.rb +50 -0
  30. data/lib/prmd/rake_tasks/doc.rb +73 -0
  31. data/lib/prmd/rake_tasks/verify.rb +60 -0
  32. data/lib/prmd/schema.rb +86 -34
  33. data/lib/prmd/template.rb +65 -8
  34. data/lib/prmd/templates/combine_head.json +6 -0
  35. data/lib/prmd/templates/init_default.json +9 -0
  36. data/lib/prmd/templates/init_resource.json.erb +90 -0
  37. data/lib/prmd/templates/link_schema_properties.md.erb +5 -0
  38. data/lib/prmd/templates/schema.erb +2 -2
  39. data/lib/prmd/templates/schemata.md.erb +37 -0
  40. data/lib/prmd/templates/schemata/helper.erb +29 -15
  41. data/lib/prmd/templates/schemata/link.md.erb +74 -0
  42. data/lib/prmd/templates/schemata/{link_curl_example.erb → link_curl_example.md.erb} +8 -2
  43. data/lib/prmd/url_generator.rb +11 -69
  44. data/lib/prmd/url_generators/generators/default.rb +66 -0
  45. data/lib/prmd/url_generators/generators/json.rb +30 -0
  46. data/lib/prmd/version.rb +10 -1
  47. data/prmd.gemspec +15 -15
  48. data/test/cli/combine_test.rb +23 -0
  49. data/test/cli/doc_test.rb +25 -0
  50. data/test/cli/generate_test.rb +23 -0
  51. data/test/cli/render_test.rb +25 -0
  52. data/test/cli/verify_test.rb +21 -0
  53. data/test/commands/init_test.rb +7 -0
  54. data/test/commands/render_test.rb +93 -0
  55. data/test/commands/verify_test.rb +60 -60
  56. data/test/helpers.rb +61 -6
  57. data/test/schema_test.rb +17 -11
  58. data/test/schemata/input/doc-settings.json +4 -0
  59. metadata +73 -28
  60. data/lib/prmd/commands/expand.rb +0 -108
  61. data/lib/prmd/templates/link_schema_properties.erb +0 -16
  62. data/lib/prmd/templates/schemata.erb +0 -47
  63. data/lib/prmd/templates/schemata/link.erb +0 -61
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZGYzNzgzNTU3YWQwMTRmNzI5ZTVkYThhMDQwMGJkZWQxM2IzODVkOA==
5
- data.tar.gz: !binary |-
6
- NGNlZDM3N2JkMzUxMmYyYjk1ZjUwNDYyMzMyYzg4MmY2NTE5MTkzOQ==
2
+ SHA1:
3
+ metadata.gz: 92c67299c0bc9e4bec5141b516ec7fa78d841f6d
4
+ data.tar.gz: dbcdf2ec6712b37f5980904e998d7085d3ca6dc9
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZjVjMmE5MTNlYjk5ZjU1MzYyZGRjNzNhMTE2Nzk4NDE4NDkyMGIzMDRhMWZl
10
- Yzg0OGM2MTAyMDcxMTgzYjhjYTAxMGM0MDU0MWJkYmUwNDRhNWVlMjhmNjU0
11
- NGJkOGVhZGRiMjgxYmM3ZTIyMmRiNTdjNmZmMjRjYmZjMDJkOGU=
12
- data.tar.gz: !binary |-
13
- NDhjYTRmYTBjMmVlZDhiYTc2OGUzMGI4NGMzOGU1ODMxZjMxZmIzYzU2YTM0
14
- ZjQ0ODJlNzYyMzEzZDY0NzY4YmJkM2EwNWZiY2E3NWU1NzkyNzk0MmUyNTg4
15
- YjUzYTMyNzU3NWI4ODc5NWVkYzVhMmI0MTQzZjA1MTI0NWI0YTk=
6
+ metadata.gz: bc6d901ec87dc0df4882265c7d5f95210f5bcf2777dda10870366547aabe9b42a90adc8007fa872b925f35ac1b192237a1c2eaebe8464f3b4083cad8405e90a5
7
+ data.tar.gz: 2b117de96b7c80c06db4e7173d3954265531ab3f70df26512118854ea6025068e3d0852cc615f1c79a5da84bd5609a4c9ba95824f5292fef9ca41cfd393db06d
@@ -1,14 +1,20 @@
1
1
  * Adel Qalieh <aqalieh95@gmail.com>
2
+ * Alex Sergeyev <alex.sergeyev@gmail.com>
3
+ * Arnold <arnoldcano@yahoo.com>
2
4
  * Brandur <brandur@heroku.com>
3
5
  * Brandur <brandur@mutelight.org>
4
6
  * Chris Continanza <christopher.continanza@gmail.com>
7
+ * Corey Powell <mistdragon100@gmail.com>
5
8
  * Dan Peterson <dpiddy@gmail.com>
6
9
  * Dane Harrigan <dane.harrigan@gmail.com>
7
10
  * Eric J. Holmes <eric@ejholmes.net>
8
11
  * Ernesto Jiménez <me@ernesto-jimenez.com>
12
+ * Jason Rudolph <github@jasonrudolph.com>
13
+ * Juan Pablo Buritica <juanpablo@buritica.org>
9
14
  * Justin Halsall <justin@juice10.com>
10
15
  * Kousuke Ebihara <Kosuke_Ebihara@voyagegroup.com>
11
16
  * Kousuke Ebihara <kousuke@co3k.org>
17
+ * Lucas Carvalho <lucas.carvalho@corp.globo.com>
12
18
  * Mark McGranaghan <mmcgrana@gmail.com>
13
19
  * Martin Seeler <developer@chasmo.de>
14
20
  * Matthew Conway <himself@mattonrails.com>
@@ -16,4 +22,6 @@
16
22
  * Scott Clasen <scott@heroku.com>
17
23
  * Timothée Peignier <timothee.peignier@tryphon.org>
18
24
  * Wesley Beary <geemus+github@gmail.com>
25
+ * Wesley Beary <geemus@gmail.com>
26
+ * Zack Shapiro <zack.shapiro@kontagent.com>
19
27
  * geemus <geemus@gmail.com>
@@ -3,21 +3,21 @@ PATH
3
3
  specs:
4
4
  prmd (0.6.2)
5
5
  erubis (~> 2.7)
6
- json_schema (~> 0.1)
6
+ json_schema (~> 0.3, >= 0.3.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
11
  erubis (2.7.0)
12
- json_schema (0.1.4)
13
- minitest (5.3.2)
14
- rake (10.2.2)
12
+ json_schema (0.3.1)
13
+ minitest (5.4.2)
14
+ rake (10.3.2)
15
15
 
16
16
  PLATFORMS
17
17
  ruby
18
18
 
19
19
  DEPENDENCIES
20
20
  bundler (~> 1.3)
21
- minitest (~> 5.3)
21
+ minitest (~> 5.4)
22
22
  prmd!
23
- rake (~> 10.2)
23
+ rake (~> 10.3)
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # Prmd
1
+ # Prmd [![Travis Status](https://travis-ci.org/interagent/prmd.svg)](https://travis-ci.org/interagent/prmd)
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/prmd.svg)](http://badge.fury.io/rb/prmd)
2
4
 
3
5
  JSON Schema tooling: scaffold, verify, and generate documentation
4
6
  from JSON Schema documents.
@@ -21,7 +23,7 @@ described in [/docs/schemata.md](/docs/schemata.md).
21
23
 
22
24
  Install the command-line tool with:
23
25
 
24
- ```console
26
+ ```bash
25
27
  $ gem install prmd
26
28
  ```
27
29
 
@@ -32,7 +34,7 @@ to the application's Gemfile:
32
34
  gem 'prmd'
33
35
  ```
34
36
 
35
- ```console
37
+ ```bash
36
38
  $ bundle install
37
39
  ```
38
40
 
@@ -48,7 +50,7 @@ Prmd provides four main commands:
48
50
 
49
51
  Here's an example of using these commands in a typical workflow:
50
52
 
51
- ```console
53
+ ```bash
52
54
  # Fill out the resource schemata
53
55
  $ mkdir -p schemata
54
56
  $ prmd init app > schemata/app.json
@@ -80,25 +82,72 @@ $ prmd doc schema.json > schema.md
80
82
 
81
83
  # Render from schema
82
84
 
83
- ```console
85
+ ```bash
84
86
  $ prmd render --template schemata.erb schema.json > schema.md
85
87
  ```
86
88
 
87
89
  Typically you'll want to prepend header and overview information to
88
90
  your API documentation. You can do this with the `--prepend` flag:
89
91
 
90
- ```console
91
- $ prmd doc schema.json --prepend overview.md > schema.md
92
+ ```bash
93
+ $ prmd doc --prepend overview.md schema.json > schema.md
92
94
  ```
93
95
 
94
96
  You can also chain commands together as needed, e.g.:
95
97
 
96
- ```console
98
+ ```bash
97
99
  $ prmd combine --meta meta.json schemata/ | prmd verify | prmd doc --prepend overview.md > schema.md
98
100
  ```
99
101
 
100
102
  See `prmd <command> --help` for additional usage details.
101
103
 
104
+ ## Documentation rendering settings
105
+
106
+ Out of the box you can supply a settings file (in either `JSON` or `YAML`) that will tweak the layout of your documentation.
107
+
108
+ ```bash
109
+ $ prmd doc --settings config.json schema.json > schema.md
110
+ ```
111
+
112
+ Available options (and their defaults)
113
+ ```json
114
+ {
115
+ "doc": {
116
+ "url_style": "default", // can also be "json"
117
+ "disable_title_and_description": false // remove the title and the description, useful when using your own custom header
118
+ }
119
+ }
120
+ ```
121
+
122
+ ## Use as rake task
123
+
124
+ In addition, prmd can be used via rake tasks
125
+
126
+ ```ruby
127
+ # Rakefile
128
+ require 'prmd/rake_tasks/combine'
129
+ require 'prmd/rake_tasks/verify'
130
+ require 'prmd/rake_tasks/doc'
131
+
132
+ namespace :schema do
133
+ Prmd::RakeTasks::Combine.new do |t|
134
+ t.options[:meta] = 'schema/meta.json'
135
+ t.paths << 'schema/schemata/api'
136
+ t.output_file = 'schema/api.json'
137
+ end
138
+
139
+ Prmd::RakeTasks::Verify.new do |t|
140
+ t.files << 'schema/api.json'
141
+ end
142
+
143
+ Prmd::RakeTasks::Doc.new do |t|
144
+ t.files = { 'schema/api.json' => 'schema/api.md' }
145
+ end
146
+ end
147
+
148
+ task default: ['schema:combine', 'schema:verify', 'schema:doc']
149
+ ```
150
+
102
151
  ## File Layout
103
152
 
104
153
  We suggest the following file layout for JSON schema related files:
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new do |t|
5
- t.pattern = "test/**/*_test.rb"
5
+ t.pattern = 'test/**/*_test.rb'
6
6
  end
7
7
 
8
- task :default => :test
8
+ task default: :test
data/bin/prmd CHANGED
@@ -1,120 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'optparse'
3
- require(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'prmd')))
3
+ require 'prmd'
4
+ require 'prmd/cli'
4
5
 
5
- options = {}
6
-
7
- commands = {
8
- combine: OptionParser.new do |opts|
9
- opts.banner = "prmd combine [options] <file or directory>"
10
- opts.on("-m", "--meta meta.json", "Set defaults for schemata") do |m|
11
- options[:meta] = m
12
- end
13
- end,
14
- doc: OptionParser.new do |opts|
15
- opts.banner = "prmd doc [options] <combined schema>"
16
- opts.on("-p", "--prepend header,overview", Array, "Prepend files to output") do |p|
17
- options[:prepend] = p
18
- end
19
- opts.on("-u", "--url-style json", String, "URL style to output (default/json)") do |s|
20
- options[:style] = s
21
- end
22
- opts.on("-c", "--content-type application/json", String, "Content-Type header") do |c|
23
- options[:content_type] = c
24
- end
25
- end,
26
- init: OptionParser.new do |opts|
27
- opts.banner = "prmd init [options] <resource name>"
28
- opts.on("-y", "--yaml", "Generate YAML") do |y|
29
- options[:yaml] = y
30
- end
31
- end,
32
- render: OptionParser.new do |opts|
33
- opts.banner = "prmd render [options] <combined schema>"
34
- opts.on("-p", "--prepend header,overview", Array, "Prepend files to output") do |p|
35
- options[:prepend] = p
36
- end
37
- opts.on("-t", "--template templates", String, "Use alternate template") do |t|
38
- options[:template] = t
39
- end
40
- end,
41
- verify: OptionParser.new do |opts|
42
- opts.banner = "prmd verify [options] <combined schema>"
43
- end
44
- }
45
-
46
- help_text = commands.values.map do |command|
47
- " #{command.banner}"
48
- end.join("\n")
49
-
50
- global = OptionParser.new do |opts|
51
- opts.banner = "Usage: prmd [options] [command [options]]"
52
- opts.separator "\nAvailable options:"
53
- opts.on("--version", "Return version") do |opts|
54
- puts "prmd #{Prmd::VERSION}"
55
- exit(0)
56
- end
57
- opts.separator "\nAvailable commands:"
58
- opts.separator help_text
59
- end
60
-
61
- if ARGV.empty?
62
- puts global
63
- exit(1)
64
- end
65
- global.order!
66
-
67
- command = ARGV.shift.to_sym
68
- option = commands[command]
69
- if option.nil?
70
- puts global
71
- exit(1)
72
- end
73
-
74
- if ARGV.empty? && $stdin.tty?
75
- puts option
76
- exit(1)
77
- end
78
- option.order!
79
-
80
- case command
81
- when :combine
82
- puts Prmd.combine(ARGV[0], options).to_s
83
- when :doc
84
- data = unless $stdin.tty?
85
- $stdin.read
86
- else
87
- File.read(ARGV[0])
88
- end
89
- schema = Prmd::Schema.new(JSON.parse(data))
90
-
91
- options[:template] = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'prmd', 'templates'))
92
-
93
- puts Prmd.render(schema, options)
94
- when :init
95
- puts Prmd.init(ARGV[0], options)
96
- when :render
97
- data = unless $stdin.tty?
98
- $stdin.read
99
- else
100
- File.read(ARGV[0])
101
- end
102
- schema = Prmd::Schema.new(JSON.parse(data))
103
- puts Prmd.render(schema, options)
104
- when :verify
105
- data, errors = '', []
106
- unless $stdin.tty?
107
- data = $stdin.read
108
- errors.concat(Prmd.verify(JSON.parse(data)))
109
- else
110
- data = JSON.parse(File.read(ARGV[0]))
111
- Prmd.verify(data).each do |error|
112
- errors << "#{ARGV[0]}: #{error}"
113
- end
114
- end
115
- errors.each do |error|
116
- $stderr.puts(error)
117
- end
118
- exit(1) unless errors.empty?
119
- puts(data) unless $stdout.tty?
120
- end
6
+ Prmd::CLI.run(ARGV.dup, bin: File.basename(__FILE__))
@@ -18,7 +18,7 @@ We have opted to split apart the schema into individual resource schema and a ro
18
18
  Each schema MUST include some meta-data, which we cluster at the top of the file, including:
19
19
 
20
20
  * `description` - a description of the resource described by the schema
21
- * `id` - an id for this schema, it MUST be in the form `"schema/#{lower_case_singular_resource}"`
21
+ * `id` - an id for this schema, it MUST be in the form `"schemata/#{lower_case_singular_resource}"`
22
22
  * `$schema` - defines what meta-schema is in use, it MUST be `http://json-schema.org/draft-04/hyper-schema`
23
23
  * `title` - title for this resource, it MUST be in the form `"#{title_case_API_name} - #{title_case_plural_resource}"`
24
24
  * `type` - the type(s) of this schema, it MUST be `["object"]`
@@ -74,7 +74,7 @@ The links array MUST include an object defining each action available. Each acti
74
74
 
75
75
  * `description` - a description of the action to perform
76
76
  * `href` - the path associated with this action, use [URI templates](http://tools.ietf.org/html/rfc6570) as needed, CGI escaping any JSON pointer values used for identity
77
- * `method` - the http method to be used with this actio
77
+ * `method` - the http method to be used with this action
78
78
  * `rel` - describes relation of link to resource, SHOULD be one of `["create", "destroy", "self", "instances", "update"]`
79
79
  * `title` - title for the link
80
80
 
@@ -94,8 +94,8 @@ If this field is not present, all attributes in this link are considered as opti
94
94
  "rel": "create",
95
95
  "schema": {
96
96
  "properties": {
97
- "owner": { "$ref": "/schema/user#/definitions/identity" },
98
- "url": { "$ref": "/schema/resource/definitions/url" }
97
+ "owner": { "$ref": "/schemata/user#/definitions/identity" },
98
+ "url": { "$ref": "/schemata/resource/definitions/url" }
99
99
  },
100
100
  "required": [ "owner", "url" ]
101
101
  },
@@ -103,14 +103,14 @@ If this field is not present, all attributes in this link are considered as opti
103
103
  },
104
104
  {
105
105
  "description": "Delete an existing resource.",
106
- "href": "/resources/{(%2Fschema%2Fresources%23%2Fdefinitions%2Fidentity)}",
106
+ "href": "/resources/{(%2Fschemata%2Fresources%23%2Fdefinitions%2Fidentity)}",
107
107
  "method": "DELETE",
108
108
  "rel": "destroy",
109
109
  "title": "Delete"
110
110
  },
111
111
  {
112
112
  "description": "Info for existing resource.",
113
- "href": "/resources/{(%2Fschema%2Fresources%23%2Fdefinitions%2Fidentity)}",
113
+ "href": "/resources/{(%2Fschemata%2Fresources%23%2Fdefinitions%2Fidentity)}",
114
114
  "method": "GET",
115
115
  "rel": "self",
116
116
  "title": "Info"
@@ -124,12 +124,12 @@ If this field is not present, all attributes in this link are considered as opti
124
124
  },
125
125
  {
126
126
  "description": "Update an existing resource.",
127
- "href": "/resources/{(%2Fschema%2Fresource%23%2Fdefinitions%2Fidentity)}",
127
+ "href": "/resources/{(%2Fschemata%2Fresource%23%2Fdefinitions%2Fidentity)}",
128
128
  "method": "PATCH",
129
129
  "rel": "update",
130
130
  "schema": {
131
131
  "properties": {
132
- "url": { "$ref": "/schema/resource/definitions/url" }
132
+ "url": { "$ref": "/schemata/resource/definitions/url" }
133
133
  }
134
134
  },
135
135
  "title": "Update"
@@ -146,15 +146,15 @@ The properties object MUST contain all the serialized attributes for the object.
146
146
  ```javascript
147
147
  {
148
148
  "properties": {
149
- "id": { "$ref": "/schema/resource#/definitions/id" },
149
+ "id": { "$ref": "/schemata/resource#/definitions/id" },
150
150
  "owner": {
151
151
  "description": "unique identifier of the user who owns this resource",
152
152
  "properties": {
153
- "id": { "$ref": "/schema/user#/definitions/id" }
153
+ "id": { "$ref": "/schemata/user#/definitions/id" }
154
154
  },
155
155
  "type": ["object"]
156
156
  },
157
- "url": { "$ref": "/schema/resource#/definitions/url" }
157
+ "url": { "$ref": "/schemata/resource#/definitions/url" }
158
158
  }
159
159
  }
160
160
  ```
@@ -1,18 +1,7 @@
1
- require "cgi"
2
- require "erubis"
3
- require "json"
4
- require "yaml"
5
-
6
- dir = File.dirname(__FILE__)
7
- require File.join(dir, 'prmd', 'commands', 'combine')
8
- require File.join(dir, 'prmd', 'commands', 'expand')
9
- require File.join(dir, 'prmd', 'commands', 'init')
10
- require File.join(dir, 'prmd', 'commands', 'render')
11
- require File.join(dir, 'prmd', 'commands', 'verify')
12
- require File.join(dir, 'prmd', 'schema')
13
- require File.join(dir, 'prmd', 'version')
14
- require File.join(dir, 'prmd', 'template')
15
- require File.join(dir, 'prmd', 'url_generator')
16
-
17
- module Prmd
18
- end
1
+ require 'prmd/version'
2
+ require 'prmd/load_schema_file'
3
+ require 'prmd/commands'
4
+ require 'prmd/schema'
5
+ require 'prmd/template'
6
+ require 'prmd/url_generator'
7
+ require 'prmd/hash_helpers'
@@ -0,0 +1,108 @@
1
+ require 'prmd/core_ext/optparse'
2
+ require 'prmd/cli/combine'
3
+ require 'prmd/cli/doc'
4
+ require 'prmd/cli/generate'
5
+ require 'prmd/cli/render'
6
+ require 'prmd/cli/verify'
7
+
8
+ # :nodoc:
9
+ module Prmd
10
+ # Main CLI module
11
+ module CLI
12
+ # @param [Hash<Symbol, Object>] props
13
+ # @return [Hash<Symbol, OptionParser>] all dem parsers
14
+ def self.make_command_parsers(props = {})
15
+ {
16
+ combine: CLI::Combine.make_parser(props),
17
+ doc: CLI::Doc.make_parser(props),
18
+ init: CLI::Generate.make_parser(props),
19
+ render: CLI::Render.make_parser(props),
20
+ verify: CLI::Verify.make_parser(props)
21
+ }
22
+ end
23
+
24
+ # List of all available commands
25
+ #
26
+ # @return [Array] available commands
27
+ def self.commands
28
+ @commands ||= make_command_parsers.keys
29
+ end
30
+
31
+ # Creates the CLI main parser
32
+ #
33
+ # @param [Hash<Symbol, Object>] options
34
+ # @param [Hash<Symbol, Object>] props
35
+ def self.make_parser(options, props = {})
36
+ binname = props.fetch(:bin, 'prmd')
37
+
38
+ # This is only used to attain the help commands
39
+ commands = make_command_parsers(props)
40
+ help_text = commands.values.map do |command|
41
+ " #{command.banner}"
42
+ end.join("\n")
43
+
44
+ global = OptionParser.new do |opts|
45
+ opts.banner = "Usage: #{binname} [options] [command [options]]"
46
+ opts.separator "\nAvailable options:"
47
+ opts.on('--version', 'Return version') do
48
+ puts "prmd #{Prmd::VERSION}"
49
+ exit(0)
50
+ end
51
+ opts.on('--noop', 'Commands will not execute') do |v|
52
+ options[:noop] = v
53
+ end
54
+ opts.separator "\nAvailable commands:"
55
+ opts.separator help_text
56
+ end
57
+
58
+ global
59
+ end
60
+
61
+ # Parse top level CLI options from argv
62
+ #
63
+ # @param [Array<String>] argv
64
+ # @param [Hash<Symbol, Object>] opts
65
+ # @return [Hash<Symbol, Object>] parsed options
66
+ def self.parse_options(argv, opts = {})
67
+ options = {}
68
+ parser = make_parser(options, opts)
69
+ abort parser if argv.empty?
70
+ com_argv = parser.order(argv)
71
+ abort parser if com_argv.empty?
72
+ command = com_argv.shift.to_sym
73
+ abort parser unless commands.include?(command)
74
+ options[:argv] = com_argv
75
+ options[:command] = command
76
+ options
77
+ end
78
+
79
+ # Execute the Prmd CLI, or its subcommands
80
+ #
81
+ # @param [Array<String>] uargv
82
+ # @param [Hash<Symbol, Object>] opts
83
+ # @return [void]
84
+ def self.run(uargv, opts = {})
85
+ options = parse_options(uargv, opts)
86
+ argv = options.delete(:argv)
87
+ command = options.delete(:command)
88
+
89
+ case command
90
+ when :combine
91
+ CLI::Combine.run(argv, options)
92
+ when :doc
93
+ CLI::Doc.run(argv, options)
94
+ when :init
95
+ CLI::Generate.run(argv, options)
96
+ when :render
97
+ CLI::Render.run(argv, options)
98
+ when :verify
99
+ CLI::Verify.run(argv, options)
100
+ end
101
+ end
102
+
103
+ class << self
104
+ private :make_command_parsers
105
+ private :commands
106
+ end
107
+ end
108
+ end