debmirrorapi 0.1.2

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.
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