packagecloud-ruby 0.2.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7499f7471cde932e1a36adfcc98484b4e432883f
4
+ data.tar.gz: ba375fde7e831a512dfb0166ff9ef534226ac235
5
+ SHA512:
6
+ metadata.gz: 84c78d28a23fada009a81f27aca356e532d2771ee5aa2430a4edfc81b9c8a2232b928ca9a9a5cb3c0846739236a1cc14d3d4b7cff03e8cd45d1fbfd4437671c9
7
+ data.tar.gz: 3cad35c0bd37c2b69dd70f47013c78b74c392784901427f2fa768ff0a322798d2544ec5b69854820f079b9a0009eb42b3b4e15b4ad74b8ae8814488ce11433e4
data/.document ADDED
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.rdoc
3
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ doc/
3
+ pkg/
4
+ vendor/cache/*.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup rdoc --title "libpcloud Documentation" --protected
data/ChangeLog.rdoc ADDED
@@ -0,0 +1,4 @@
1
+ === 0.1.0 / 2014-11-11
2
+
3
+ * Initial release:
4
+
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'excon'
4
+ gem 'json_pure'
5
+ gem 'mime'
6
+
7
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 Computology, LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,64 @@
1
+ = libpcloud
2
+
3
+ * {Homepage}[https://rubygems.org/gems/libpcloud]
4
+ * {Documentation}[http://rubydoc.info/gems/libpcloud/frames]
5
+ * {Email}[mailto:support@packagecloud.io]
6
+
7
+ == Description
8
+
9
+ Ruby library for communicating with the {packagecloud.io}[https://packagecloud.io] API.
10
+
11
+ == Features
12
+
13
+ Implemented:
14
+
15
+ * {Get Package Contents}[https://packagecloud.io/docs/api#resource_packages_method_contents]
16
+ * {Create Package}[https://packagecloud.io/docs/api#resource_packages_method_create]
17
+ * {List distributions}[https://packagecloud.io/docs/api#resource_distributions_method_index]
18
+
19
+ == Usage
20
+
21
+ require 'packagecloud'
22
+
23
+ # Create a client
24
+ credentials = Credentials.new("joedamato", "test_token")
25
+ @client = PackageCloud.new(credentials)
26
+
27
+ # Get distributions
28
+ distros = @client.distributions
29
+
30
+ # Looking up a distribution id by name
31
+ id = @client.find_distribution_id("centos/6") # returns 12
32
+
33
+ # Looking up all repositories available for a client
34
+ repos = @client.repositories
35
+
36
+ # Lookup info on a single repo
37
+ repo = @client.repository("my_repo")
38
+
39
+ # Creating a repository
40
+ @client.create_repository("my_repo")
41
+
42
+ # Create Packages (takes IO object for file)
43
+ gem_package = Package.new(open("rails-4.0.0.gem"))
44
+ rpm_package = Package.new(open("libcurl-0.1.2.rpm"), 12) # 12 being the distribution id for centos/6, for example
45
+
46
+ # Creating source Packages
47
+ source_files = { "jake_1.0.orig.tar.bz2" => open("/path/jake_1.0.orig.tar.bz2"),
48
+ "jake_1.0-7.debian.tar.gz" => open("/path/jake_1.0-7.debian.tar.gz") }
49
+ dsc_package = Package.new("jake_1.0-7.dsc", 20, source_files)
50
+
51
+ # Upload Packages
52
+ @client.put_package("test_repo", gem_package)
53
+ @client.put_package("test_repo", rpm_package)
54
+ @client.put_package("test_repo", dsc_package)
55
+
56
+ == Install
57
+
58
+ $ gem install libpcloud
59
+
60
+ == Copyright
61
+
62
+ Copyright (c) 2014 Computology, LLC
63
+
64
+ See LICENSE.txt for details.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit -1
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+
23
+ require 'rubygems/tasks'
24
+ Gem::Tasks.new
25
+
26
+ require 'rspec/core/rake_task'
27
+ RSpec::Core::RakeTask.new
28
+
29
+ task :test => :spec
30
+ task :default => :spec
31
+
32
+ require 'yard'
33
+ YARD::Rake::YardocTask.new
34
+ task :doc => :yard
35
+
36
+ require 'rspec/core/rake_task'
37
+
38
+ desc "Run all specs with rcov"
39
+ RSpec::Core::RakeTask.new("spec:coverage") do |t|
40
+ t.rcov = true
41
+ t.rcov_opts = %w{-Ispec
42
+ --exclude gems\/,spec\/,features\/,seeds\/}
43
+ t.spec_opts = ["-c"]
44
+ end
45
+
@@ -0,0 +1,4 @@
1
+ require 'packagecloud/version'
2
+ require 'packagecloud/client'
3
+ require 'packagecloud/package'
4
+ require 'packagecloud/credentials'
@@ -0,0 +1,219 @@
1
+ require 'json/pure'
2
+ require 'mime'
3
+ require 'excon'
4
+ require 'packagecloud/result'
5
+ require 'packagecloud/connection'
6
+ require 'packagecloud/version'
7
+
8
+ module Packagecloud
9
+ SUPPORTED_EXTENSIONS = ["deb", "rpm", "gem", "dsc"]
10
+
11
+ class UnauthenticatedException < StandardError
12
+ attr_reader :object
13
+
14
+ def initialize(object = nil)
15
+ @object = object
16
+ end
17
+ end
18
+
19
+ class GemOutOfDateException < StandardError
20
+ attr_reader :object
21
+
22
+ def initialize(object = nil)
23
+ @object = object
24
+ end
25
+ end
26
+
27
+ class Client
28
+ attr_reader :connection
29
+ attr_reader :credentials
30
+
31
+ def initialize(credentials, user_agent="default", connection=Connection.new)
32
+ @credentials = credentials
33
+ @connection = connection
34
+ @user_agent = user_agent
35
+
36
+ scheme = self.connection.scheme
37
+ host = self.connection.host
38
+ port = self.connection.port
39
+ token = self.credentials.token
40
+
41
+ @excon = Excon.new("#{scheme}://#{token}@#{host}:#{port}")
42
+ assert_valid_credentials
43
+ assert_compatible_version
44
+ end
45
+
46
+ def distributions
47
+ response = get("/api/v1/distributions.json")
48
+ parsed_json_result(response)
49
+ end
50
+
51
+ def repositories
52
+ response = get("/api/v1/repos.json")
53
+ parsed_json_result(response)
54
+ end
55
+
56
+ def repository(repo)
57
+ response = get("/api/v1/repos/#{username}/#{repo}.json")
58
+ parsed_json_result(response)
59
+ end
60
+
61
+ def gem_version
62
+ response = get("/api/v1/gem_version.json")
63
+ parsed_json_result(response)
64
+ end
65
+
66
+ def create_repository(repo, private=false)
67
+ privacy = private ? 1 : 0
68
+ body = { "repository" => { "name" => repo, "private" => privacy.to_s } }
69
+ response = post("/api/v1/repos.json", body.to_json)
70
+ parsed_json_result(response)
71
+ end
72
+
73
+ def package_contents(repo, package)
74
+ url = "/api/v1/repos/#{username}/#{repo}/packages/contents.json"
75
+
76
+ mixed_msg = MIME::Multipart::FormData.new
77
+
78
+ pkg_data = MIME::Application.new(package.file.read)
79
+ pkg_data.headers.set('Content-Transfer-Encoding', 'binary')
80
+ mixed_msg.add(pkg_data, "package[package_file]", package.filename)
81
+
82
+ response = multipart_post(url, mixed_msg)
83
+
84
+ parsed_json_result(response)
85
+ end
86
+
87
+ def put_package(repo, package)
88
+ url = "/api/v1/repos/#{username}/#{repo}/packages.json"
89
+
90
+ mixed_msg = MIME::Multipart::FormData.new
91
+
92
+ if package.distro_version_id != nil
93
+ mixed_msg.add(MIME::Text.new(package.distro_version_id), "package[distro_version_id]")
94
+ end
95
+
96
+ pkg_data = MIME::Application.new(package.file.read)
97
+ pkg_data.headers.set('Content-Transfer-Encoding', 'binary')
98
+ mixed_msg.add(pkg_data, "package[package_file]", package.filename)
99
+
100
+ package.source_files.each do |filename, io|
101
+ src_pkg_data = MIME::Application.new(io.read)
102
+ src_pkg_data.headers.set('Content-Transfer-Encoding', 'binary')
103
+ mixed_msg.add(src_pkg_data, "package[source_files][]", filename)
104
+ end
105
+
106
+ response = multipart_post(url, mixed_msg)
107
+
108
+ prepare_result(response) { |result| result.response = "" }
109
+ end
110
+
111
+ def find_distribution_id(distro_query)
112
+ distros = distributions
113
+ if distros.succeeded
114
+ deb_distros = distro_map distros.response["deb"]
115
+ rpm_distros = distro_map distros.response["rpm"]
116
+ all_distros = deb_distros.merge(rpm_distros)
117
+ result = all_distros.select { |distro, id| distro.include?(distro_query) }
118
+ if result.size > 1
119
+ keys = result.map { |x| x.first }.join(' ')
120
+ raise ArgumentError, "'#{distro_query}' is ambiguous, did you mean: #{keys}?"
121
+ elsif result.size == 1
122
+ result.first[1] # [["ubuntu/breezy", 1]]
123
+ else
124
+ nil
125
+ end
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def assert_compatible_version
132
+ result = gem_version
133
+ if result.succeeded
134
+ if result.response["minor"] != MINOR_VERSION
135
+ raise GemOutOfDateException.new("This library is out of date, please update it!")
136
+ elsif result.response["patch"].to_i > PATCH_VERSION.to_i
137
+ puts "[WARNING] There's a newer version of the packagecloud-ruby library. Update as soon as possible!"
138
+ end
139
+ elsif result.response.downcase.include?('unauthenticated')
140
+ raise UnauthenticatedException.new
141
+ else
142
+ raise "Unable to get gem version from API: #{result.response}"
143
+ end
144
+ end
145
+
146
+ def assert_valid_credentials
147
+ result = distributions
148
+ if result.succeeded == false && result.response.downcase.include?('unauthenticated')
149
+ raise UnauthenticatedException
150
+ end
151
+ end
152
+
153
+ def distro_map(distros)
154
+ result = {}
155
+ distros.each do |distro|
156
+ name = distro["index_name"]
157
+ distro["versions"].each do |version|
158
+ version_name = version["index_name"]
159
+ key = "#{name}/#{version_name}"
160
+ result[key] = version["id"]
161
+ end
162
+ end
163
+ result
164
+ end
165
+
166
+ def user_agent
167
+ "packagecloud-ruby #{VERSION}/#{@user_agent}"
168
+ end
169
+
170
+ def multipart_post(url, mixed_msg)
171
+ boundary = mixed_msg.boundary
172
+ content_type = "multipart/form-data; boundary=#{boundary}"
173
+ body = mixed_msg.to_s
174
+ post(url, body, content_type)
175
+ end
176
+
177
+ def post(url, body, content_type="application/json")
178
+ request(url, :post, body, content_type)
179
+ end
180
+
181
+ def get(url)
182
+ request(url, :get)
183
+ end
184
+
185
+ def username
186
+ self.credentials.username
187
+ end
188
+
189
+ def request(url, method=:get, body=nil, content_type=nil)
190
+ headers = { "User-Agent" => user_agent }
191
+ if content_type != nil
192
+ headers.merge!({ "Content-Type" => content_type })
193
+ end
194
+ request_params = { :method => method, :path => url, :headers => headers }
195
+ if body != nil
196
+ request_params.merge!({ :body => body })
197
+ end
198
+ @excon.request(request_params)
199
+ end
200
+
201
+ # returns the parsed body of a successful result
202
+ def parsed_json_result(response)
203
+ prepare_result(response) { |result| result.response = JSON.parse(response.data[:body]) }
204
+ end
205
+
206
+ def prepare_result(response)
207
+ result = Result.new
208
+ if response.status == 201 || response.status == 200
209
+ result.succeeded = true
210
+ yield result
211
+ else
212
+ result.response = response.data[:body]
213
+ result.succeeded = false
214
+ end
215
+ result
216
+ end
217
+
218
+ end
219
+ end
@@ -0,0 +1,11 @@
1
+ module Packagecloud
2
+ class Connection
3
+ attr_reader :scheme, :host, :port
4
+
5
+ def initialize(scheme="https", host="packagecloud.io", port="443")
6
+ @scheme = scheme
7
+ @host = host
8
+ @port = port
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Packagecloud
2
+ class Credentials
3
+ attr_reader :username
4
+ attr_reader :token
5
+
6
+ def initialize(username, token)
7
+ @username = username
8
+ @token = token
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ module Packagecloud
2
+ class Package
3
+
4
+ attr_reader :file
5
+ attr_reader :distro_version_id
6
+ attr_accessor :source_files
7
+ attr_reader :filename
8
+
9
+ def initialize(file,
10
+ distro_version_id=nil,
11
+ source_files={},
12
+ filename=rand(2**32).to_s(36))
13
+
14
+ raise ArgumentError, 'file cannot be nil' if file.nil?
15
+ @file = file
16
+ @filename = filename
17
+ @distro_version_id = distro_version_id
18
+ @source_files = source_files
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ module Packagecloud
2
+ class Result
3
+ attr_accessor :response
4
+ attr_accessor :succeeded
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module Packagecloud
2
+ MAJOR_VERSION = "0"
3
+ MINOR_VERSION = "2"
4
+ PATCH_VERSION = "16"
5
+
6
+ VERSION = [MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION].join(".")
7
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/packagecloud/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "packagecloud-ruby"
7
+ gem.version = Packagecloud::VERSION
8
+ gem.summary = "library for interacting with packagecloud.io"
9
+ gem.description = gem.summary
10
+ gem.license = "APL 2.0"
11
+ gem.authors = ["Joe Damato"]
12
+ gem.email = "joe@packagecloud.io"
13
+ gem.homepage = "https://rubygems.org/gems/packagecloud-ruby"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_development_dependency 'bundler', '~> 1.0'
21
+ gem.add_development_dependency 'rake', '~> 0.8'
22
+ gem.add_development_dependency 'rspec', '~> 2.4'
23
+ gem.add_development_dependency 'simplecov', '~> 0.9'
24
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
25
+ gem.add_development_dependency 'yard', '~> 0.8'
26
+ end
Binary file
@@ -0,0 +1,27 @@
1
+ Format: 3.0 (quilt)
2
+ Source: jake
3
+ Binary: jake, jake-doc
4
+ Architecture: i386 amd64 all
5
+ Version: 1.0-7
6
+ Origin: Ubuntu
7
+ Maintainer: jake <joe@packagecloud.io>
8
+ Dm-Upload-Allowed: yes
9
+ Homepage: http://www.chkrootkit.org/
10
+ Standards-Version: 3.9.3
11
+ Vcs-Browser: http://git.debian.org/?p=collab-maint/chkrootkit.git
12
+ Vcs-Git: git://git.debian.org/git/collab-maint/chkrootkit.git
13
+ Build-Depends: pkg-config, quilt
14
+ Build-Depends-Indep: debhelper (>= 2.0.40), gettext, bzip2, cpio
15
+ Build-Conflicts: tk8.0-dev
16
+ Package-List:
17
+ jake deb misc optional
18
+ jake-doc deb doc optional
19
+ Checksums-Sha1:
20
+ 4c054ea8b265d50ee09cac44c9707dbb0ee9a91f 1108 jake_1.0.orig.tar.bz2
21
+ e4749cf9995cd5340a9f23f1656282467e3e105c 1571 jake_1.0-7.debian.tar.gz
22
+ Checksums-Sha256:
23
+ 759cdaf056dc76ba07e5ae7bbd4a452c95aa054d87047cbee0225637ab25d572 1108 jake_1.0.orig.tar.bz2
24
+ be58a87fa814ef56008d0973f60432aec990d427de72e91f84ef0029f0fba46f 1571 jake_1.0-7.debian.tar.gz
25
+ Files:
26
+ a7a309b55424198ee98abcb8092d7be0 1108 jake_1.0.orig.tar.bz2
27
+ 0fa5395e95ddf846b419e96575ce8044 1571 jake_1.0-7.debian.tar.gz
@@ -0,0 +1,81 @@
1
+ require 'webrick'
2
+
3
+ class PackagecloudServer < WEBrick::HTTPServlet::AbstractServlet
4
+ DISTRIBUTIONS = "{\"deb\":[{\"display_name\":\"Ubuntu\",\"index_name\":\"ubuntu\",\"versions\":[{\"id\":3,\"display_name\":\"5.10 Breezy Badger\",\"index_name\":\"breezy\",\"version_number\":\"5.10\"},{\"id\":4,\"display_name\":\"6.06 LTS Dapper Drake\",\"index_name\":\"dapper\",\"version_number\":\"6.06\"},{\"id\":5,\"display_name\":\"6.10 Edgy Eft\",\"index_name\":\"edgy\",\"version_number\":\"6.10\"},{\"id\":6,\"display_name\":\"7.04 Feisty Fawn\",\"index_name\":\"feisty\",\"version_number\":\"7.04\"},{\"id\":7,\"display_name\":\"7.10 Gutsy Gibbon\",\"index_name\":\"gutsy\",\"version_number\":\"7.10\"},{\"id\":8,\"display_name\":\"8.04 LTS Hardy Heron\",\"index_name\":\"hardy\",\"version_number\":\"8.04\"},{\"id\":2,\"display_name\":\"5.04 Hoary Hedgehog\",\"index_name\":\"hoary\",\"version_number\":\"5.04\"},{\"id\":9,\"display_name\":\"8.10 Intrepid Ibex\",\"index_name\":\"intrepid\",\"version_number\":\"8.10\"},{\"id\":10,\"display_name\":\"9.04 Jaunty Jackalope\",\"index_name\":\"jaunty\",\"version_number\":\"9.04\"},{\"id\":11,\"display_name\":\"9.10 Karmic Koala\",\"index_name\":\"karmic\",\"version_number\":\"9.10\"},{\"id\":12,\"display_name\":\"10.04 LTS Lucid Lynx\",\"index_name\":\"lucid\",\"version_number\":\"10.04\"},{\"id\":13,\"display_name\":\"10.10 Maverick Meerkat\",\"index_name\":\"maverick\",\"version_number\":\"10.10\"},{\"id\":14,\"display_name\":\"11.04 Natty Narwhal\",\"index_name\":\"natty\",\"version_number\":\"11.04\"},{\"id\":15,\"display_name\":\"11.10 Oneiric Ocelot\",\"index_name\":\"oneiric\",\"version_number\":\"11.10\"},{\"id\":16,\"display_name\":\"12.04 LTS Precise Pangolin\",\"index_name\":\"precise\",\"version_number\":\"12.04\"},{\"id\":17,\"display_name\":\"12.10 Quantal Quetzal\",\"index_name\":\"quantal\",\"version_number\":\"12.10\"},{\"id\":18,\"display_name\":\"13.04 Raring Ringtail\",\"index_name\":\"raring\",\"version_number\":\"13.04\"},{\"id\":19,\"display_name\":\"13.10 Saucy Salamander\",\"index_name\":\"saucy\",\"version_number\":\"13.10\"},{\"id\":20,\"display_name\":\"14.04 LTS[66] Trusty Tahr\",\"index_name\":\"trusty\",\"version_number\":\"14.04\"},{\"id\":1,\"display_name\":\"4.10 Warty Warthog\",\"index_name\":\"warty\",\"version_number\":\"4.10\"}]},{\"display_name\":\"Debian\",\"index_name\":\"debian\",\"versions\":[{\"id\":21,\"display_name\":\"4.0 etch\",\"index_name\":\"etch\",\"version_number\":\"4.0\"},{\"id\":25,\"display_name\":\"8 jessie\",\"index_name\":\"jessie\",\"version_number\":\"8.0\"},{\"id\":22,\"display_name\":\"5.0 lenny\",\"index_name\":\"lenny\",\"version_number\":\"5.0\"},{\"id\":23,\"display_name\":\"6.0 squeeze\",\"index_name\":\"squeeze\",\"version_number\":\"6.0\"},{\"id\":24,\"display_name\":\"7 wheezy\",\"index_name\":\"wheezy\",\"version_number\":\"7.0\"}]},{\"display_name\":\"Any deb-based distribution.\",\"index_name\":\"any\",\"versions\":[{\"id\":35,\"display_name\":\"Any version.\",\"index_name\":\"any\",\"version_number\":null}]}],\"rpm\":[{\"display_name\":\"Enterprise Linux\",\"index_name\":\"el\",\"versions\":[{\"id\":26,\"display_name\":\"Enterprise Linux 5.0\",\"index_name\":\"5\",\"version_number\":\"5.0\"},{\"id\":27,\"display_name\":\"Enterprise Linux 6.0\",\"index_name\":\"6\",\"version_number\":\"6.0\"},{\"id\":140,\"display_name\":\"Enterprise Linux 7.0\",\"index_name\":\"7\",\"version_number\":\"7.0\"}]},{\"display_name\":\"Fedora\",\"index_name\":\"fedora\",\"versions\":[{\"id\":28,\"display_name\":\"14 Laughlin\",\"index_name\":\"14\",\"version_number\":\"14.0\"},{\"id\":29,\"display_name\":\"15 Lovelock\",\"index_name\":\"15\",\"version_number\":\"15.0\"},{\"id\":30,\"display_name\":\"16 Verne\",\"index_name\":\"16\",\"version_number\":\"16.0\"},{\"id\":31,\"display_name\":\"17 Beefy Miracle\",\"index_name\":\"17\",\"version_number\":\"17.0\"},{\"id\":32,\"display_name\":\"18 Spherical Cow\",\"index_name\":\"18\",\"version_number\":\"18.0\"},{\"id\":33,\"display_name\":\"19 Schrödinger's Cat\",\"index_name\":\"19\",\"version_number\":\"19.0\"},{\"id\":34,\"display_name\":\"20 Heisenbug\",\"index_name\":\"20\",\"version_number\":\"20.0\"}]},{\"display_name\":\"Scientific Linux\",\"index_name\":\"scientific\",\"versions\":[{\"id\":138,\"display_name\":\"Scientific Linux 5.0\",\"index_name\":\"5\",\"version_number\":\"5.0\"},{\"id\":139,\"display_name\":\"Scientific Linux 6.0\",\"index_name\":\"6\",\"version_number\":\"6.0\"}]}],\"dsc\":[{\"display_name\":\"Ubuntu\",\"index_name\":\"ubuntu\",\"versions\":[{\"id\":3,\"display_name\":\"5.10 Breezy Badger\",\"index_name\":\"breezy\",\"version_number\":\"5.10\"},{\"id\":4,\"display_name\":\"6.06 LTS Dapper Drake\",\"index_name\":\"dapper\",\"version_number\":\"6.06\"},{\"id\":5,\"display_name\":\"6.10 Edgy Eft\",\"index_name\":\"edgy\",\"version_number\":\"6.10\"},{\"id\":6,\"display_name\":\"7.04 Feisty Fawn\",\"index_name\":\"feisty\",\"version_number\":\"7.04\"},{\"id\":7,\"display_name\":\"7.10 Gutsy Gibbon\",\"index_name\":\"gutsy\",\"version_number\":\"7.10\"},{\"id\":8,\"display_name\":\"8.04 LTS Hardy Heron\",\"index_name\":\"hardy\",\"version_number\":\"8.04\"},{\"id\":2,\"display_name\":\"5.04 Hoary Hedgehog\",\"index_name\":\"hoary\",\"version_number\":\"5.04\"},{\"id\":9,\"display_name\":\"8.10 Intrepid Ibex\",\"index_name\":\"intrepid\",\"version_number\":\"8.10\"},{\"id\":10,\"display_name\":\"9.04 Jaunty Jackalope\",\"index_name\":\"jaunty\",\"version_number\":\"9.04\"},{\"id\":11,\"display_name\":\"9.10 Karmic Koala\",\"index_name\":\"karmic\",\"version_number\":\"9.10\"},{\"id\":12,\"display_name\":\"10.04 LTS Lucid Lynx\",\"index_name\":\"lucid\",\"version_number\":\"10.04\"},{\"id\":13,\"display_name\":\"10.10 Maverick Meerkat\",\"index_name\":\"maverick\",\"version_number\":\"10.10\"},{\"id\":14,\"display_name\":\"11.04 Natty Narwhal\",\"index_name\":\"natty\",\"version_number\":\"11.04\"},{\"id\":15,\"display_name\":\"11.10 Oneiric Ocelot\",\"index_name\":\"oneiric\",\"version_number\":\"11.10\"},{\"id\":16,\"display_name\":\"12.04 LTS Precise Pangolin\",\"index_name\":\"precise\",\"version_number\":\"12.04\"},{\"id\":17,\"display_name\":\"12.10 Quantal Quetzal\",\"index_name\":\"quantal\",\"version_number\":\"12.10\"},{\"id\":18,\"display_name\":\"13.04 Raring Ringtail\",\"index_name\":\"raring\",\"version_number\":\"13.04\"},{\"id\":19,\"display_name\":\"13.10 Saucy Salamander\",\"index_name\":\"saucy\",\"version_number\":\"13.10\"},{\"id\":20,\"display_name\":\"14.04 LTS[66] Trusty Tahr\",\"index_name\":\"trusty\",\"version_number\":\"14.04\"},{\"id\":1,\"display_name\":\"4.10 Warty Warthog\",\"index_name\":\"warty\",\"version_number\":\"4.10\"}]},{\"display_name\":\"Debian\",\"index_name\":\"debian\",\"versions\":[{\"id\":21,\"display_name\":\"4.0 etch\",\"index_name\":\"etch\",\"version_number\":\"4.0\"},{\"id\":25,\"display_name\":\"8 jessie\",\"index_name\":\"jessie\",\"version_number\":\"8.0\"},{\"id\":22,\"display_name\":\"5.0 lenny\",\"index_name\":\"lenny\",\"version_number\":\"5.0\"},{\"id\":23,\"display_name\":\"6.0 squeeze\",\"index_name\":\"squeeze\",\"version_number\":\"6.0\"},{\"id\":24,\"display_name\":\"7 wheezy\",\"index_name\":\"wheezy\",\"version_number\":\"7.0\"}]},{\"display_name\":\"Any deb-based distribution.\",\"index_name\":\"any\",\"versions\":[{\"id\":35,\"display_name\":\"Any version.\",\"index_name\":\"any\",\"version_number\":null}]}]}"
5
+ PACKAGE_CONTENTS = "{\"files\":[{\"filename\":\"jake_1.0.orig.tar.bz2\",\"size\":1108,\"md5sum\":\"a7a309b55424198ee98abcb8092d7be0\"},{\"filename\":\"jake_1.0-7.debian.tar.gz\",\"size\":1571,\"md5sum\":\"0fa5395e95ddf846b419e96575ce8044\"}]}"
6
+ GEM_VERSION = "{\"major\":\"0\",\"minor\":\"2\",\"patch\":\"1\"}"
7
+ REPO = '{"name": "test_repo","created_at": "2014-08-30T03:51:37.000Z","url": "https://packagecloud.io/joedamato/test_repo","last_push_human": "about 2 months ago","package_count_human": "4 packages","private": true,"fqname": "joedamato/test_repo"}'
8
+ REPOS = "[#{REPO}]"
9
+
10
+ def json_response(request, response, body)
11
+ response.status = 200
12
+ response['Content-Type'] = "application/json"
13
+ response.body = body
14
+ $request, $response = request, response
15
+ end
16
+
17
+ def plain_response(request, response, body)
18
+ response.status = 200
19
+ response['Content-Type'] = "text/plain"
20
+ response.body = body
21
+ $request, $response = request, response
22
+ end
23
+
24
+ def created_response(request, response)
25
+ response.status = 201
26
+ response['Content-Type'] = "text/plain"
27
+ response.body = "{}"
28
+ $request, $response = request, response
29
+ end
30
+
31
+ def default_response(request, response)
32
+ response.status = 404
33
+ response['Content-Type'] = "text/plain"
34
+ response.body = "nope"
35
+ $request, $response = request, response
36
+ end
37
+
38
+ def forbidden_response(request, response)
39
+ response.status = 401
40
+ response['Content-Type'] = "text/plain"
41
+ response.body = "{ 'error': 'unauthenticated' }"
42
+
43
+ $request, $response = request, response
44
+ end
45
+ def route(request, response)
46
+ if request["Authorization"] && request["Authorization"] != "Basic dGVzdF90b2tlbjo="
47
+ return forbidden_response(request, response)
48
+ end
49
+ path = request.path
50
+ case path
51
+ when "/api/v1/distributions.json"
52
+ json_response(request, response, DISTRIBUTIONS)
53
+ when "/api/v1/repos.json"
54
+ if request.request_method == "GET"
55
+ json_response(request, response, REPOS)
56
+ else
57
+ created_response(request, response)
58
+ end
59
+ when "/api/v1/repos/joedamato/test_repo.json"
60
+ json_response(request, response, REPO)
61
+ when "/api/v1/repos/joedamato/test_repo/packages.json"
62
+ created_response(request, response)
63
+ when "/api/v1/repos/joedamato/test_repo/packages/contents.json"
64
+ plain_response(request, response, PACKAGE_CONTENTS)
65
+ when "/api/v1/gem_version.json"
66
+ json_response(request, response, GEM_VERSION)
67
+ else
68
+ default_response(request, response)
69
+ $request, $response = request, response
70
+ end
71
+ end
72
+
73
+ def do_GET(request, response)
74
+ route(request, response)
75
+ end
76
+
77
+ def do_POST(request, response)
78
+ route(request, response)
79
+ end
80
+
81
+ end
@@ -0,0 +1,204 @@
1
+ require 'spec_helper'
2
+ require 'excon'
3
+ require 'packagecloud_server'
4
+ require 'packagecloud'
5
+ require 'webrick'
6
+
7
+ describe Packagecloud do
8
+
9
+ include Packagecloud
10
+
11
+ before(:all) do
12
+ @server = Thread.start do
13
+ server = WEBrick::HTTPServer.new(:Port => 8000)
14
+ server.mount "/", PackagecloudServer
15
+ trap "INT" do
16
+ server.shutdown
17
+ end
18
+ server.start
19
+ end
20
+
21
+ credentials = Credentials.new("joedamato", "test_token")
22
+ connection = Connection.new("http", "localhost", 8000)
23
+
24
+ @client = Client.new(credentials, "test_client", connection)
25
+ end
26
+
27
+ it "should have a VERSION constant" do
28
+ subject.const_get('VERSION').should_not be_empty
29
+ end
30
+
31
+ it "GET api/v1/distributions.json" do
32
+ distros = @client.distributions
33
+ expect(distros.succeeded).to be_truthy
34
+
35
+ deb = distros.response["deb"]
36
+ dsc = distros.response["dsc"]
37
+ rpm = distros.response["rpm"]
38
+
39
+ expect(deb).not_to be_empty
40
+ expect(dsc).not_to be_empty
41
+ expect(rpm).not_to be_empty
42
+ end
43
+
44
+ it "POST debian package /api/v1/repos/joedamato/test_repo/packages.json" do
45
+ deb = File.dirname(__FILE__) + '/fixtures/libampsharp2.0-cil_2.0.4-1_all.deb'
46
+ size = File.size(deb)
47
+ package = Package.new(open(deb), 22)
48
+
49
+ result = @client.put_package("test_repo", package)
50
+ expect(result.succeeded).to be_truthy
51
+
52
+ #assert content type is set correctly
53
+ expect($request.content_type).to include("boundary=")
54
+ expect($request.content_type).to include("multipart/form-data")
55
+
56
+ # assert body is at least bigger than fixture file
57
+ expect($request.content_length > size).to be_truthy
58
+ end
59
+
60
+ it "POST source package /api/v1/repos/joedamato/test_repo/packages.json" do
61
+ dsc = File.dirname(__FILE__) + '/fixtures/natty_dsc/jake_1.0-7.dsc'
62
+ jake_orig = File.dirname(__FILE__) + '/fixtures/natty_dsc/jake_1.0.orig.tar.bz2'
63
+ jake_debian = File.dirname(__FILE__) + '/fixtures/natty_dsc/jake_1.0-7.debian.tar.gz'
64
+
65
+ source_packages = { "jake_1.0.orig.tar.bz2" => open(jake_orig),
66
+ "jake_1.0-7.debian.tar.gz" => open(jake_debian),}
67
+
68
+ dsc_size = File.size(dsc)
69
+ jake_orig_size = File.size(jake_orig)
70
+ jake_debian_size = File.size(jake_debian)
71
+ combined_size = dsc_size + jake_orig_size + jake_debian_size
72
+
73
+ #TODO consider opening IO objects automatically for paths
74
+ package = Package.new(open(dsc), 22, source_packages)
75
+
76
+ result = @client.put_package("test_repo", package)
77
+ expect(result.succeeded).to be_truthy
78
+
79
+ #assert content type is set correctly
80
+ expect($request.content_type).to include("boundary=")
81
+ expect($request.content_type).to include("multipart/form-data")
82
+
83
+ # assert body is at least bigger than fixture file
84
+ expect($request.content_length > combined_size).to be_truthy
85
+ end
86
+
87
+ it "POST /api/v1/repos/joedamato/test_repo/packages/contents.json" do
88
+ dsc = File.dirname(__FILE__) + '/fixtures/natty_dsc/jake_1.0-7.dsc'
89
+ size = File.size(dsc)
90
+ package = Package.new(open(dsc))
91
+
92
+ result = @client.package_contents("test_repo", package)
93
+ expect(result.succeeded).to be_truthy
94
+ expect(result.response["files"]).not_to be_empty
95
+
96
+ #assert content type is set correctly
97
+ expect($request.content_type).to include("boundary=")
98
+ expect($request.content_type).to include("multipart/form-data")
99
+
100
+ # assert body is at least bigger than fixture file
101
+ expect($request.content_length > size).to be_truthy
102
+ end
103
+
104
+ it "GET /api/v1/gem_version.json" do
105
+ result = @client.gem_version
106
+ expect(result.succeeded).to be_truthy
107
+ expect(result.response["major"]).to eq("0")
108
+ expect(result.response["minor"]).to eq("2")
109
+ expect(result.response["patch"]).to eq("1")
110
+ end
111
+
112
+ it "GET /api/v1/repos.json" do
113
+ result = @client.repositories
114
+ expect(result.succeeded).to be_truthy
115
+ expect(result.response[0]["private"]).to be_truthy
116
+ expect(result.response[0]["fqname"]).to eq("joedamato/test_repo")
117
+ expect(result.response[0]["name"]).to eq("test_repo")
118
+ end
119
+
120
+ it "POST /api/v1/repos.json" do
121
+ body = { "repository" => { "name" => "my_repo", "private" => "0" } }.to_json
122
+ result = @client.create_repository("my_repo")
123
+ expect(result.succeeded).to be_truthy
124
+ expect($request.content_type).to include("json")
125
+ expect($request.content_length).to eq(body.size)
126
+ end
127
+
128
+ it "GET /api/v1/repos/joedamato/test_repo.json" do
129
+ result = @client.repository("test_repo")
130
+ expect(result.succeeded).to be_truthy
131
+ expect(result.response["private"]).to be_truthy
132
+ expect(result.response["fqname"]).to eq("joedamato/test_repo")
133
+ expect(result.response["name"]).to eq("test_repo")
134
+ end
135
+
136
+ it "GET /api/v1/repos/joedamato/invalid_repo.json (invalid repo)" do
137
+ result = @client.repository("invalid_repo")
138
+ expect(result.succeeded).to be_falsey
139
+ end
140
+
141
+ it "should have a distinct User-Agent that includes the version" do
142
+ @client.distributions
143
+ expect($request["User-Agent"]).to eq("packagecloud-ruby #{Packagecloud::VERSION}/test_client")
144
+ end
145
+
146
+ it "should raise if api has advanced too far" do
147
+ current = Packagecloud::MINOR_VERSION
148
+ Packagecloud::MINOR_VERSION = "1"
149
+ credentials = Credentials.new("joedamato", "test_token")
150
+ connection = Connection.new("http", "localhost", 8000)
151
+
152
+ expect {
153
+ Client.new(credentials, "test_client", connection)
154
+ }.to raise_error(GemOutOfDateException)
155
+ # Set this back to current
156
+ Packagecloud::MINOR_VERSION = current
157
+ end
158
+
159
+ it "should suggest upgrading if patch version is higher" do
160
+ current = Packagecloud::PATCH_VERSION
161
+ Packagecloud::PATCH_VERSION = "0"
162
+ credentials = Credentials.new("joedamato", "test_token")
163
+ connection = Connection.new("http", "localhost", 8000)
164
+ $stdout.should_receive(:write).with("[WARNING] There's a newer version of the packagecloud-ruby library. Update as soon as possible!")
165
+ $stdout.should_receive(:write).with("\n")
166
+ Client.new(credentials, "test_client", connection)
167
+ # Set this back to current
168
+ Packagecloud::PATCH_VERSION = current
169
+ end
170
+
171
+ it "invalid credentials should raise unauthenticated exception" do
172
+ credentials = Credentials.new("joedamato", "test_tafdfasoken")
173
+ connection = Connection.new("http", "localhost", 8000)
174
+ expect {
175
+ Client.new(credentials, "test_client", connection)
176
+ }.to raise_error(UnauthenticatedException)
177
+ end
178
+
179
+ describe "find_distribution_id" do
180
+
181
+ it "should find ubuntu/breezy" do
182
+ id = @client.find_distribution_id("ubuntu/breezy")
183
+ expect(id).to be(3)
184
+ end
185
+
186
+ it "should find just breezy" do
187
+ id = @client.find_distribution_id("breezy")
188
+ expect(id).to be(3)
189
+ end
190
+
191
+ it "should return nil for invalid distro" do
192
+ id = @client.find_distribution_id("ubuasdalsdntu/breezy")
193
+ expect(id).to be_nil
194
+ end
195
+
196
+ it "should raise for amiguous distro queries" do
197
+ expect {
198
+ @client.find_distribution_id("ubuntu")
199
+ }.to raise_error
200
+ end
201
+ end
202
+
203
+
204
+ end
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ require 'simplecov'
3
+ require 'packagecloud/version'
4
+ SimpleCov.start
5
+
6
+ include Packagecloud
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: packagecloud-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.16
5
+ platform: ruby
6
+ authors:
7
+ - Joe Damato
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubygems-tasks
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
97
+ description: library for interacting with packagecloud.io
98
+ email: joe@packagecloud.io
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - ".document"
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".yardopts"
107
+ - ChangeLog.rdoc
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.rdoc
111
+ - Rakefile
112
+ - lib/packagecloud.rb
113
+ - lib/packagecloud/client.rb
114
+ - lib/packagecloud/connection.rb
115
+ - lib/packagecloud/credentials.rb
116
+ - lib/packagecloud/package.rb
117
+ - lib/packagecloud/result.rb
118
+ - lib/packagecloud/version.rb
119
+ - packagecloud-ruby.gemspec
120
+ - spec/fixtures/chewbacca-1.0.0.gem
121
+ - spec/fixtures/libampsharp2.0-cil_2.0.4-1_all.deb
122
+ - spec/fixtures/natty_dsc/jake_1.0-7.debian.tar.gz
123
+ - spec/fixtures/natty_dsc/jake_1.0-7.dsc
124
+ - spec/fixtures/natty_dsc/jake_1.0.orig.tar.bz2
125
+ - spec/packagecloud_server.rb
126
+ - spec/packagecloud_spec.rb
127
+ - spec/spec_helper.rb
128
+ homepage: https://rubygems.org/gems/packagecloud-ruby
129
+ licenses:
130
+ - APL 2.0
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.4.1
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: library for interacting with packagecloud.io
152
+ test_files:
153
+ - spec/fixtures/chewbacca-1.0.0.gem
154
+ - spec/fixtures/libampsharp2.0-cil_2.0.4-1_all.deb
155
+ - spec/fixtures/natty_dsc/jake_1.0-7.debian.tar.gz
156
+ - spec/fixtures/natty_dsc/jake_1.0-7.dsc
157
+ - spec/fixtures/natty_dsc/jake_1.0.orig.tar.bz2
158
+ - spec/packagecloud_server.rb
159
+ - spec/packagecloud_spec.rb
160
+ - spec/spec_helper.rb