debmirrorapi 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ Debmirror-API
2
+ =============
3
+
4
+ Documentation of methods is done in rspec - simply run `bundle exec rspec -f d` to see supported methods.
5
+
6
+ You can also do `bundle exec rackup -p 9292` and open <http://localhost:9292> in your browser.
7
+
8
+ For a todo list, see [TODO.md](TODO.md)
9
+
10
+ Continously built on ruby 1.8.7 and ruby 1.9.3 on Travis-CI: [![Build Status](https://travis-ci.org/Jimdo/debmirror-api.png?branch=master)](https://travis-ci.org/Jimdo/debmirror-api)
11
+
12
+ ## Contributing
13
+
14
+ 1. Fork it
15
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
16
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
17
+ 4. Push to the branch (`git push origin my-new-feature`)
18
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+
4
+ desc "run specs"
5
+ RSpec::Core::RakeTask.new
6
+
7
+ desc "run api"
8
+ task :run => "Gemfile.lock" do
9
+ require File.join(File.dirname(__FILE__), 'debmirrorapi.rb')
10
+ DebmirrorApi.run!
11
+ end
12
+
13
+ file "Gemfile.lock" => "Gemfile" do
14
+ sh "bundle && touch Gemfile.lock"
15
+ end
data/TODO.md ADDED
@@ -0,0 +1,10 @@
1
+ * split up production/development environment
2
+ * add configuration for hardcoded paths
3
+ * check if stubbing in tests or full repository as fixture in tests is the thing to do
4
+ * for next version
5
+ * add auth for post/patch
6
+ * add post method to create new tags
7
+ * add search
8
+ * add diff method to check changes between tags (maybe in v1 release!)
9
+ * somewhen add method to parse changelog and give you detailed update information
10
+ * more detailed responses, like url of resource, modified date of tage etc.
data/bin/debmirrorapi ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
4
+
5
+ require 'debmirrorapi'
6
+
7
+ DebmirrorApi.run!
data/config.ru ADDED
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require "#{File.dirname(__FILE__)}/debmirrorapi"
4
+ require "#{File.dirname(__FILE__)}/lib/debmirrorapihelpers"
5
+ run DebmirrorApi
@@ -0,0 +1,123 @@
1
+ require 'sinatra'
2
+ require 'sinatra/croon'
3
+ require 'json'
4
+ require 'debmirrorapihelpers'
5
+
6
+ class DebmirrorApi < Sinatra::Base
7
+ register Sinatra::Croon
8
+
9
+ helpers DebMirrorApi::Helpers
10
+
11
+ # GET existing mirrors
12
+ #
13
+ # @request GET /mirrors
14
+ #
15
+ # @response
16
+ # "["deb.theforeman.org/","ftp.uk.debian.org/debian"]"
17
+ get '/mirrors' do
18
+ content_type :json
19
+ if mirror_list
20
+ mirror_list.to_json
21
+ else
22
+ body "file not found ('/var/lib/debmirror/mirror.index')".to_json
23
+ status 500
24
+ end
25
+ end
26
+
27
+ # GET existing dists
28
+ #
29
+ # @request GET /dists/<mirror>
30
+ # @request GET /dists/ftp.uk.debian.org/debian
31
+ #
32
+ # @response
33
+ # "[\"squeeze\",\"wheezy\",\"sid\"]"
34
+ get '/dists/*' do
35
+ content_type :json
36
+ requested_mirror = params[:splat][0]
37
+ if mirror_list.include?(requested_mirror)
38
+ dists_dir = File.join("/var/lib/debmirror/", requested_mirror, "dists")
39
+ File.directory?(dists_dir) ? ((Dir.entries dists_dir).delete_if { |dist| dist == '.' || dist == '..' || File.symlink?(File.join(dists_dir, dist)) }).to_json : 404
40
+ else
41
+ 405
42
+ end
43
+ end
44
+
45
+ # GET tags of a dist
46
+ #
47
+ # @request GET /tags/repo.percona.com/apt/dist/squeeze
48
+ #
49
+ # @response
50
+ # "{\"prod\":\"0\",\"prod-unstaged\":\"0\",\"dev\":\"5\",\"stable\":\"0\",\"latest\":\"17\"}"
51
+ get '/tags/*/dist/*' do
52
+ content_type :json
53
+ requested_mirror = params[:splat][0]
54
+ requested_dist = params[:splat][1]
55
+ if mirror_list.include?(requested_mirror) and requested_dist !=~ /\/..\//
56
+ tag_dir = File.join("/var/lib/debmirror/", requested_mirror, "dists", requested_dist)
57
+ response = {}
58
+ if File.directory?(tag_dir)
59
+ links = ((Dir.entries tag_dir).delete_if { |tag| tag == '.' || tag == '..' || !File.symlink?(File.join(tag_dir, tag)) })
60
+ links.each do |link|
61
+ response[link] = File.readlink(File.join(tag_dir,link))
62
+ end
63
+ response.to_json
64
+ else
65
+ 404
66
+ end
67
+ else
68
+ 405
69
+ end
70
+ end
71
+
72
+ # PATCH tags of a dist to version
73
+ #
74
+ # @request PATCH /tag/repo.percona.com/apt/dist/squeeze/stable
75
+ # version=4
76
+ #
77
+ # @response
78
+ # "{\"prod\":\"0\",\"prod-unstaged\":\"0\",\"dev\":\"5\",\"stable\":\"4\",\"latest\":\"17\"}"
79
+ patch '/tag/*/dist/*/*' do
80
+ content_type :json
81
+ requested_mirror = params[:splat][0]
82
+ requested_dist = params[:splat][1]
83
+ requested_tag = params[:splat][2]
84
+ if params['version'] =~ /\d+/
85
+ requested_tag_version = params['version']
86
+ else
87
+ body 'missing version in patch data'.to_json
88
+ halt 400
89
+ end
90
+ requested_tag_file = File.join("/var/lib/debmirror/", requested_mirror, "dists", requested_dist, requested_tag)
91
+ tag_dir = File.join("/var/lib/debmirror/", requested_mirror, "dists", requested_dist)
92
+ if mirror_list.include?(requested_mirror) and requested_dist !=~ /\/..\// and File.symlink?(requested_tag_file)
93
+ requested_tag_version_file = File.join("/var/lib/debmirror/", requested_mirror, "dists", requested_dist, requested_tag_version)
94
+ if File.exists?(requested_tag_version_file) and not File.symlink?(requested_tag_version_file)
95
+ File.link(requested_tag_version_file, requested_tag_file)
96
+ response = {}
97
+ links = ((Dir.entries tag_dir).delete_if { |tag| tag == '.' || tag == '..' || !File.symlink?(File.join(tag_dir, tag)) })
98
+ links.each do |link|
99
+ response[link] = File.readlink(File.join(tag_dir,link))
100
+ end
101
+ response.to_json
102
+ else
103
+ halt 405
104
+ end
105
+ else
106
+ 404
107
+ end
108
+ end
109
+
110
+
111
+ # GET something that is not yet implemented
112
+ # @request GET /blubbi
113
+ #
114
+ # @response
115
+ # "{\"method not implemented\"}"
116
+ # status 501
117
+ get '/*' do
118
+ content_type :json
119
+ body 'method not implemented'.to_json
120
+ status 501
121
+ end
122
+
123
+ end
@@ -0,0 +1,19 @@
1
+ module DebMirrorApi
2
+ module Helpers
3
+
4
+ def mirror_list
5
+ if File.file?('/var/lib/debmirror/mirror.index')
6
+ list = []
7
+ File.readlines('/var/lib/debmirror/mirror.index').each do |mirror|
8
+ list.push(mirror.chomp())
9
+ end
10
+ list
11
+ else
12
+ false
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+
data/spec/api_spec.rb ADDED
@@ -0,0 +1,225 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Debmirror-API" do
4
+
5
+ context "mirrors" do
6
+
7
+ it "should respond to GET /mirrors" do
8
+ app.class_eval { helpers {
9
+ def mirror_list;
10
+ return ["deb.theforeman.org/", "ftp.uk.debian.org/debian", "archive.debian.org/debian-archive/debian", "repo.percona.com/apt"];
11
+ end } }
12
+ get '/mirrors'
13
+ last_response.should be_ok
14
+ last_response.status.should == 200
15
+ last_response.content_type.should eq('application/json;charset=utf-8')
16
+ parsed_body = JSON.parse(last_response.body)
17
+ parsed_body.should include('deb.theforeman.org/', 'ftp.uk.debian.org/debian')
18
+ end
19
+
20
+ it "should respond with empty set if mirror.index is empty to GET /mirrors" do
21
+ app.class_eval { helpers {
22
+ def mirror_list;
23
+ return [];
24
+ end } }
25
+ get '/mirrors'
26
+ last_response.should be_ok
27
+ last_response.status.should == 200
28
+ last_response.content_type.should eq('application/json;charset=utf-8')
29
+ last_response.body.should eq([].to_json)
30
+ end
31
+
32
+ it "should respond with an internal server error if mirror.index is missing" do
33
+ app.class_eval { helpers {
34
+ def mirror_list;
35
+ return false;
36
+ end } }
37
+ get '/mirrors'
38
+ last_response.should_not be_ok
39
+ last_response.status.should == 500
40
+ last_response.content_type.should eq('application/json;charset=utf-8')
41
+ last_response.body.should eq("file not found ('/var/lib/debmirror/mirror.index')".to_json)
42
+ end
43
+
44
+ end
45
+
46
+ context "dists" do
47
+
48
+ before (:each) do
49
+ app.class_eval {
50
+ helpers {
51
+ def mirror_list;
52
+ return ["deb.theforeman.org/", "ftp.uk.debian.org/debian", "archive.debian.org/debian-archive/debian", "repo.percona.com/apt"];
53
+ end
54
+ }
55
+ }
56
+ end
57
+
58
+ it "should respond to GET /dists/deb.theforeman.org/" do
59
+ Dir.stub(:entries).with('/var/lib/debmirror/deb.theforeman.org/dists') { [".", "..", "stable"] }
60
+ File.stub(:directory?).with('/var/lib/debmirror/deb.theforeman.org/dists') { true }
61
+ get '/dists/deb.theforeman.org/'
62
+ last_response.should be_ok
63
+ last_response.content_type.should eq('application/json;charset=utf-8')
64
+ last_response.should match(['stable'].to_json)
65
+ end
66
+
67
+ it "should respond to GET /dists/ftp.uk.debian.org/debian" do
68
+ Dir.stub(:entries).with('/var/lib/debmirror/ftp.uk.debian.org/debian/dists') { [".", "..", "squeeze", "wheezy", "sid", "unstable", "stable", "testing"] }
69
+ File.stub(:directory?).with('/var/lib/debmirror/ftp.uk.debian.org/debian/dists') { true }
70
+ File.stub(:symlink?) { false }
71
+ File.stub(:symlink?).with(%r{^/var/lib/debmirror/ftp.uk.debian.org/debian/dists/(unstable|testing|stable)$}) { true }
72
+ get '/dists/ftp.uk.debian.org/debian'
73
+ last_response.should be_ok
74
+ last_response.content_type.should eq('application/json;charset=utf-8')
75
+ last_response.body.should eq(['squeeze', 'wheezy', 'sid'].to_json)
76
+ end
77
+
78
+ it "should respond to GET /dists/archive.debian.org/debian-archive/debian" do
79
+ Dir.stub(:entries).with('/var/lib/debmirror/archive.debian.org/debian-archive/debian/dists') { [".", "..", "lenny", "oldstable"] }
80
+ File.stub(:directory?).with('/var/lib/debmirror/archive.debian.org/debian-archive/debian/dists') { true }
81
+ File.stub(:symlink?) { false }
82
+ File.stub(:symlink?).with('/var/lib/debmirror/archive.debian.org/debian-archive/debian/dists/oldstable') { true }
83
+ get '/dists/archive.debian.org/debian-archive/debian'
84
+ last_response.should be_ok
85
+ last_response.content_type.should eq('application/json;charset=utf-8')
86
+ last_response.body.should eq(['lenny'].to_json)
87
+ end
88
+
89
+ it "should send 405 to GET /dists/some.host.that.does.not.exist/" do
90
+ get '/dists/some.host.that.does.not.exist/'
91
+ last_response.status.should == 405
92
+ end
93
+
94
+ end
95
+
96
+ context "tags" do
97
+
98
+ before (:each) do
99
+ app.class_eval {
100
+ helpers {
101
+ def mirror_list;
102
+ return ["deb.theforeman.org/", "ftp.uk.debian.org/debian", "archive.debian.org/debian-archive/debian", "repo.percona.com/apt"];
103
+ end
104
+ }
105
+ }
106
+ File.stub(:directory?).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze') { true }
107
+ Dir.stub(:entries).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze') { [".", "..", "0", "main", "1", "prod", "prod-unstaged", "dev", "stable", "2", "latest", "3", "4", "11", "Release", "5", "6", "15", "Release.gpg", "7", "8", "9", "10", "12", "13", "14", "16", "17"] }
108
+ File.stub(:symlink?) { false }
109
+ File.stub(:symlink?).with(%r{^/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/(latest|dev|stable|prod|prod-unstaged)$}) { true }
110
+ File.stub(:readlink) { "0" }
111
+ File.stub(:readlink).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/latest') { "17" }
112
+ File.stub(:readlink).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/dev') { "5" }
113
+ end
114
+
115
+ it "should respond to GET /tags/repo.percona.com/apt/dists/squeeze" do
116
+ get '/tags/repo.percona.com/apt/dist/squeeze'
117
+ last_response.should be_ok
118
+ last_response.content_type.should eq('application/json;charset=utf-8')
119
+ parsed_body = JSON.parse(last_response.body)
120
+ parsed_body.should eql({'dev' => '5', 'latest' => '17', 'prod' => '0', 'prod-unstaged' => '0', 'stable' => '0'})
121
+ end
122
+
123
+ #we don't need to test this, it is fixed in framework, see https://groups.google.com/forum/#!msg/sinatrarb/6Vp3JQd-vzM/LjGsFVspjScJ
124
+ it "should respond with a method not allowed error to GET /tags/repo.percona.com/apt/dists/../../../../../etc/passwd" do
125
+ get '/tags/repo.percona.com/apt/dist/../../../../../etc/passwd'
126
+ #last_response.should_not be_ok
127
+ #last_response.status.should == 405
128
+ end
129
+
130
+ it "should respond with a 404 to a not existing tag (e.g. GET /tags/repo.percona.com/apt/dists/toystory)" do
131
+ File.stub(:directory?).with('/var/lib/debmirror/repo.percona.com/apt/dists/toystory') { false }
132
+ get '/tags/repo.percona.com/apt/dist/toystory'
133
+ last_response.should_not be_ok
134
+ last_response.status.should == 404
135
+ end
136
+
137
+ it "should respond with method not allowed to a not existing repo (e.g. GET /tags/bullshitrepo/dists/stable" do
138
+ get '/tags/bullshitrepo/dist/stable'
139
+ last_response.should_not be_ok
140
+ last_response.status.should == 405
141
+ end
142
+
143
+ end
144
+
145
+ context "update tag" do
146
+
147
+ before (:each) do
148
+ app.class_eval {
149
+ helpers {
150
+ def mirror_list;
151
+ return ["deb.theforeman.org/", "ftp.uk.debian.org/debian", "archive.debian.org/debian-archive/debian", "repo.percona.com/apt"];
152
+ end
153
+ }
154
+ }
155
+ File.stub(:directory?).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze') { true }
156
+ Dir.stub(:entries).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze') { [".", "..", "0", "main", "1", "prod", "prod-unstaged", "dev", "stable", "2", "latest", "3", "4", "11", "Release", "5", "6", "15", "Release.gpg", "7", "8", "9", "10", "12", "13", "14", "16", "17"] }
157
+ File.stub(:symlink?) { false }
158
+ File.stub(:symlink?).with(%r{^/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/(latest|dev|stable|prod|prod-unstaged)$}) { true }
159
+ File.stub(:symlink?).with(%r{^/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/\d+$}) { false }
160
+ File.stub(:exists?).with(%r{^/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/\d+$}) { true }
161
+ File.stub(:readlink) { "0" }
162
+ File.stub(:readlink).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/latest') { "17" }
163
+ File.stub(:readlink).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/dev') { "5" }
164
+ File.stub(:link).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/4','/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/stable') { 0 }
165
+ File.stub(:readlink).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/stable') { "4" }
166
+
167
+ end
168
+
169
+ it "should update a tag to a defined version (e.g. PATCH /tags/repo.percona.com/apt/dists/squeeze/stable" do
170
+ patch '/tag/repo.percona.com/apt/dist/squeeze/stable', :version => 4
171
+ last_response.should be_ok
172
+ last_response.status.should == 200
173
+ parsed_body = JSON.parse(last_response.body)
174
+ parsed_body.should eql({'dev' => '5', 'latest' => '17', 'prod' => '0', 'prod-unstaged' => '0', 'stable' => '4'})
175
+ end
176
+
177
+ it "should respond with method not allowed if version does not exist" do
178
+ File.stub(:exists?).with('/var/lib/debmirror/repo.percona.com/apt/dists/squeeze/20') { false }
179
+ patch '/tag/repo.percona.com/apt/dist/squeeze/stable', :version => 20
180
+ last_response.should_not be_ok
181
+ last_response.status.should == 405
182
+ end
183
+
184
+ it "should respond with 404 if release_tag is not a valid tag" do
185
+ patch '/tag/repo.percona.com/apt/dist/squeeze/bullshit', :version => 4
186
+ last_response.should_not be_ok
187
+ last_response.status.should == 404
188
+ end
189
+
190
+ it "should respond with 404 if mirror does not exist" do
191
+ patch '/tag/bullshitrepo/dist/squeeze/stable', :version => 4
192
+ last_response.should_not be_ok
193
+ last_response.status.should == 404
194
+ end
195
+
196
+ it "should respond with 400 if version is empty" do
197
+ patch '/tag/repo.percona.com/apt/dist/squeeze/stable'
198
+ last_response.should_not be_ok
199
+ last_response.status.should == 400
200
+ last_response.body.should eq('missing version in patch data'.to_json)
201
+ end
202
+
203
+ end
204
+
205
+ context "request not implemented resource" do
206
+ it "should return not implemented httpcode and message" do
207
+ get '/something'
208
+ last_response.should_not be_ok
209
+ last_response.content_type.should eq('application/json;charset=utf-8')
210
+ last_response.body.should eq('method not implemented'.to_json)
211
+ last_response.status.should == 501
212
+ end
213
+ end
214
+
215
+ context "croon should generate valid documentation" do
216
+ it "should return readable documentation" do
217
+ get '/docs'
218
+ last_response.should be_ok
219
+ last_response.content_type.should eq('text/html;charset=utf-8')
220
+ last_response.body.should =~ /API Documentation/
221
+ last_response.status.should == 200
222
+ end
223
+ end
224
+
225
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ class Helper
4
+ include DebMirrorApi::Helpers
5
+ end
6
+
7
+ describe "DebmirrorApi::Helpers" do
8
+
9
+ before(:all) do
10
+ @helper = Helper.new
11
+
12
+ @mirror_index = File.readlines('spec/fixtures/mirror.index')
13
+ end
14
+
15
+ it "should return a mirror list" do
16
+ File.stub(:file?).with('/var/lib/debmirror/mirror.index') { true }
17
+ File.stub(:readlines).with('/var/lib/debmirror/mirror.index') { @mirror_index }
18
+ @helper.mirror_list.include?("repo.percona.com/apt/debian/dists/squeeze").should == true
19
+ @helper.mirror_list.include?("ftp.uk.debian.org/debian").should == true
20
+ @helper.mirror_list.include?("apt.newrelic.com/debian").should == true
21
+ end
22
+
23
+ it "should return false if no mirror.index is present" do
24
+ File.stub(:file?).with('/var/lib/debmirror/mirror.index') { false }
25
+ @helper.mirror_list.should == false
26
+ end
27
+
28
+ it "should return empty list if no lines present in mirror.index" do
29
+ File.stub(:file?).with('/var/lib/debmirror/mirror.index') { true }
30
+ File.stub(:readlines).with('/var/lib/debmirror/mirror.index') { [] }
31
+ @helper.mirror_list.should eql([])
32
+ end
33
+
34
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: debmirrorapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Lars Fronius
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sinatra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sinatra-croon
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: json
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec-mocks
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rack-test
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: ! 'API to provide an interface to debmirror.
127
+
128
+ It provides methods like get mirrors, dists, tags of your mirror and update already
129
+ created tags.
130
+
131
+ '
132
+ email: l.fronius@googlemail.com
133
+ executables:
134
+ - debmirrorapi
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - README.md
139
+ - Rakefile
140
+ - TODO.md
141
+ - bin/debmirrorapi
142
+ - lib/debmirrorapi.rb
143
+ - lib/debmirrorapihelpers.rb
144
+ - config.ru
145
+ - spec/api_spec.rb
146
+ - spec/debmirrorapihelpers_spec.rb
147
+ homepage: http://github.com/Jimdo/debmirror-api
148
+ licenses: []
149
+ post_install_message:
150
+ rdoc_options: []
151
+ require_paths:
152
+ - lib
153
+ required_ruby_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubyforge_project:
167
+ rubygems_version: 1.8.23
168
+ signing_key:
169
+ specification_version: 3
170
+ summary: Simple API to provide an interface to debmirror.
171
+ test_files:
172
+ - spec/api_spec.rb
173
+ - spec/debmirrorapihelpers_spec.rb