bump-cli 0.3.2 → 0.6.0

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
  SHA256:
3
- metadata.gz: aa0bd892b8317be2e6bce1fe83c0d747c6ae989fe3e02c69730479e9c595ba9b
4
- data.tar.gz: '0924e8faa5b4221383c8c3ea0dc80774790666a5568c7180e51ad655a5c9cfcd'
3
+ metadata.gz: a76424c2ad6eed8a8b65caa28e57e26c7efb892b8909a9e6aed60871b9964105
4
+ data.tar.gz: 4f597a0961e36cfb2108409198a11abae798333b49fadf298fbd0f7b332c529a
5
5
  SHA512:
6
- metadata.gz: de9f6fe376a5ebba4144c595004d5b990a10be581a58ca6af116d80ab9cb957cdbe9e03a549ea7ba1b2597f194e38bc5d9b001232beb0675cf152a01ca599021
7
- data.tar.gz: 7fa8848a39ceabc042183cb1d5fe5151f6956f001149a01db4751d02c05793e3a6306695b432fda851dbb88741a20a770bd78ae47fd891765f0ddb395c6099bd
6
+ metadata.gz: bda499aed9b3edfb4600ccd8ede77a65dd6bd98403937f29b714c557e8fb5457f8258d49d55ab5968499c5e10ff67b6a0cd446d3304a5b0ea69afeab20f0e47d
7
+ data.tar.gz: 2fa948728d09d134b552954d12d2f64d3141bf5c0422ffdd95ec853afed861aed0440c4c6a3ff5378025f5788d1ceb535e04c37a12e8b4180441d35b850b499c
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  .byebug_history
2
+ .ruby-version
2
3
  /.bundle/
3
4
  /.yardoc
4
5
  /Gemfile.lock
data/README.md CHANGED
@@ -20,27 +20,40 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- By default, `bump-cli` considers files as `yaml` ones. If you work with JSON definitions, you need to specify the format for all the commands using `--format json`.
23
+ Bump tries to identify your file specification and format automatically. You can force it by using the `--specification` option. Here are the supported values:
24
24
 
25
- The doc `id` and `token` used below can be found in your documentation settings page on https://bump.sh. Note that you can replace the options by environments variables: `--id` can be replaced by `BUMP_ID`, and `--token` can by replaced by `BUMP_TOKEN`. This is useful to keep your private token secret.
25
+ * `openapi/v2/json`
26
+ * `openapi/v2/yaml`
27
+ * `openapi/v3/json`
28
+ * `openapi/v3/yaml`
29
+ * `asyncapi/v2/json`
30
+ * `asyncapi/v2/yaml`
31
+
32
+ `doc` and `token` options used below can be found in your documentation settings page on https://bump.sh. Note that you can replace the token option by an environment variable, to keep it secret: `--token` can by replaced by `BUMP_TOKEN`.
26
33
 
27
34
  ### Preview
28
35
 
29
36
  You can preview your documentation by calling the `preview` command. A temporary preview will be created, with a unique URL. This preview will be available for 30 minutes. You don't need any credentials to use this command.
30
37
 
31
- $ bundle exec bump preview path/to/your/openapi.yml
38
+ Preview a documentation:
39
+
40
+ $ bundle exec bump preview path/to/your/file.yml
32
41
 
33
42
  ### Validate
34
43
 
35
- Validate your file against the OpenApi specification.
44
+ Validate your file against its specification:
36
45
 
37
- $ bundle exec bump validate path/to/your/openapi.yml --id DOC_ID --token DOC_TOKEN
46
+ $ bundle exec bump validate path/to/your/file.yml --doc DOC_ID_OR_SLUG --token DOC_TOKEN
38
47
 
39
48
  ### Deploy
40
49
 
41
- Deploy the file as the current version of the documentation.
50
+ Deploy the file as the current version of the documentation:
51
+
52
+ $ bundle exec bump deploy path/to/your/file.yml --doc DOC_ID_OR_SLUG --token DOC_TOKEN
53
+
54
+ Automatically create a documentation inside a hub and deploy it:
42
55
 
43
- $ bundle exec bump deploy path/to/your/openapi.yml --id DOC_ID --token DOC_TOKEN
56
+ $ bundle exec bump deploy path/to/your/file.yml --auto-create --doc DOC_SLUG --hub HUB_ID_OR_SLUG --token HUB_TOKEN
44
57
 
45
58
  ## Development
46
59
 
@@ -26,13 +26,13 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.required_ruby_version = '>= 2.3'
28
28
 
29
- spec.add_dependency "hanami-cli", '~> 0'
30
- spec.add_dependency "http", '~> 3'
29
+ spec.add_dependency "dry-cli", '~> 0'
30
+ spec.add_dependency "http", '>= 3'
31
31
 
32
- spec.add_development_dependency "bundler", "~> 1.15"
33
- spec.add_development_dependency "byebug", "~> 9"
32
+ spec.add_development_dependency "bundler", ">= 1", "< 3"
33
+ spec.add_development_dependency "byebug", "~> 11"
34
34
  spec.add_development_dependency "climate_control", '~> 0'
35
- spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "rake", "~> 13"
36
36
  spec.add_development_dependency "rspec", "~> 3"
37
37
  spec.add_development_dependency "webmock", "~> 3"
38
38
  end
@@ -1,5 +1,5 @@
1
1
  require "bump/cli/version"
2
- require "hanami/cli"
2
+ require "dry/cli"
3
3
  require "http"
4
4
 
5
5
  module Bump
@@ -9,11 +9,11 @@ module Bump
9
9
  API_URL = ROOT_URL + API_PATH
10
10
 
11
11
  def call(*args)
12
- Hanami::CLI.new(Commands).call(*args)
12
+ Dry::CLI.new(Commands).call(*args)
13
13
  end
14
14
 
15
15
  module Commands
16
- extend Hanami::CLI::Registry
16
+ extend Dry::CLI::Registry
17
17
  end
18
18
  end
19
19
  end
@@ -1,9 +1,10 @@
1
- require 'open-uri'
1
+ require 'bump/cli/definition'
2
+ require 'bump/cli/uuid'
2
3
 
3
4
  module Bump
4
5
  class CLI
5
6
  module Commands
6
- class Base < Hanami::CLI::Command
7
+ class Base < Dry::CLI::Command
7
8
  USER_AGENT = "bump-cli/#{VERSION}".freeze
8
9
 
9
10
  private
@@ -14,11 +15,64 @@ module Bump
14
15
  .post(url, body: body)
15
16
  end
16
17
 
17
- def body(file, specification)
18
- {
19
- definition: open(file).read,
20
- specification: specification
21
- }
18
+ def body(file, **options)
19
+ deprecation_warning(options)
20
+
21
+ compact(
22
+ {
23
+ definition: prepare_file(file, options),
24
+ specification: options[:specification],
25
+ validation: options[:validation],
26
+ auto_create_documentation: options[:'auto-create']
27
+ }.merge(documentation_or_hub(options))
28
+ )
29
+ end
30
+
31
+ def prepare_file(file, options)
32
+ Definition.new(file, import_external_references: options[:'import-external-references']).prepare
33
+ end
34
+
35
+ def deprecation_warning(options)
36
+ if present?(options[:id])
37
+ puts "[DEPRECATION WARNING] --id option is deprecated. Please use --doc instead."
38
+ end
39
+ end
40
+
41
+ def present?(string)
42
+ !string.nil? && string != ''
43
+ end
44
+
45
+ def compact(hash)
46
+ hash.delete_if { |key, value| value.nil? }
47
+ end
48
+
49
+ def documentation_or_hub(options)
50
+ result = {}
51
+
52
+ result[:documentation_id] = options[:id]
53
+ result[:documentation_id] = options[:doc] if documentation_uuid?(options)
54
+ result[:documentation_slug] = options[:doc] if documentation_slug?(options)
55
+ result[:documentation_name] = options[:'doc-name']
56
+ result[:hub_id] = options[:hub] if hub_uuid?(options)
57
+ result[:hub_slug] = options[:hub] if hub_slug?(options)
58
+
59
+ compact(result)
60
+ end
61
+
62
+ def documentation_uuid?(options)
63
+ Bump::CLI::UUID.valid?(options[:doc])
64
+ end
65
+
66
+ def documentation_slug?(options)
67
+ !options[:doc].nil? && !documentation_uuid?(options)
68
+ end
69
+
70
+ def hub_uuid?(options)
71
+ Bump::CLI::UUID.valid?(options[:hub])
72
+ end
73
+
74
+ def hub_slug?(options)
75
+ !options[:hub].nil? && !hub_uuid?(options)
22
76
  end
23
77
 
24
78
  def with_errors_rescued
@@ -5,17 +5,23 @@ module Bump
5
5
  module Commands
6
6
  class Deploy < Base
7
7
  desc "Create a new version"
8
- argument :file, required: true, desc: "Path or URL to your API documentation file. Only OpenApi 2.0 (Swagger) specification is currently supported."
9
- option :id, default: ENV.fetch("BUMP_ID", ""), desc: "Documentation public id"
10
- option :token, default: ENV.fetch("BUMP_TOKEN", ""), desc: "Documentation private token"
8
+ argument :file, required: true, desc: "Path or URL to your API documentation file. OpenAPI (2.0 to 3.0.2) and AsyncAPI (2.0) specifications are currently supported."
9
+ option :id, default: ENV.fetch("BUMP_ID", ""), desc: "[DEPRECATED] Documentation id. Use `documentation` option instead"
10
+ option :doc, default: ENV.fetch("BUMP_ID", ""), desc: "Documentation id or slug"
11
+ option :'doc-name', desc: "Documentation name. Used with --auto-create flag."
12
+ option :hub, default: ENV.fetch("BUMP_HUB_ID", ""), desc: "Hub id or slug"
13
+ option :token, default: ENV.fetch("BUMP_TOKEN", ""), desc: "Documentation or Hub token"
11
14
  option :specification, desc: "Specification of the definition"
15
+ option :validation, desc: "Validation mode", values: %w(basic strict), default: 'basic'
16
+ option :'auto-create', type: :boolean, default: false, desc: 'Automatically create the documentation if needed (only available with a hub and when specifying a slug for documentation)'
17
+ option :'import-external-references', type: :boolean, default: false, desc: 'Import external $refs (URI or file system) into the specification before sending it to Bump servers'
12
18
 
13
- def call(file:, id:, token:, specification: nil)
19
+ def call(file:, **options)
14
20
  with_errors_rescued do
15
21
  response = post(
16
- url: API_URL + "/docs/#{id}/versions",
17
- body: body(file, specification).to_json,
18
- token: token
22
+ url: API_URL + "/versions",
23
+ body: body(file, options).to_json,
24
+ token: options[:token]
19
25
  )
20
26
 
21
27
  if response.code == 201
@@ -3,14 +3,16 @@ module Bump
3
3
  module Commands
4
4
  class Preview < Base
5
5
  desc "Create a documentation preview for the given file"
6
- argument :file, required: true, desc: "Path or URL to your API documentation file. Only OpenApi 2.0 (Swagger) specification is currently supported."
6
+ argument :file, required: true, desc: "Path or URL to your API documentation file. OpenAPI (2.0 to 3.0.2) and AsyncAPI (2.0) specifications are currently supported."
7
7
  option :specification, desc: "Specification of the definition"
8
+ option :validation, desc: "Validation mode", values: %w(basic strict), default: 'basic'
9
+ option :'import-external-references', type: :boolean, default: false, desc: 'Import external $refs (URI or file system) into the specification before sending it to Bump servers'
8
10
 
9
- def call(file:, specification: nil)
11
+ def call(file:, **options)
10
12
  with_errors_rescued do
11
13
  response = post(
12
14
  url: API_URL + "/previews",
13
- body: body(file, specification).to_json
15
+ body: body(file, options).to_json
14
16
  )
15
17
 
16
18
  if response.code == 201
@@ -5,17 +5,23 @@ module Bump
5
5
  module Commands
6
6
  class Validate < Base
7
7
  desc "Validate a given file against its schema definition"
8
- argument :file, required: true, desc: "Path or URL to your API documentation file. Only OpenApi 2.0 (Swagger) specification is currently supported."
9
- option :id, default: ENV.fetch("BUMP_ID", ""), desc: "Documentation public id"
10
- option :token, default: ENV.fetch("BUMP_TOKEN", ""), desc: "Documentation private token"
8
+ argument :file, required: true, desc: "Path or URL to your API documentation file. OpenAPI (2.0 to 3.0.2) and AsyncAPI (2.0) specifications are currently supported."
9
+ option :id, default: ENV.fetch("BUMP_ID", ""), desc: "[DEPRECATED] Documentation id. Use `documentation` option instead"
10
+ option :doc, default: ENV.fetch("BUMP_ID", ""), desc: "Documentation public id or slug"
11
+ option :'doc-name', desc: "Documentation name. Used with --auto-create flag."
12
+ option :hub, desc: "Hub id or slug"
13
+ option :token, default: ENV.fetch("BUMP_TOKEN", ""), desc: "Documentation or Hub token"
11
14
  option :specification, desc: "Specification of the definition"
15
+ option :validation, desc: "Validation mode", values: %w(basic strict), default: 'basic'
16
+ option :'auto-create', type: :boolean, default: false, desc: 'Automatically create the documentation if needed (only available with a hub and when specifying a slug for documentation)'
17
+ option :'import-external-references', type: :boolean, default: false, desc: 'Import external $refs (URI or file system) into the specification before sending it to Bump servers'
12
18
 
13
- def call(file:, id:, token:, specification: nil)
19
+ def call(file:, **options)
14
20
  with_errors_rescued do
15
21
  response = post(
16
- url: API_URL + "/docs/#{id}/validations",
17
- body: body(file, specification).to_json,
18
- token: token
22
+ url: API_URL + "/validations",
23
+ body: body(file, options).to_json,
24
+ token: options[:token]
19
25
  )
20
26
 
21
27
  if response.code == 200
@@ -0,0 +1,43 @@
1
+ require 'open-uri'
2
+ require 'bump/cli/parser'
3
+ require 'bump/cli/references'
4
+
5
+ module Bump
6
+ class CLI
7
+ class Definition
8
+ def initialize(path, import_external_references: false)
9
+ @path = path
10
+ @import_external_references = import_external_references
11
+ end
12
+
13
+ def prepare
14
+ if !import_external_references
15
+ read_file
16
+ else
17
+ parse_file_and_import_external_references
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :path, :import_external_references
24
+
25
+ def read_file
26
+ open(path).read
27
+ end
28
+
29
+ def parse_file_and_import_external_references
30
+ original_format, definition = parser.load(read_file)
31
+
32
+ references = References.new(definition, base_path: path)
33
+ references.import!
34
+
35
+ parser.dump(references.definition, original_format)
36
+ end
37
+
38
+ def parser
39
+ @parser ||= Parser.new
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,24 @@
1
+ require 'json'
2
+ require 'yaml'
3
+
4
+ module Bump
5
+ class CLI
6
+ class Parser
7
+ def load(content)
8
+ [:json, ::JSON.parse(content)]
9
+ rescue ::JSON::ParserError => e
10
+ [:yaml, ::YAML.safe_load(content, [Date, Time])]
11
+ rescue ::Psych::SyntaxError
12
+ raise 'Invalid format: definition file should be valid YAML or JSON'
13
+ end
14
+
15
+ def dump(definition, format)
16
+ if format == :yaml
17
+ ::YAML.dump(definition)
18
+ else
19
+ ::JSON.dump(definition)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,88 @@
1
+ require 'open-uri'
2
+ require 'pathname'
3
+
4
+ module Bump
5
+ class CLI
6
+ class References
7
+ attr_reader :definition
8
+
9
+ def initialize(definition, base_path: '')
10
+ @definition = definition
11
+ @base_path = cleanup(base_path)
12
+ @processed = false
13
+ @external_references = {}
14
+ end
15
+
16
+ def import!
17
+ if !processed
18
+ @definition = traverse_and_replace_external_references(definition)
19
+ import_references
20
+ @processed = true
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :base_path, :processed, :external_references
27
+
28
+ def traverse_and_replace_external_references(current, parent = nil)
29
+ current.each do |key, value|
30
+ if key == '$ref'
31
+ current[key] = replace_external_reference(value)
32
+ elsif value.is_a?(Hash)
33
+ traverse_and_replace_external_references(value, key)
34
+ end
35
+ end
36
+ end
37
+
38
+ def replace_external_reference(reference)
39
+ if external?(reference)
40
+ if external_references[reference].nil?
41
+ @external_references[reference] = "#{external_references.count + 1}"
42
+ end
43
+
44
+ subpath = reference[/#(.*)$/, 1]
45
+ "#/components/x-imported/#{external_references[reference]}#{ '/' + subpath if !subpath.nil? }"
46
+ else
47
+ reference
48
+ end
49
+ end
50
+
51
+ def import_references
52
+ if external_references.count > 0
53
+ @definition['components'] = {} if @definition['components'].nil?
54
+ @definition['components']['x-imported'] = {} if @definition['components']['x-imported'].nil?
55
+
56
+ external_references.each do |key, value|
57
+ _, @definition['components']['x-imported'][value.to_s] = Parser.new.load(open(prepare_path(key)).read)
58
+ end
59
+ end
60
+ end
61
+
62
+ def prepare_path(key)
63
+ key = key.sub(/#.*/, '')
64
+ if url?(key) || absolute_path?(key)
65
+ key
66
+ else
67
+ base_path + key
68
+ end
69
+ end
70
+
71
+ def external?(reference)
72
+ !reference.start_with?('#')
73
+ end
74
+
75
+ def url?(path)
76
+ path.start_with?('http')
77
+ end
78
+
79
+ def absolute_path?(path)
80
+ path.start_with?('/')
81
+ end
82
+
83
+ def cleanup(path)
84
+ Pathname.new(path).dirname.to_s + Pathname::SEPARATOR_LIST
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,11 @@
1
+ module Bump
2
+ class CLI
3
+ class UUID
4
+ REGEXP = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
5
+
6
+ def self.valid?(string)
7
+ string.to_s =~ REGEXP
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,5 +1,5 @@
1
1
  module Bump
2
2
  class CLI
3
- VERSION = "0.3.2"
3
+ VERSION = "0.6.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bump-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mehdi Lahmam
@@ -9,10 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-01-17 00:00:00.000000000 Z
12
+ date: 2020-06-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: hanami-cli
15
+ name: dry-cli
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - "~>"
@@ -29,44 +29,50 @@ dependencies:
29
29
  name: http
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '3'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '3'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: bundler
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - "~>"
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '1'
49
+ - - "<"
47
50
  - !ruby/object:Gem::Version
48
- version: '1.15'
51
+ version: '3'
49
52
  type: :development
50
53
  prerelease: false
51
54
  version_requirements: !ruby/object:Gem::Requirement
52
55
  requirements:
53
- - - "~>"
56
+ - - ">="
54
57
  - !ruby/object:Gem::Version
55
- version: '1.15'
58
+ version: '1'
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '3'
56
62
  - !ruby/object:Gem::Dependency
57
63
  name: byebug
58
64
  requirement: !ruby/object:Gem::Requirement
59
65
  requirements:
60
66
  - - "~>"
61
67
  - !ruby/object:Gem::Version
62
- version: '9'
68
+ version: '11'
63
69
  type: :development
64
70
  prerelease: false
65
71
  version_requirements: !ruby/object:Gem::Requirement
66
72
  requirements:
67
73
  - - "~>"
68
74
  - !ruby/object:Gem::Version
69
- version: '9'
75
+ version: '11'
70
76
  - !ruby/object:Gem::Dependency
71
77
  name: climate_control
72
78
  requirement: !ruby/object:Gem::Requirement
@@ -87,14 +93,14 @@ dependencies:
87
93
  requirements:
88
94
  - - "~>"
89
95
  - !ruby/object:Gem::Version
90
- version: '10.0'
96
+ version: '13'
91
97
  type: :development
92
98
  prerelease: false
93
99
  version_requirements: !ruby/object:Gem::Requirement
94
100
  requirements:
95
101
  - - "~>"
96
102
  - !ruby/object:Gem::Version
97
- version: '10.0'
103
+ version: '13'
98
104
  - !ruby/object:Gem::Dependency
99
105
  name: rspec
100
106
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +155,10 @@ files:
149
155
  - lib/bump/cli/commands/deploy.rb
150
156
  - lib/bump/cli/commands/preview.rb
151
157
  - lib/bump/cli/commands/validate.rb
158
+ - lib/bump/cli/definition.rb
159
+ - lib/bump/cli/parser.rb
160
+ - lib/bump/cli/references.rb
161
+ - lib/bump/cli/uuid.rb
152
162
  - lib/bump/cli/version.rb
153
163
  homepage: https://bump.sh
154
164
  licenses: