cyclid-client 0.4.0 → 0.4.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: 078b4e179f24bb0cd378bcd6993fd834bdcb4555
4
- data.tar.gz: 0abab651a16850f267229149a11ebd59e58b089e
3
+ metadata.gz: d4d1024367f882c7fafb1ae3080d8d324c4552c6
4
+ data.tar.gz: 2ff1efb950368d68163c345f81b2de8cf034b202
5
5
  SHA512:
6
- metadata.gz: 6635460d43ba93794cf903263d3b0f6341965b79cdd17ef5b1f5c06b5a42df653205c0c997039198a88f55c1ba143397c7f03f70037208e2db305cbf17108026
7
- data.tar.gz: 696dd68c6329ac1159616b6174445543ab0c9ee162e2b1f0c9404a3401cdea245b505eed71e76d5c4eecea013f77707f71d84316289ae801ada9b711a495672b
6
+ metadata.gz: ed3506d6b65119d0cf36d032e88768ca1ba7cb1ed514e98ecafdb1362aa13efd49c0c271dd989e8353bf6b20ebf501faf08772ea9a5a0428e0360b569347ec8c
7
+ data.tar.gz: d0fdf7cea01e01d6c0f077cb8a0bac01b7739f44d4211417c5df7a0c604fbe262ceeb3f14046baeb34e47182e782f0beb4f9e8634dde36ca63e6298a1a973b20
data/bin/cyclid CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
+
3
4
  # Copyright 2016 Liqwyd Ltd.
4
5
  #
5
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,6 +32,8 @@ module Cyclid
31
32
  Kernel.puts t + args.join
32
33
  end
33
34
  alias colorize puts
35
+ alias warning puts
36
+ alias error puts
34
37
 
35
38
  def ask(question)
36
39
  print "#{question}: "
@@ -42,16 +45,30 @@ module Cyclid
42
45
  class Terminal < Base
43
46
  class << self
44
47
  def colorize(title, *args)
48
+ puts_with_color(:cyan, title, args)
49
+ end
50
+
51
+ def warning(title, *args)
52
+ puts_with_color(:yellow, title, args)
53
+ end
54
+
55
+ def error(title, *args)
56
+ puts_with_color(:red, title, args)
57
+ end
58
+
59
+ def ask(question)
60
+ print "#{question}: ".colorize(:red)
61
+ end
62
+
63
+ private
64
+
65
+ def puts_with_color(color, title, *args)
45
66
  t = if args.empty?
46
67
  title
47
68
  else
48
69
  "#{title}: "
49
70
  end
50
- Kernel.puts t.colorize(:cyan) + args.join
51
- end
52
-
53
- def ask(question)
54
- print "#{question}: ".colorize(:red)
71
+ Kernel.puts t.colorize(color) + args.join
55
72
  end
56
73
  end
57
74
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +18,8 @@ require 'yaml'
17
18
  require 'json'
18
19
  require 'cyclid/constants'
19
20
 
21
+ require_relative 'linter'
22
+
20
23
  module Cyclid
21
24
  module Cli
22
25
  # 'job' sub-command
@@ -33,36 +36,12 @@ module Cyclid
33
36
 
34
37
  The --json option causes the job file to be parsed as JSON.
35
38
  LONGDESC
36
- option :yaml, aliases: '-y'
37
- option :json, aliases: '-j'
39
+ option :yaml, type: :boolean, aliases: '-y', desc: 'Force the input file type to YAML'
40
+ option :json, type: :boolean, aliases: '-j', desc: 'Force the input file type to JSON'
38
41
  def submit(filename)
39
- job_file = File.expand_path(filename)
40
- raise 'Cannot open file' unless File.exist?(job_file)
41
-
42
- job_type = if options[:yaml]
43
- 'yaml'
44
- elsif options[:json]
45
- 'json'
46
- else
47
- # Detect format
48
- match = job_file.match(/\A.*\.(json|yml|yaml)\z/)
49
- match[1]
50
- end
51
- job_type = 'yaml' if job_type == 'yml'
42
+ job_data, job_type = load_job_file(filename)
52
43
 
53
- # Do a client-side sanity check by attempting to parse the file; we
54
- # don't do anything with the data but it fails-fast if the file has a
55
- # syntax error
56
- job = File.read(job_file)
57
- if job_type == 'yaml'
58
- YAML.load(job)
59
- elsif job_type == 'json'
60
- JSON.parse(job)
61
- else
62
- raise 'Unknown or unsupported file type'
63
- end
64
-
65
- job_info = client.job_submit(client.config.organization, job, job_type)
44
+ job_info = client.job_submit(client.config.organization, job_data, job_type)
66
45
  Formatter.colorize 'Job', job_info['job_id'].to_s
67
46
  rescue StandardError => ex
68
47
  abort "Failed to submit job: #{ex}"
@@ -138,6 +117,126 @@ module Cyclid
138
117
  rescue StandardError => ex
139
118
  abort "Failed to get job list: #{ex}"
140
119
  end
120
+
121
+ desc 'lint FILENAME', 'Check your job file for errors'
122
+ long_desc <<-LONGDESC
123
+ Lint a Cyclid job file for errors and potential problems. FILENAME should be the path to a
124
+ valid Cyclid job file, in either YAML or JSON format.
125
+
126
+ Cyclid will attempt to detect the format of the job file automatically. You can force the
127
+ parsing format using either the --yaml or --json options.
128
+
129
+ The --yaml option causes the job file to be parsed as YAML.
130
+
131
+ The --json option causes the job file to be parsed as JSON.
132
+ LONGDESC
133
+ option :yaml, type: :boolean, aliases: '-y', desc: 'Force the input file type to YAML'
134
+ option :json, type: :boolean, aliases: '-j', desc: 'Force the input file type to JSON'
135
+ def lint(filename)
136
+ job = parse_job_file(filename)
137
+
138
+ # Now run the job through the Verifier to find problems
139
+ verifier = RemoteVerifier.new(client: client)
140
+ verifier.verify(job)
141
+
142
+ # Display the result summary
143
+ verifier.status.messages.each do |message|
144
+ case message[:type]
145
+ when Cyclid::Linter::StatusLogger::MessageTypes::WARNING
146
+ Formatter.warning 'Warning', message[:text]
147
+ when Cyclid::Linter::StatusLogger::MessageTypes::ERROR
148
+ Formatter.error 'Error', message[:text]
149
+ end
150
+ end
151
+
152
+ Formatter.puts ''
153
+ Formatter.error 'Errors', verifier.status.errors \
154
+ unless verifier.status.errors.zero?
155
+ Formatter.warning 'Warnings', verifier.status.warnings \
156
+ unless verifier.status.warnings.zero?
157
+
158
+ # Finish with an exit code of 1 if there were problems
159
+ exit 1 unless verifier.status.errors.zero? && verifier.status.warnings.zero?
160
+ end
161
+
162
+ desc 'format FILENAME', 'Re-format or convert your job file'
163
+ long_desc <<-LONGDESC
164
+ Pretty-format a Cyclid job file. FILENAME should be the path to a valid Cyclid job file,
165
+ in either YAML or JSON format. The output format can be YAML or JSON, regardless of the
166
+ input format.
167
+
168
+ Cyclid will attempt to detect the format of the job file automatically. You can force the
169
+ parsing format using either the --yaml or --json options.
170
+
171
+ The --yaml option causes the job file to be parsed as YAML.
172
+
173
+ The --json option causes the job file to be parsed as JSON.
174
+
175
+ The --yamlout option sets the output format the YAML.
176
+
177
+ The --jsonout option sets the output format the JSON.
178
+ LONGDESC
179
+
180
+ option :yaml, type: :boolean, aliases: '-y', desc: 'Force the input file type to YAML'
181
+ option :json, type: :boolean, aliases: '-j', desc: 'Force the input file type to JSON'
182
+ option :yamlout, type: :boolean, aliases: '-Y', desc: 'Set the output format to YAML'
183
+ option :jsonout, type: :boolean,
184
+ aliases: '-J',
185
+ desc: 'Set the input format to JSON',
186
+ default: true
187
+ def format(filename)
188
+ job = parse_job_file(filename)
189
+
190
+ # Re-emit; Oj & YAML are nice and trustworthy in that they wont re-order objects. This
191
+ # means that we can nicely indent, or convert, without worrying that things like the
192
+ # Sequence is going to get re-ordered.
193
+ #
194
+ # The downside is that we can't force things like ordering of top-level elements,
195
+ # although users may consider that an advantage.
196
+ if options[:yamlout]
197
+ puts YAML.dump(job)
198
+ else
199
+ puts Oj.dump(job, indent: 2)
200
+ end
201
+ end
202
+
203
+ private
204
+
205
+ # Load a Cyclid job file, including format detection
206
+ def load_job_file(filename)
207
+ job_file = File.expand_path(filename)
208
+ raise 'Cannot open file' unless File.exist?(job_file)
209
+
210
+ job_type = if options[:yaml]
211
+ 'yaml'
212
+ elsif options[:json]
213
+ 'json'
214
+ else
215
+ # Detect format
216
+ match = job_file.match(/\A.*\.(json|yml|yaml)\z/)
217
+ match[1]
218
+ end
219
+ job_type = 'yaml' if job_type == 'yml'
220
+
221
+ # Attempt to load & parse the job file; any JSON or YAML syntax errors
222
+ # will be caught here
223
+ job_data = File.read(job_file)
224
+
225
+ [job_data, job_type]
226
+ end
227
+
228
+ # Load and parse a Cyclid job file
229
+ def parse_job_file(filename)
230
+ job_data, job_type = load_job_file(filename)
231
+
232
+ if job_type == 'yaml'
233
+ YAML.safe_load(job_data)
234
+ elsif job_type == 'json'
235
+ JSON.parse(job_data)
236
+ else
237
+ raise 'Unknown or unsupported file type'
238
+ end
239
+ end
141
240
  end
142
241
  end
143
242
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2017 Liqwyd Ltd.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'yaml'
18
+ require 'json'
19
+ require 'cyclid/linter'
20
+
21
+ module Cyclid
22
+ module Cli
23
+ # Verify by fetching Stages from a remote server
24
+ class RemoteVerifier < Cyclid::Linter::Verifier
25
+ def initialize(args)
26
+ @client = args[:client]
27
+
28
+ super
29
+ end
30
+
31
+ # Find a Stage by it's name on a remote server
32
+ def stage_exists?(name)
33
+ @client.stage_get(@client.config.organization, name)
34
+
35
+ Bertrand::EXIST
36
+ rescue StandardError => ex
37
+ if ex.to_s == 'stage does not exist'
38
+ Bertrand::NOT_EXIST
39
+ else
40
+ Bertrand::UNKNOWN
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -63,8 +64,8 @@ module Cyclid
63
64
 
64
65
  The --json option causes the file to be parsed as JSON.
65
66
  LONGDESC
66
- option :yaml, aliases: '-y'
67
- option :json, aliases: '-j'
67
+ option :yaml, type: :boolean, aliases: '-y', desc: 'Force the input file type to YAML'
68
+ option :json, type: :boolean, aliases: '-j', desc: 'Force the input file type to JSON'
68
69
  option :version, aliases: '-v'
69
70
  def create(filename)
70
71
  stage_file = File.expand_path(filename)
@@ -85,7 +86,7 @@ module Cyclid
85
86
  # will fail-fast if the file has a syntax error
86
87
  stage = File.read(stage_file)
87
88
  stage_data = if stage_type == 'yaml'
88
- YAML.load(stage)
89
+ YAML.safe_load(stage)
89
90
  elsif stage_type == 'json'
90
91
  JSON.parse(stage)
91
92
  else
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -80,6 +81,7 @@ module Cyclid
80
81
  def api_request(uri, req)
81
82
  http = Net::HTTP.new(uri.hostname, uri.port)
82
83
  http.use_ssl = uri.scheme == 'https'
84
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @config.ssl_verify_none
83
85
 
84
86
  res = http.request(req)
85
87
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,7 +43,7 @@ module Cyclid
42
43
  nonce = SecureRandom.hex
43
44
  headers = signer.sign_request(uri.path,
44
45
  @config.secret,
45
- auth_header_format: '%{auth_scheme} %{username}:%{signature}', # rubocop:disable Metrics/LineLength
46
+ auth_header_format: '%<auth_scheme>s %<username>s:%<signature>s', # rubocop:disable Metrics/LineLength
46
47
  username: @config.username,
47
48
  nonce: nonce,
48
49
  method: method)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -66,13 +67,15 @@ module Cyclid
66
67
  user['secret'] = secret unless secret.nil?
67
68
 
68
69
  # Add the password if one was supplied
69
- user['password'] = if password =~ /\A\$2a\$.+\z/
70
- # Password is already encrypted
71
- password
72
- else
73
- # Encrypt the plaintext password
74
- BCrypt::Password.create(password).to_s
75
- end unless password.nil?
70
+ unless password.nil?
71
+ user['password'] = if password =~ /\A\$2a\$.+\z/
72
+ # Password is already encrypted
73
+ password
74
+ else
75
+ # Encrypt the plaintext password
76
+ BCrypt::Password.create(password).to_s
77
+ end
78
+ end
76
79
 
77
80
  @logger.debug user
78
81
 
@@ -114,13 +117,15 @@ module Cyclid
114
117
  user['secret'] = args[:secret] if args.key? :secret and args[:secret]
115
118
 
116
119
  # Add the password if one was supplied
117
- user['password'] = if args[:password] =~ /\A\$2a\$.+\z/
118
- # Password is already encrypted
119
- args[:password]
120
- else
121
- # Encrypt the plaintext password
122
- BCrypt::Password.create(args[:password]).to_s
123
- end if args.key? :password and args[:password]
120
+ if args.key? :password and args[:password]
121
+ user['password'] = if args[:password] =~ /\A\$2a\$.+\z/
122
+ # Password is already encrypted
123
+ args[:password]
124
+ else
125
+ # Encrypt the plaintext password
126
+ BCrypt::Password.create(args[:password]).to_s
127
+ end
128
+ end
124
129
 
125
130
  @logger.debug user
126
131
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Copyright 2016 Liqwyd Ltd.
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,6 +26,7 @@ module Cyclid
25
26
  :server,
26
27
  :port,
27
28
  :tls,
29
+ :ssl_verify_none,
28
30
  :organization,
29
31
  :username,
30
32
  :secret,
@@ -65,6 +67,10 @@ module Cyclid
65
67
  def initialize(options = {})
66
68
  # Load the config if a path was provided
67
69
  @path = options[:path] || nil
70
+ unless File.file?(@path)
71
+ raise "no config found at #{@path} - Have you selected an organisation with " \
72
+ '`cyclid organization use <name>`?'
73
+ end
68
74
  @config = @path.nil? ? nil : YAML.load_file(@path)
69
75
 
70
76
  # Select the authentication type & associated authentication data.
@@ -72,6 +78,7 @@ module Cyclid
72
78
  case @auth
73
79
  when AUTH_NONE
74
80
  # Nothing
81
+ nil
75
82
  when AUTH_HMAC
76
83
  @secret = options[:secret] || @config['secret']
77
84
  when AUTH_BASIC
@@ -85,6 +92,7 @@ module Cyclid
85
92
  @server = options[:server] || nil
86
93
  @port = options[:port] || nil
87
94
  @tls = options[:tls] || nil
95
+ @ssl_verify_none = options[:ssl_verify_none] || nil
88
96
  @organization = options[:organization] || nil
89
97
  @username = options[:username] || nil
90
98
 
@@ -94,6 +102,7 @@ module Cyclid
94
102
  @server ||= @config['server']
95
103
  @port ||= @config['port'] || 8361
96
104
  @tls ||= @config['tls'] || false
105
+ @ssl_verify_none ||= @config['ssl_verify_none'] || false
97
106
  @organization ||= @config['organization']
98
107
  @username ||= @config['username']
99
108
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Cyclid
3
4
  module Client
4
- VERSION = '0.4.0'
5
+ VERSION = '0.4.1'.freeze
5
6
  end
6
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyclid-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristian Van Der Vliet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-28 00:00:00.000000000 Z
11
+ date: 2017-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -113,6 +113,7 @@ files:
113
113
  - lib/cyclid/cli/admin/user.rb
114
114
  - lib/cyclid/cli/formatter.rb
115
115
  - lib/cyclid/cli/job.rb
116
+ - lib/cyclid/cli/linter.rb
116
117
  - lib/cyclid/cli/organization.rb
117
118
  - lib/cyclid/cli/organization/config.rb
118
119
  - lib/cyclid/cli/organization/member.rb
@@ -153,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
154
  version: '0'
154
155
  requirements: []
155
156
  rubyforge_project:
156
- rubygems_version: 2.5.1
157
+ rubygems_version: 2.2.0
157
158
  signing_key:
158
159
  specification_version: 4
159
160
  summary: Cyclid command line client & library