xapixctl 1.0.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xapixctl
4
+ module PhoenixClient
5
+ class ResultHandler
6
+ def initialize(default_success_handler:, default_error_handler:)
7
+ @success_handler = default_success_handler
8
+ @error_handler = default_error_handler
9
+ @result_handler = nil
10
+ yield self if block_given?
11
+ end
12
+
13
+ def on_success(&block); @success_handler = block; self; end
14
+
15
+ def on_error(&block); @error_handler = block; self; end
16
+
17
+ def prepare_data(proc); @result_handler = proc; self; end
18
+
19
+ def formatter(proc); @formatter = proc; self; end
20
+
21
+ def run
22
+ res = yield
23
+ res = res.present? ? JSON.parse(res) : res
24
+ res = @result_handler ? @result_handler.call(res) : res
25
+ res = @formatter ? @formatter.call(res) : res
26
+ @success_handler.call(res)
27
+ rescue RestClient::Exception => err
28
+ response = JSON.parse(err.response) rescue {}
29
+ @error_handler.call(err, response)
30
+ rescue SocketError, Errno::ECONNREFUSED => err
31
+ @error_handler.call(err, nil)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xapixctl/base_cli'
4
+
5
+ module Xapixctl
6
+ class PreviewCli < BaseCli
7
+ option :format, aliases: "-f", default: 'text', enum: ['text', 'yaml', 'json'], desc: "Output format"
8
+ desc "pipeline ID", "Preview a pipeline"
9
+ long_desc <<-LONGDESC
10
+ `xapixctl preview pipeline` will return a preview of the given pipeline.
11
+
12
+ The preview function will not call any external data sources but calculate a preview based on the provided sample data.
13
+
14
+ To preview a pipeline attached to an endpoint, please use `xapixctl preview endpoint` to see the correct preview.
15
+
16
+ Examples:
17
+ \x5> $ xapixctl preview pipeline -o xapix -p some-project pipeline
18
+ \x5> $ xapixctl preview pipeline -p xapix/some-project pipeline
19
+ LONGDESC
20
+ def pipeline(pipeline)
21
+ puts prj_connection.pipeline_preview(pipeline, format: options[:format].to_sym)
22
+ end
23
+
24
+ option :format, aliases: "-f", default: 'text', enum: ['text', 'yaml', 'json'], desc: "Output format"
25
+ desc "endpoint ID", "Preview an endpoint"
26
+ long_desc <<-LONGDESC
27
+ `xapixctl preview endpoint` will return a preview of the given endpoint.
28
+
29
+ The preview function will not call any external data sources but calculate a preview based on the provided sample data.
30
+
31
+ Examples:
32
+ \x5> $ xapixctl preview endpoint -o xapix -p some-project endpoint
33
+ \x5> $ xapixctl preview endpoint -p xapix/some-project endpoint
34
+ LONGDESC
35
+ def endpoint(endpoint)
36
+ puts prj_connection.endpoint_preview(endpoint, format: options[:format].to_sym)
37
+ end
38
+
39
+ option :format, aliases: "-f", default: 'text', enum: ['text', 'yaml', 'json'], desc: "Output format"
40
+ desc "stream-processor ID", "Preview a stream processor"
41
+ long_desc <<-LONGDESC
42
+ `xapixctl preview stream-processor` will return a preview of the given stream processor.
43
+
44
+ The preview function will not call any external data sources but calculate a preview based on the provided sample data.
45
+
46
+ Examples:
47
+ \x5> $ xapixctl preview stream-processor -o xapix -p some-project processor
48
+ \x5> $ xapixctl preview stream-processor -p xapix/some-project processor
49
+ LONGDESC
50
+ def stream_processor(stream_processor)
51
+ puts prj_connection.stream_processor_preview(stream_processor, format: options[:format].to_sym)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xapixctl/base_cli'
4
+ require 'pathname'
5
+
6
+ module Xapixctl
7
+ class SyncCli < BaseCli
8
+ class_option :credentials, desc: "Whether to include Credential resources in sync", type: :boolean, default: true
9
+ class_option :exclude_types, desc: "Resource types to exclude from sync", type: :array
10
+
11
+ desc "to-dir DIRECTORY", "Syncs resources in project to directory"
12
+ long_desc <<-LONGDESC
13
+ `xapixctl sync to-dir DIRECTORY` will export all resources of a given project and remove any additional resources from the directory.
14
+
15
+ With --no-credentials you can exclude all credentials from getting exported.
16
+
17
+ With --exclude-types you can specify any resource types besides Project you'd like to exclude.
18
+
19
+ When excluding types, the excluded types will be recorded in the sync directory in a file called .excluded_types, so that any future syncs will exclude those types.
20
+
21
+ Examples:
22
+ \x5> $ xapixctl sync to-dir ./project_dir -p xapix/some-project
23
+ \x5> $ xapixctl sync to-dir ./project_dir -p xapix/some-project --no-credentials
24
+ \x5> $ xapixctl sync to-dir ./project_dir -p xapix/some-project --exclude-types=ApiPublishing ApiPublishingRole Credential
25
+ LONGDESC
26
+ def to_dir(dir)
27
+ sync_path = SyncPath.new(dir, prj_connection.resource_types_for_export, excluded_types)
28
+
29
+ res_details = prj_connection.project_resource
30
+ sync_path.write_file(generate_readme(res_details), 'README.md')
31
+ sync_path.write_resource_yaml(res_details, 'project')
32
+
33
+ sync_path.types_to_sync.each do |type|
34
+ res_path = sync_path.resource_path(type)
35
+ prj_connection.resource_ids(type).each do |res_id|
36
+ res_details = prj_connection.resource(type, res_id)
37
+ res_path.write_resource_yaml(res_details, res_id)
38
+ end
39
+ res_path.remove_outdated_resources
40
+ end
41
+ sync_path.update_excluded_types_file
42
+ end
43
+
44
+ desc "from-dir DIRECTORY", "Syncs resources in project from directory"
45
+ long_desc <<-LONGDESC
46
+ `xapixctl sync from-dir project dir` will import all resources into the given project from the directory and remove any additional resources which are not present in the directory.
47
+
48
+ With --no-credentials you can exclude all credentials from getting exported.
49
+
50
+ With --exclude-types you can specify any resource types besides Project you'd like to exclude.
51
+
52
+ Examples:
53
+ \x5> $ xapixctl sync from-dir ./project_dir -p xapix/some-project
54
+ \x5> $ xapixctl sync from-dir ./project_dir -p xapix/some-project --no-credentials
55
+ \x5> $ xapixctl sync from-dir ./project_dir -p xapix/some-project --exclude-types=ApiPublishing ApiPublishingRole Credential
56
+ LONGDESC
57
+ def from_dir(dir)
58
+ sync_path = SyncPath.new(dir, prj_connection.resource_types_for_export, excluded_types)
59
+
60
+ sync_path.load_resource('project') do |desc|
61
+ puts "applying #{desc['kind']} #{desc.dig('metadata', 'id')} to #{prj_connection.project}"
62
+ desc['metadata']['id'] = prj_connection.project
63
+ prj_connection.organization.apply(desc)
64
+ end
65
+
66
+ outdated_resources = {}
67
+ sync_path.types_to_sync.each do |type|
68
+ res_path = sync_path.resource_path(type)
69
+ updated_resource_ids = []
70
+ res_path.load_resources do |desc|
71
+ puts "applying #{desc['kind']} #{desc.dig('metadata', 'id')}"
72
+ updated_resource_ids += prj_connection.apply(desc)
73
+ end
74
+ outdated_resources[type] = prj_connection.resource_ids(type) - updated_resource_ids
75
+ end
76
+
77
+ outdated_resources.each do |type, resource_ids|
78
+ resource_ids.each do |resource_id|
79
+ puts "removing #{type} #{resource_id}"
80
+ prj_connection.delete(type, resource_id)
81
+ end
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ class ResourcePath
88
+ def initialize(path)
89
+ @path = path
90
+ @resource_files = []
91
+ end
92
+
93
+ def write_file(content, filename)
94
+ @path.mkpath
95
+ unless @path.directory? && @path.writable?
96
+ warn "Cannot write to #{@path}, please check directory exists and is writable"
97
+ exit 1
98
+ end
99
+ file = @path.join(filename)
100
+ file.write(content)
101
+ puts "updated #{file}..."
102
+ file
103
+ end
104
+
105
+ def write_resource_yaml(res_details, res_name)
106
+ file = write_file(res_details.to_yaml, "#{res_name}.yaml")
107
+ @resource_files << file
108
+ file
109
+ end
110
+
111
+ def load_resources(&block)
112
+ Util.resources_from_file(@path, ignore_missing: true, &block)
113
+ end
114
+
115
+ def load_resource(res_name, &block)
116
+ Util.resources_from_file(@path.join("#{res_name}.yaml"), ignore_missing: false, &block)
117
+ end
118
+
119
+ def remove_outdated_resources
120
+ (@path.glob('*.yaml') - @resource_files).each do |outdated_file|
121
+ outdated_file.delete
122
+ puts "removed #{outdated_file}"
123
+ end
124
+ end
125
+ end
126
+
127
+ class SyncPath < ResourcePath
128
+ attr_reader :types_to_sync
129
+
130
+ def initialize(dir, all_types, excluded_types)
131
+ super(Pathname.new(dir))
132
+ @all_types = all_types
133
+ @excluded_types_file = @path.join('.excluded_types')
134
+ @excluded_types = excluded_types || []
135
+ @excluded_types += @excluded_types_file.read.split if @excluded_types_file.exist?
136
+ @excluded_types &= @all_types
137
+ @excluded_types.sort!
138
+ @types_to_sync = @all_types - @excluded_types
139
+ puts "Resource types excluded from sync: #{@excluded_types.join(', ')}" if @excluded_types.any?
140
+ end
141
+
142
+ def resource_path(type)
143
+ ResourcePath.new(@path.join(type.underscore))
144
+ end
145
+
146
+ def update_excluded_types_file
147
+ @excluded_types_file.write(@excluded_types.join(" ") + "\n") if @excluded_types.any?
148
+ end
149
+ end
150
+
151
+ def excluded_types
152
+ excluded = options[:exclude_types]
153
+ excluded += ['Credential'] unless options[:credentials]
154
+ excluded
155
+ end
156
+
157
+ def generate_readme(res_details)
158
+ <<~EOREADME
159
+ # #{res_details.dig('definition', 'name')}
160
+ #{res_details.dig('definition', 'description')}
161
+
162
+ Project exported from #{File.join(prj_connection.public_project_url)} by xapixctl v#{Xapixctl::VERSION}.
163
+ EOREADME
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ module Xapixctl
6
+ module Util
7
+ extend self
8
+
9
+ class InvalidDocumentStructureError < StandardError
10
+ def initialize(file)
11
+ super("#{file} has invalid document structure")
12
+ end
13
+ end
14
+
15
+ DOCUMENT_STRUCTURE = %w[version kind metadata definition].freeze
16
+
17
+ def resources_from_file(filename, ignore_missing: false)
18
+ load_files(filename, ignore_missing) do |actual_file, yaml_string|
19
+ yaml_string.split(/^---\s*\n/).map { |yml| Psych.safe_load(yml) }.compact.each do |doc|
20
+ raise InvalidDocumentStructureError, actual_file unless (DOCUMENT_STRUCTURE - doc.keys.map(&:to_s)).empty?
21
+ yield doc
22
+ end
23
+ end
24
+ end
25
+
26
+ def load_files(filename, ignore_missing)
27
+ if filename == '-'
28
+ yield 'STDIN', $stdin.read
29
+ else
30
+ pn = filename.is_a?(Pathname) ? filename : Pathname.new(filename)
31
+ if pn.directory?
32
+ pn.glob(["**/*.yaml", "**/*.yml"]).sort.each { |dpn| yield dpn.to_s, dpn.read }
33
+ elsif pn.exist?
34
+ yield pn.to_s, pn.read
35
+ elsif !ignore_missing
36
+ warn "file not found: #{filename}"
37
+ exit 1
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Xapixctl
2
- VERSION = "1.0.0"
4
+ VERSION = "1.2.1"
3
5
  end
data/xapixctl.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path("lib", __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require "xapixctl/version"
@@ -8,7 +10,7 @@ Gem::Specification.new do |spec|
8
10
  spec.authors = ["Michael Reinsch"]
9
11
  spec.email = ["michael@xapix.io"]
10
12
 
11
- spec.summary = %q{xapix client library and command line tool}
13
+ spec.summary = 'xapix client library and command line tool'
12
14
  spec.homepage = "https://github.com/xapix-io/xapixctl"
13
15
  spec.license = "EPL-2.0"
14
16
 
@@ -17,20 +19,25 @@ Gem::Specification.new do |spec|
17
19
 
18
20
  # Specify which files should be added to the gem when it is released.
19
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
21
23
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
24
  end
23
25
  spec.bindir = "exe"
24
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
27
  spec.require_paths = ["lib"]
26
28
 
27
- spec.add_dependency "activesupport", "~> 5.2.3"
28
- spec.add_dependency "rest-client", "~> 2.1.0"
29
- spec.add_dependency "thor", "~> 0.20.3"
29
+ spec.required_ruby_version = '>= 2.6'
30
+
31
+ spec.add_dependency "activesupport", ">= 5.2.3", "< 6.0.0"
32
+ spec.add_dependency "rest-client", ">= 2.1.0", "< 3.0.0"
33
+ spec.add_dependency "thor", ">= 1.0.0", "< 1.2.0"
30
34
 
31
- spec.add_development_dependency "bundler", "~> 1.17.3"
32
- spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "bundler", "~> 2.1.4"
36
+ spec.add_development_dependency "rake", "~> 13.0"
33
37
  spec.add_development_dependency "relaxed-rubocop", "~> 2.5"
34
- spec.add_development_dependency "rspec", "~> 3.0"
35
- spec.add_development_dependency "rubocop", "~> 0.79.0"
38
+ spec.add_development_dependency "rspec", "~> 3.10.0"
39
+ spec.add_development_dependency "rubocop", "~> 1.11.0"
40
+ spec.add_development_dependency "rubocop-rake", "~> 0.5.1"
41
+ spec.add_development_dependency "rubocop-rspec", "~> 2.2.0"
42
+ spec.add_development_dependency "webmock", "~> 3.11.0"
36
43
  end
metadata CHANGED
@@ -1,85 +1,103 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xapixctl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Reinsch
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-11 00:00:00.000000000 Z
11
+ date: 2021-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 5.2.3
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 6.0.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: 5.2.3
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 6.0.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rest-client
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - "~>"
37
+ - - ">="
32
38
  - !ruby/object:Gem::Version
33
39
  version: 2.1.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 3.0.0
34
43
  type: :runtime
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
- - - "~>"
47
+ - - ">="
39
48
  - !ruby/object:Gem::Version
40
49
  version: 2.1.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 3.0.0
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: thor
43
55
  requirement: !ruby/object:Gem::Requirement
44
56
  requirements:
45
- - - "~>"
57
+ - - ">="
46
58
  - !ruby/object:Gem::Version
47
- version: 0.20.3
59
+ version: 1.0.0
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: 1.2.0
48
63
  type: :runtime
49
64
  prerelease: false
50
65
  version_requirements: !ruby/object:Gem::Requirement
51
66
  requirements:
52
- - - "~>"
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 1.0.0
70
+ - - "<"
53
71
  - !ruby/object:Gem::Version
54
- version: 0.20.3
72
+ version: 1.2.0
55
73
  - !ruby/object:Gem::Dependency
56
74
  name: bundler
57
75
  requirement: !ruby/object:Gem::Requirement
58
76
  requirements:
59
77
  - - "~>"
60
78
  - !ruby/object:Gem::Version
61
- version: 1.17.3
79
+ version: 2.1.4
62
80
  type: :development
63
81
  prerelease: false
64
82
  version_requirements: !ruby/object:Gem::Requirement
65
83
  requirements:
66
84
  - - "~>"
67
85
  - !ruby/object:Gem::Version
68
- version: 1.17.3
86
+ version: 2.1.4
69
87
  - !ruby/object:Gem::Dependency
70
88
  name: rake
71
89
  requirement: !ruby/object:Gem::Requirement
72
90
  requirements:
73
91
  - - "~>"
74
92
  - !ruby/object:Gem::Version
75
- version: '10.0'
93
+ version: '13.0'
76
94
  type: :development
77
95
  prerelease: false
78
96
  version_requirements: !ruby/object:Gem::Requirement
79
97
  requirements:
80
98
  - - "~>"
81
99
  - !ruby/object:Gem::Version
82
- version: '10.0'
100
+ version: '13.0'
83
101
  - !ruby/object:Gem::Dependency
84
102
  name: relaxed-rubocop
85
103
  requirement: !ruby/object:Gem::Requirement
@@ -100,29 +118,71 @@ dependencies:
100
118
  requirements:
101
119
  - - "~>"
102
120
  - !ruby/object:Gem::Version
103
- version: '3.0'
121
+ version: 3.10.0
104
122
  type: :development
105
123
  prerelease: false
106
124
  version_requirements: !ruby/object:Gem::Requirement
107
125
  requirements:
108
126
  - - "~>"
109
127
  - !ruby/object:Gem::Version
110
- version: '3.0'
128
+ version: 3.10.0
111
129
  - !ruby/object:Gem::Dependency
112
130
  name: rubocop
113
131
  requirement: !ruby/object:Gem::Requirement
114
132
  requirements:
115
133
  - - "~>"
116
134
  - !ruby/object:Gem::Version
117
- version: 0.79.0
135
+ version: 1.11.0
136
+ type: :development
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: 1.11.0
143
+ - !ruby/object:Gem::Dependency
144
+ name: rubocop-rake
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: 0.5.1
118
150
  type: :development
119
151
  prerelease: false
120
152
  version_requirements: !ruby/object:Gem::Requirement
121
153
  requirements:
122
154
  - - "~>"
123
155
  - !ruby/object:Gem::Version
124
- version: 0.79.0
125
- description:
156
+ version: 0.5.1
157
+ - !ruby/object:Gem::Dependency
158
+ name: rubocop-rspec
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - "~>"
162
+ - !ruby/object:Gem::Version
163
+ version: 2.2.0
164
+ type: :development
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - "~>"
169
+ - !ruby/object:Gem::Version
170
+ version: 2.2.0
171
+ - !ruby/object:Gem::Dependency
172
+ name: webmock
173
+ requirement: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - "~>"
176
+ - !ruby/object:Gem::Version
177
+ version: 3.11.0
178
+ type: :development
179
+ prerelease: false
180
+ version_requirements: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - "~>"
183
+ - !ruby/object:Gem::Version
184
+ version: 3.11.0
185
+ description:
126
186
  email:
127
187
  - michael@xapix.io
128
188
  executables:
@@ -130,6 +190,7 @@ executables:
130
190
  extensions: []
131
191
  extra_rdoc_files: []
132
192
  files:
193
+ - ".github/workflows/cd.yaml"
133
194
  - ".gitignore"
134
195
  - ".rspec"
135
196
  - ".rubocop.yml"
@@ -143,8 +204,16 @@ files:
143
204
  - bin/setup
144
205
  - exe/xapixctl
145
206
  - lib/xapixctl.rb
207
+ - lib/xapixctl/base_cli.rb
146
208
  - lib/xapixctl/cli.rb
147
209
  - lib/xapixctl/phoenix_client.rb
210
+ - lib/xapixctl/phoenix_client/connection.rb
211
+ - lib/xapixctl/phoenix_client/organization_connection.rb
212
+ - lib/xapixctl/phoenix_client/project_connection.rb
213
+ - lib/xapixctl/phoenix_client/result_handler.rb
214
+ - lib/xapixctl/preview_cli.rb
215
+ - lib/xapixctl/sync_cli.rb
216
+ - lib/xapixctl/util.rb
148
217
  - lib/xapixctl/version.rb
149
218
  - xapixctl.gemspec
150
219
  homepage: https://github.com/xapix-io/xapixctl
@@ -153,7 +222,7 @@ licenses:
153
222
  metadata:
154
223
  homepage_uri: https://github.com/xapix-io/xapixctl
155
224
  source_code_uri: https://github.com/xapix-io/xapixctl
156
- post_install_message:
225
+ post_install_message:
157
226
  rdoc_options: []
158
227
  require_paths:
159
228
  - lib
@@ -161,15 +230,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
230
  requirements:
162
231
  - - ">="
163
232
  - !ruby/object:Gem::Version
164
- version: '0'
233
+ version: '2.6'
165
234
  required_rubygems_version: !ruby/object:Gem::Requirement
166
235
  requirements:
167
236
  - - ">="
168
237
  - !ruby/object:Gem::Version
169
238
  version: '0'
170
239
  requirements: []
171
- rubygems_version: 3.0.6
172
- signing_key:
240
+ rubygems_version: 3.0.9
241
+ signing_key:
173
242
  specification_version: 4
174
243
  summary: xapix client library and command line tool
175
244
  test_files: []