habitat-client 0.6.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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +8 -0
- data/Gemfile +3 -0
- data/README.md +38 -0
- data/Rakefile +6 -0
- data/habitat-client.gemspec +28 -0
- data/lib/habitat/client.rb +329 -0
- data/lib/habitat/client/version.rb +22 -0
- data/lib/habitat/exceptions.rb +38 -0
- metadata +165 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6b6f661829b14a79b6baf3e8d49567d8b824d3a9
|
4
|
+
data.tar.gz: 98edb09a4de342b6914537e0ac5f23bbcf82476e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 76fdffc37cc805ecd11594632dff4ff5c5b65828794f22534b86e1b1f0009147a71ebb5ef6098c4d90ddc3fd35df9dc96d2ebf23276302c0909649f898be61bf
|
7
|
+
data.tar.gz: 2dd61ea89763ebc4711bf90ae2aeef7f716e44e7dee455f313a3d8d4939015cc9e4dd6dc2f21a77cb4cff9eaf22265c68bb70619f5e0d505d45e25785a42e759
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Habitat::Client
|
2
|
+
|
3
|
+
This is the Ruby client library for Habitat.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'habitat-client'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install habitat-client
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# Create an instance object
|
25
|
+
hc = Habitat::Client.new
|
26
|
+
|
27
|
+
# Create the instance with a specific Habitat Depot
|
28
|
+
hc = Habitat::Client.new('http://localhost:9636/v1/depot')
|
29
|
+
|
30
|
+
# Upload a Habitat Artifact
|
31
|
+
hc.put_package('core-pandas-0.0.1-20160425190407.hart')
|
32
|
+
|
33
|
+
# Show a package
|
34
|
+
hc.show_package('core/pandas')
|
35
|
+
|
36
|
+
# Promote a package to the `stable` view
|
37
|
+
hc.promote_package('core/pandas', 'stable')
|
38
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'habitat/client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'habitat-client'
|
8
|
+
spec.version = Habitat::Client::VERSION
|
9
|
+
spec.authors = ['Joshua Timberman']
|
10
|
+
spec.email = ['humans@habitat.sh']
|
11
|
+
|
12
|
+
spec.summary = 'Habitat Depot Client Library'
|
13
|
+
spec.homepage = 'https://www.habitat.sh'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.add_dependency 'rbnacl', '~> 3.3'
|
20
|
+
spec.add_dependency 'faraday', '~> 0.9.0'
|
21
|
+
spec.add_dependency 'mixlib-shellout', '~> 2.2'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'pry'
|
24
|
+
spec.add_development_dependency 'pry-coolline'
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
end
|
@@ -0,0 +1,329 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2016 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
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
|
+
|
18
|
+
require_relative 'client/version'
|
19
|
+
require_relative 'exceptions'
|
20
|
+
require 'faraday'
|
21
|
+
require 'json'
|
22
|
+
|
23
|
+
module Habitat
|
24
|
+
# Habitat Client
|
25
|
+
#
|
26
|
+
# This class is an API client to the Habitat Depot. It uses Faraday
|
27
|
+
# under the covers to give us a nice HTTP interface.
|
28
|
+
#
|
29
|
+
class Client
|
30
|
+
attr_reader :depot, :connection
|
31
|
+
|
32
|
+
# Creates the Habitat client connection object. The public
|
33
|
+
# interface should be used for the common interactions with the
|
34
|
+
# API, but more complex operations can be done using the
|
35
|
+
# +connection+ attribute through Faraday.
|
36
|
+
#
|
37
|
+
# === Attributes
|
38
|
+
#
|
39
|
+
# * +depot+ - URL to the Habitat Depot, defaults to the public
|
40
|
+
# service run by the Habitat organization
|
41
|
+
# * +connection+ - A Faraday object representing the HTTP connection
|
42
|
+
#
|
43
|
+
# === Examples
|
44
|
+
#
|
45
|
+
# hc = Habitat::Client.new
|
46
|
+
# hc = Habitat::Client.new('https://habitat-depot.example.com')
|
47
|
+
# hc.connection.get('/pkgs')
|
48
|
+
|
49
|
+
def initialize(depot = 'https://willem.habitat.sh/v1/depot')
|
50
|
+
@depot = depot
|
51
|
+
@connection = Faraday.new(url: @depot) do |f|
|
52
|
+
f.request :multipart
|
53
|
+
f.request :url_encoded
|
54
|
+
f.adapter :net_http
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Downloads the specified key. By default, it will download to the
|
59
|
+
# current directory as a file named by the +X-Filename+ HTTP
|
60
|
+
# header.
|
61
|
+
def fetch_key(_key, _path = '.')
|
62
|
+
raise 'Downloading keys is not yet implemented'
|
63
|
+
end
|
64
|
+
|
65
|
+
# Uploads the specified key from the given path location.
|
66
|
+
def put_key(_key, _path)
|
67
|
+
raise 'Uploading keys is not yet implemented'
|
68
|
+
end
|
69
|
+
|
70
|
+
# Downloads the specified package. It will default to the latest
|
71
|
+
# version if not specified, or the latest release of a version if
|
72
|
+
# the release is not specified.
|
73
|
+
#
|
74
|
+
# The file will be downloaded to the current directory as a file
|
75
|
+
# named by the +X-Filename+ HTTP header.
|
76
|
+
#
|
77
|
+
# === Arguments
|
78
|
+
#
|
79
|
+
# * +pkg+ - A package string, like +core/zlib+
|
80
|
+
def fetch_package(pkg, path = '.')
|
81
|
+
download(fetch_package_path(pkg), path)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Show details about the specified package using a package
|
85
|
+
# identifier string. If the version or release are not specified,
|
86
|
+
# +latest+ is assumed.
|
87
|
+
#
|
88
|
+
# === Examples
|
89
|
+
#
|
90
|
+
# hc = Habitat::Client.new
|
91
|
+
# hc.show_package('core/zlib')
|
92
|
+
# hc.show_package('core/zlib/1.2.8')
|
93
|
+
# hc.show_package('core/zlib/1.2.8/20160222155343')
|
94
|
+
def show_package(pkg)
|
95
|
+
JSON.parse(@connection.get(show_package_path(pkg)).body)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Uploads a package from the specified filepath.
|
99
|
+
#
|
100
|
+
# === Arguments
|
101
|
+
#
|
102
|
+
# * +file+ - The file to upload
|
103
|
+
#
|
104
|
+
# === Examples
|
105
|
+
def put_package(file)
|
106
|
+
upload(upload_package_path(file), file)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Promotes a package to the specified view, for example
|
110
|
+
# +core/zlib+ to +staging+ or +production+
|
111
|
+
#
|
112
|
+
# === Examples
|
113
|
+
#
|
114
|
+
# hc = Habitat::Client.new
|
115
|
+
# hc.promote_package('core/pandas/0.0.1/20160419213120', 'staging')
|
116
|
+
def promote_package(pkg, view)
|
117
|
+
promote(promote_artifact_path(pkg, view))
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# Returns the PackageIdent as a string with the version and/or
|
123
|
+
# release qualified if not specified. For example, if +pkg+ is
|
124
|
+
# +'core/zlib'+, it will return +'core/zlib/latest'+.
|
125
|
+
def package_ident(pkg)
|
126
|
+
PackageIdent.new(*pkg.split('/')).to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
# If the PackageIdent has four parts, it's fully qualified.
|
130
|
+
def fully_qualified?(pkg)
|
131
|
+
parts = package_ident(pkg).split('/')
|
132
|
+
parts.count == 4 && parts.last != 'latest'
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns a URL path for retrieving the PackageIdent specified.
|
136
|
+
def show_package_path(pkg)
|
137
|
+
['pkgs', package_ident(pkg)].join('/')
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns a URL path for retrieving the PackageIdent specified
|
141
|
+
# using the download path.
|
142
|
+
def fetch_package_path(pkg)
|
143
|
+
resolved_path = resolve_latest(package_ident(pkg))
|
144
|
+
['pkgs', resolved_path, 'download'].join('/')
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns a URL path for retrieving the specified key
|
148
|
+
def fetch_key_path(key)
|
149
|
+
['keys', key].join('/')
|
150
|
+
end
|
151
|
+
|
152
|
+
# Returns a URL path for uploading the specified package artifact
|
153
|
+
def upload_package_path(path)
|
154
|
+
['pkgs', derive_pkgid_from_file(path)].join('/')
|
155
|
+
end
|
156
|
+
|
157
|
+
# Resolves the latest version of the package returned by +show_package+
|
158
|
+
def resolve_latest(pkg)
|
159
|
+
latest = show_package(pkg)
|
160
|
+
%w(origin name version release).map { |i| latest['ident'][i] }.join('/')
|
161
|
+
end
|
162
|
+
|
163
|
+
def validate_pkg_path!(pkg)
|
164
|
+
# rubocop:disable GuardClause
|
165
|
+
unless fully_qualified?(pkg)
|
166
|
+
raise <<-EOH.gsub(/^\s+/, '')
|
167
|
+
You must specify a fully qualified package path, such as:
|
168
|
+
|
169
|
+
core/pandas/0.0.1/20160419213120
|
170
|
+
|
171
|
+
You specified `#{pkg}' in `#{caller_locations(1, 1)[0].label}'
|
172
|
+
EOH
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Opens a Habitat Artifact and reads the IDENT metadata to get the
|
177
|
+
# fully qualified package identifier.
|
178
|
+
#
|
179
|
+
def derive_pkgid_from_file(file)
|
180
|
+
require 'mixlib/shellout'
|
181
|
+
tail_n = 'tail -n +6'
|
182
|
+
xzcat = 'xzcat --decompress'
|
183
|
+
tar_toc = 'tar -tf -'
|
184
|
+
tar_stdout = 'tar -xOf -'
|
185
|
+
subcommand = "#{tail_n} #{file} | #{xzcat} | #{tar_toc} | grep '/IDENT$'"
|
186
|
+
command = "#{tail_n} #{file} | #{xzcat} | #{tar_stdout} $(#{subcommand})"
|
187
|
+
pkgid = Mixlib::ShellOut.new(command)
|
188
|
+
begin
|
189
|
+
pkgid.run_command.stdout.chomp
|
190
|
+
rescue
|
191
|
+
raise "Could not derive a version from #{file}, aborting!"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Returns a hex encoded blake2b hash from the given data.
|
196
|
+
def blake2b_checksum(data, size = 32)
|
197
|
+
require 'rbnacl'
|
198
|
+
require 'digest'
|
199
|
+
Digest.hexencode(RbNaCl::Hash.blake2b(data, digest_size: size)).chomp
|
200
|
+
end
|
201
|
+
|
202
|
+
# Returns the URL path for promoting an artifact
|
203
|
+
def promote_artifact_path(pkg, view)
|
204
|
+
validate_pkg_path!(pkg)
|
205
|
+
['views', view, 'pkgs', pkg, 'promote'].join('/')
|
206
|
+
end
|
207
|
+
|
208
|
+
def promote(url)
|
209
|
+
response = @connection.post(url)
|
210
|
+
if response.status == 200
|
211
|
+
return true
|
212
|
+
else
|
213
|
+
raise Habitat::PromotionError,
|
214
|
+
"Depot returned #{response.status} on promote"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Downloads the file from the depot.
|
219
|
+
#
|
220
|
+
def download(url, path = '.')
|
221
|
+
response = @connection.get(url)
|
222
|
+
if response.status == 200
|
223
|
+
::File.open(
|
224
|
+
::File.join(
|
225
|
+
path,
|
226
|
+
response.headers['x-filename']
|
227
|
+
), 'wb') do |fp|
|
228
|
+
fp.write(response.body)
|
229
|
+
end
|
230
|
+
else
|
231
|
+
raise Habitat::DownloadError,
|
232
|
+
"Depot returned #{response.status} on download"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Uploads a file to the depot.
|
237
|
+
#
|
238
|
+
# === Attributes
|
239
|
+
# * +url+ - the URL path on the depot server
|
240
|
+
# * +path+ - the file path to upload
|
241
|
+
#
|
242
|
+
def upload(url, path)
|
243
|
+
payload = { file: Faraday::UploadIO.new(path, 'application/octet-stream') }
|
244
|
+
response = @connection.post do |req|
|
245
|
+
req.url url
|
246
|
+
req.params['checksum'] = blake2b_checksum(IO.read(path))
|
247
|
+
req.body = payload
|
248
|
+
end
|
249
|
+
|
250
|
+
if response.status == 200
|
251
|
+
return true
|
252
|
+
else
|
253
|
+
raise Habitat::UploadError,
|
254
|
+
"Depot returned #{response.status} on uploading '#{path}'"
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# Habitat Package Ident
|
260
|
+
#
|
261
|
+
# This class builds a Habitat Package Identifier object using the
|
262
|
+
# four components of a Habitat package: origin, package name (pkg),
|
263
|
+
# version, and release. It subclasses +Struct+ with arguments that
|
264
|
+
# have default values - 'latest' for +version+ and +release+. It
|
265
|
+
# also implements a method to return the package identifier as a +/+
|
266
|
+
# separated string for use in the Habitat Depot API
|
267
|
+
# rubocop:disable StructInheritance
|
268
|
+
class PackageIdent < Struct.new(:origin, :pkg, :version, :release)
|
269
|
+
# Creates the package identifier using the origin and package
|
270
|
+
# name. Optionally will also use the version and release, or sets
|
271
|
+
# them to latest if not specified.
|
272
|
+
#
|
273
|
+
# === Attributes
|
274
|
+
#
|
275
|
+
# * +origin+ - The package origin
|
276
|
+
# * +pkg+ - The package name
|
277
|
+
# * +version+ - The version of the package
|
278
|
+
# * +release+ - The timestamp release of the package
|
279
|
+
#
|
280
|
+
# === Examples
|
281
|
+
#
|
282
|
+
# Use the latest core/zlib package:
|
283
|
+
#
|
284
|
+
# Habitat::PackageIdent.new('core', 'zlib')
|
285
|
+
#
|
286
|
+
# Use version 1.2.8 of the core/zlib package:
|
287
|
+
#
|
288
|
+
# Habitat::PackageIdent.new('core', 'zlib', '1.2.8')
|
289
|
+
#
|
290
|
+
# Use a specific release of version 1.2.8 of the core/zlib
|
291
|
+
# package:
|
292
|
+
#
|
293
|
+
# Habitat::PackageIdent.new('core', 'zlib', '1.2.8', '20160222155343')
|
294
|
+
#
|
295
|
+
# Pass an array as an argument:
|
296
|
+
#
|
297
|
+
# Habitat::PackageIdent.new(*['core', 'zlib'])
|
298
|
+
#
|
299
|
+
# For example, from a +#split+ string:
|
300
|
+
#
|
301
|
+
# Habitat::PackageIdent.new(*'core/zlib'.split('/'))
|
302
|
+
|
303
|
+
def initialize(origin, pkg, version = 'latest', release = 'latest')
|
304
|
+
super
|
305
|
+
end
|
306
|
+
|
307
|
+
# Returns a string from a +Habitat::PackageIdent+ object separated by
|
308
|
+
# +/+ (forward slash).
|
309
|
+
#
|
310
|
+
# === Examples
|
311
|
+
#
|
312
|
+
# zlib = Habitat::PackageIdent.new('core', 'zlib')
|
313
|
+
# zlib.to_s #=> "core/zlib/latest"
|
314
|
+
|
315
|
+
def to_s
|
316
|
+
parts = if self[:version] == 'latest'
|
317
|
+
[self[:origin], self[:pkg], self[:version]]
|
318
|
+
else
|
319
|
+
[self[:origin], self[:pkg], self[:version], self[:release]]
|
320
|
+
end
|
321
|
+
parts.join('/')
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# So users don't have to remember +Habitat+ vs +Hab+
|
327
|
+
module Hab
|
328
|
+
include Habitat
|
329
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2016 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
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
|
+
|
18
|
+
module Habitat
|
19
|
+
class Client
|
20
|
+
VERSION = '0.6.0'.freeze
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2016 Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
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
|
+
module Habitat
|
18
|
+
# Error class for promotion errors
|
19
|
+
class PromotionError < StandardError
|
20
|
+
def initialize(msg = 'Promotion of package on Depot server failed')
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Error class for upload errors
|
26
|
+
class UploadError < StandardError
|
27
|
+
def initialize(msg = 'Upload of artifact to Depot server failed')
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Error class for download errors
|
33
|
+
class DownloadError < StandardError
|
34
|
+
def initialize(msg = 'Download of artifact from Depot server failed')
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: habitat-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joshua Timberman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rbnacl
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.9.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mixlib-shellout
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-coolline
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.11'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.11'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.0'
|
125
|
+
description:
|
126
|
+
email:
|
127
|
+
- humans@habitat.sh
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- ".rubocop.yml"
|
135
|
+
- Gemfile
|
136
|
+
- README.md
|
137
|
+
- Rakefile
|
138
|
+
- habitat-client.gemspec
|
139
|
+
- lib/habitat/client.rb
|
140
|
+
- lib/habitat/client/version.rb
|
141
|
+
- lib/habitat/exceptions.rb
|
142
|
+
homepage: https://www.habitat.sh
|
143
|
+
licenses: []
|
144
|
+
metadata: {}
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
requirements: []
|
160
|
+
rubyforge_project:
|
161
|
+
rubygems_version: 2.6.4
|
162
|
+
signing_key:
|
163
|
+
specification_version: 4
|
164
|
+
summary: Habitat Depot Client Library
|
165
|
+
test_files: []
|