frm 0.0.1 → 0.0.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/.gitignore CHANGED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ Copyright (c) 2012, Martin K. Rhoads and FRM Project Contributors.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ * Neither the name of the FRM Project, Martin K. Rhoads, nor the names
16
+ of its contributors may be used to endorse or promote products
17
+ derived from this software without specific prior written
18
+ permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile CHANGED
@@ -1,2 +1,21 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ fpm_base = File.dirname __FILE__
5
+
6
+ namespace :bump do
7
+
8
+ desc "bump the patch version number"
9
+ task :patch do
10
+ version_file_path = File.join fpm_base, 'lib', 'frm', 'version.rb'
11
+ current_version_file = File.read version_file_path
12
+ current_version_file =~ /VERSION[^\d]+(\d+)\.(\d+)\.(\d+)(\.([^'"]*))?/
13
+ major,minor,patch = $1, $2, $3
14
+ new_version = [$1,$2,$3.to_i+1].join('.')
15
+ new_version_file = current_version_file.sub /VERSION\s*=.*/, %Q{VERSION = "#{new_version}"}
16
+ File.open(version_file_path, 'w') {|f| f.write(new_version_file) }
17
+ puts "bumping version to #{new_version}"
18
+ end
19
+
20
+ end
21
+
data/bin/fpm ADDED
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env ruby
2
+ # This is the CLI interface into Effin Repo Manager
3
+
4
+ require 'optparse'
5
+
6
+ # This hash will hold all of the options
7
+ # parsed from the command-line by
8
+ # OptionParser.
9
+ options = {}
10
+
11
+ packages = []
12
+
13
+ def print_and_exit(message)
14
+ puts
15
+ puts message
16
+ puts
17
+ puts `#{__FILE__} -h`
18
+ exit 1
19
+ end
20
+
21
+ optparse = OptionParser.new do|opts|
22
+ opts.banner = "Usage: frm.rb [options] package1 [package2]B ..."
23
+
24
+ options[:access_key] = nil
25
+ opts.on( '-a', '--access-key ACCESS_KEY', 'S3 public access key' ) do |key|
26
+ options[:access_key] = key
27
+ end
28
+
29
+
30
+ options[:secret_key] = nil
31
+ opts.on( '-s', '--secret-key SECRET_KEY', 'S3 private access key' ) do |key|
32
+ options[:secret_key] = key
33
+ end
34
+
35
+ options[:bucket] = nil
36
+ opts.on( '-b', '--bucket BUCKET', 'S3 bucket' ) do |bucket|
37
+ options[:bucket] = bucket
38
+ end
39
+
40
+ options[:prefix] = nil
41
+ opts.on( '-p', '--prefix PREFIX', 'S3 prefix of repostory' ) do |prefix|
42
+ options[:prefix] = prefix
43
+ end
44
+
45
+
46
+ # This displays the help screen, all programs are
47
+ # assumed to have this option.
48
+ opts.on( '-h', '--help', 'Display this screen' ) do
49
+ puts opts
50
+ exit
51
+ end
52
+ end
53
+
54
+ optparse.parse!
55
+
56
+
57
+ ARGV.each do |package|
58
+ packages << package
59
+ end
60
+
61
+
62
+ # verify that the required inputs are set
63
+ %w{access_key secret_key bucket prefix }.each do |input|
64
+ print_and_exit "you must specify the #{input} parameter!!!" if options.values_at(input.to_sym) == [nil]
65
+ end
66
+
67
+ # verify that we have at least one package to install
68
+ print_and_exit "you need to specify at least one package to publish!!!" if packages.empty?
69
+
70
+ packages.each do |package|
71
+ print_and_exit "package '#{package}' does not exits!!!" unless File.exists?(package)
72
+ print_and_exit "package '#{package}' does not appear to be a valid deb" unless system("dpkg --field #{package} > /dev/null 2>&1 ")
73
+ end
74
+
75
+
76
+ # if we have gotten this far it means that all required parameters have been set, so let's begin
77
+
78
+
79
+ # chdir to the top level of the code
80
+ Dir.chdir(File.dirname(File.dirname(__FILE__)))
81
+
82
+ # require the necessary FRM libs
83
+ require File.join Dir.pwd, 'lib', 'deb'
84
+
85
+ puts "creating release..."
86
+ package_release = FRM::PackageRelease.new(packages)
87
+
88
+ puts "pushing release..."
89
+ release_pusher = FRM::ReleasePusher.new(package_release,options[:access_key],options[:secret_key],options[:bucket],options[:prefix])
90
+
91
+ puts "looks like everything ran ok!"
data/lib/frm/deb.rb ADDED
@@ -0,0 +1,327 @@
1
+ DEFAULT_HOST = 's3-us-west-1.amazonaws.com' # stupid hack to point to
2
+ # the right region
3
+
4
+ module FRM
5
+
6
+
7
+ class Base
8
+ my_dir = File.dirname __FILE__
9
+ require File.join my_dir, 's3'
10
+ require 'zlib'
11
+ require 'tempfile'
12
+ require 'digest/md5'
13
+ require 'digest/sha1'
14
+ require 'digest/sha2'
15
+
16
+ def compute_md5(string)
17
+ Digest::MD5.hexdigest(string)
18
+ end
19
+
20
+ def compute_sha1(string)
21
+ Digest::SHA1.hexdigest(string)
22
+ end
23
+
24
+ def compute_sha2(string)
25
+ Digest::SHA2.hexdigest(string)
26
+ end
27
+
28
+ # TODO:
29
+ # there has to be a better way to use gpg withen ruby. found many
30
+ # broken solutions :\
31
+ def gpg_clearsign(message)
32
+ `echo "#{message}" | gpg --clearsign`
33
+ end
34
+
35
+ # TODO: same as above
36
+ def gpg_detached(message)
37
+ `echo "#{message}" | gpg -abs`
38
+ end
39
+
40
+
41
+ def generate_gzip_pipe(contents)
42
+ read_buffer, write_buffer = IO.pipe
43
+ gzip_writer = Zlib::GzipWriter.new write_buffer
44
+ gzip_writer.mtime = 1 # ensure that the header is determinstic
45
+ gzip_writer.write contents
46
+ gzip_writer.close
47
+ read_buffer
48
+ end
49
+
50
+ def gunzip_pipe(gziped_pipe)
51
+ gzip_reader = Zlib::GzipReader.new gziped_pipe
52
+ unzipped_string = gzip_reader.read
53
+ gzip_reader.close
54
+ return unzipped_string
55
+ end
56
+
57
+ def parse_package_stub(read_buffer)
58
+ package = {}
59
+ stub = ""
60
+ while line = read_buffer.gets
61
+ return nil if line.strip.empty?
62
+ raise "bad input" unless (match = line.match /^\w+\-?\w+?: /)
63
+ stub << line
64
+ key = match[0].delete ': ' # if match
65
+ value = match.post_match.strip
66
+ package[key] = value
67
+ if key == 'Description'
68
+ while (line = read_buffer.gets).strip != ""
69
+ package['Description'] << line
70
+ stub << line
71
+ end
72
+ package['Description'].rstrip!
73
+ return package, stub
74
+ end
75
+ end
76
+ nil
77
+ end
78
+
79
+ def merge_package_file(in_pipe,out_pipe,package_list)
80
+ sorted_list = package_list.sort { |a,b| a['Package'] <=> b['Package'] }
81
+ while (next_stub = parse_package_stub in_pipe)
82
+ STDERR.puts "next_stub[0] = #{next_stub[0]}"
83
+ end
84
+ end
85
+ end
86
+
87
+
88
+ class Package < Base
89
+ attr_accessor :repo_filename
90
+ attr_reader :path, :content, :md5, :sha1, :sha2 , :size
91
+ def initialize(path)
92
+ @path = path
93
+ raise "Can not find file '#{path}'" unless File.exists?(path)
94
+ begin
95
+ @content = File.read(path)
96
+ rescue Object => o
97
+ STDERR.puts "Could not open file '#{path}'. Exiting..."
98
+ STDERR.puts o.inspect
99
+ STDERR.puts o.backtrace
100
+ raise "Could not open file '#{path}'. Exiting..."
101
+ end
102
+ @size = File.size(@path)
103
+ @md5 = compute_md5(@content)
104
+ @sha1 = compute_sha1(@content)
105
+ @sha2 = compute_sha2(@content)
106
+ end
107
+ end
108
+
109
+ class PackageRelease < Base
110
+ attr_reader :packages, :standards_version, :priority, :package_file, :gzipped_package_file, :release_file, :short_release_file, :component
111
+ def initialize(packages={},component='main/binary-amd64')
112
+ @component = component
113
+ @standards_version = standards_version
114
+ @priority = priority
115
+ @packages = []
116
+ packages.each { |package| @packages << Package.new(package) }
117
+ @package_file = generate_package_file
118
+ @gzipped_package_file = generate_gzip_pipe(@package_file).read
119
+ @short_release_file = generate_short_release_file
120
+ @release_file = generate_release_file
121
+ end
122
+
123
+ private
124
+
125
+ def generate_release_file()
126
+ partial_release_file = "Origin: apt.cloudscaling.com
127
+ Label: apt repository natty
128
+ Codename: natty
129
+ Date: Thu, 22 Dec 2011 00:29:55 UTC
130
+ Architectures: amd64
131
+ Components: main universe multiverse
132
+ Description: Cloudscaling APT repository
133
+ MD5Sum:
134
+ #{compute_md5(@package_file)} #{@package_file.size} #{@component}/Packages
135
+ #{compute_md5(@gzipped_package_file)} #{@gzipped_package_file.size} #{@component}/Packages.gz
136
+ #{compute_md5(@short_release_file)} #{@short_release_file.size} #{@component}/Release
137
+ SHA1:
138
+ #{compute_sha1(@package_file)} #{@package_file.size} #{@component}/Packages
139
+ #{compute_sha1(@gzipped_package_file)} #{@gzipped_package_file.size} #{@component}/Packages.gz
140
+ #{compute_sha1(@short_release_file)} #{@short_release_file.size} #{@component}/Release
141
+ SHA256:
142
+ #{compute_sha2(@package_file)} #{@package_file.size} #{@component}/Packages
143
+ #{compute_sha2(@gzipped_package_file)} #{@gzipped_package_file.size} #{@component}/Packages.gz
144
+ #{compute_sha2(@short_release_file)} #{@short_release_file.size} #{@component}/Release
145
+ "
146
+ return partial_release_file
147
+ end
148
+
149
+ def generate_short_release_file
150
+ "Component: main
151
+ Origin: apt.cloudscaling.com
152
+ Label: apt repository natty
153
+ Architecture: amd64
154
+ Description: Cloudscaling APT repository
155
+ "
156
+ end
157
+
158
+
159
+ def filename(package)
160
+ filename = File.basename package.path
161
+ shortname = `dpkg --field #{package.path} Package`.chomp
162
+ first_letter = shortname[0]
163
+ package.repo_filename = "pool/main/#{first_letter}/#{shortname}/#{filename}"
164
+ end
165
+
166
+ def generate_package_file()
167
+ package_file = ''
168
+ @packages.each { |package| package_file << generate_package_stub(package) }
169
+ return package_file
170
+ end
171
+
172
+ def generate_package_stub(package)
173
+ package_stub = ''
174
+ package_stub << `dpkg --field #{package.path}`
175
+ package_stub << "Filename: #{filename(package)}\n"
176
+ package_stub << "Size: #{package.size}\n"
177
+ package_stub << "MD5sum: #{package.md5}\n"
178
+ package_stub << "SHA1: #{package.sha1}\n"
179
+ package_stub << "SHA256: #{package.sha2}\n"
180
+ package_stub << "\n"
181
+ return package_stub
182
+ end
183
+ end
184
+
185
+ class ReleasePusher < Base
186
+ def initialize(package_release,access_key,secret_key,bucket,prefix,server='s3-us-west-1.amazonaws.com')
187
+ @bucket = bucket
188
+ @prefix = prefix
189
+ @s3 = FRM::S3.new(access_key,secret_key,server)
190
+ push_packages(package_release.packages)
191
+ push_release_files(package_release)
192
+ end
193
+
194
+ private
195
+
196
+
197
+ def push_release_files(package_release)
198
+ # TODO: un-hardcode this
199
+ release_path = @prefix + "/dists/natty/Release"
200
+ @s3.put(release_path,package_release.release_file,@bucket)
201
+
202
+ in_release_path = @prefix + "/dists/natty/InRelease"
203
+ @s3.put(in_release_path,gpg_clearsign(package_release.release_file),@bucket)
204
+
205
+ gpg_release_path = @prefix + "/dists/natty/Release.gpg"
206
+ @s3.put(gpg_release_path,gpg_detached(package_release.release_file),@bucket)
207
+
208
+ release_file_path = @prefix + "/dists/natty/" + package_release.component
209
+ @s3.put(release_file_path + '/Release',package_release.short_release_file,@bucket)
210
+ @s3.put(release_file_path + '/Packages',package_release.package_file,@bucket)
211
+ @s3.put(release_file_path + '/Packages.gz',package_release.gzipped_package_file,@bucket)
212
+ end
213
+
214
+
215
+ def push_packages(packages)
216
+ packages.each { |package| push_package(package) }
217
+ end
218
+
219
+ def push_package(package)
220
+ remote_path = @prefix + '/' + package.repo_filename
221
+ @s3.put(remote_path,package.content,@bucket)
222
+ end
223
+
224
+
225
+ end
226
+
227
+
228
+
229
+ class Deb < Base
230
+
231
+ def initialize()
232
+ end
233
+
234
+ def generate_package_file(in_packages=[])
235
+ packages = in_packages.dup
236
+ package_file = ''
237
+ packages.each { |package| package_file << generate_package_stub(package) }
238
+ return package_file
239
+ end
240
+
241
+
242
+ def generate_package_stub(in_package={})
243
+ package = in_package.dup
244
+ package_stub = ''
245
+ description = package.delete('Description') || "no description given"
246
+ path_to_deb = package.delete 'path_to_deb'
247
+ section = package.delete 'section'
248
+ package["Filename"] = "pool/#{section}/#{package['Package'][0]}/#{package['Package']}/#{package['Package']}_#{package['Version']}_#{package['Architecture']}.deb"
249
+ package["Size"] = File.new(path_to_deb).size
250
+ package["MD5sum"] = self.compute_md5 File.read path_to_deb
251
+ package["SHA1"] = compute_sha1 File.read path_to_deb
252
+ package["SHA256"] = compute_sha2 File.read path_to_deb
253
+ package["Description"] = description
254
+ package.each { |key,value| package_stub << generate_package_line(key,value) }
255
+ package_stub << "\n"
256
+ return package_stub
257
+ end
258
+
259
+
260
+ def generate_package_release
261
+ return "Component: main
262
+ Origin: apt.cloudscaling.com
263
+ Label: apt repository natty
264
+ Architecture: amd64
265
+ Description: Cloudscaling APT repository
266
+ "
267
+ end
268
+
269
+
270
+ def generate_release
271
+ return "Origin: apt.cloudscaling.com
272
+ Label: apt repository natty
273
+ Codename: natty
274
+ Date: Thu, 22 Dec 2011 00:29:55 UTC
275
+ Architectures: amd64
276
+ Components: main universe multiverse
277
+ Description: Cloudscaling APT repository
278
+ MD5Sum:
279
+ a4b943ff89790ccdc186875dad67827b 5813 main/binary-amd64/Packages
280
+ 004fd3f868ebbe7501fb2e1c0c54e2a7 2148 main/binary-amd64/Packages.gz
281
+ 79dd2fee35fba7255dcd40e1f6529591 134 main/binary-amd64/Release
282
+ d41d8cd98f00b204e9800998ecf8427e 0 universe/binary-amd64/Packages
283
+ 7029066c27ac6f5ef18d660d5741979a 20 universe/binary-amd64/Packages.gz
284
+ 018c8e37146b908a6bde46012a83d4ba 138 universe/binary-amd64/Release
285
+ d41d8cd98f00b204e9800998ecf8427e 0 multiverse/binary-amd64/Packages
286
+ 7029066c27ac6f5ef18d660d5741979a 20 multiverse/binary-amd64/Packages.gz
287
+ 4680f88c741bad22529909db5be4f608 140 multiverse/binary-amd64/Release
288
+ SHA1:
289
+ 6e03924030eab56cb9735a52ec710537e682bcfc 5813 main/binary-amd64/Packages
290
+ 5f2989bae96e148cb5f18accc4357305926ab1e1 2148 main/binary-amd64/Packages.gz
291
+ 6d932af9af761f418e5374f73dcd09badb4fe57e 134 main/binary-amd64/Release
292
+ da39a3ee5e6b4b0d3255bfef95601890afd80709 0 universe/binary-amd64/Packages
293
+ 46c6643f07aa7f6bfe7118de926b86defc5087c4 20 universe/binary-amd64/Packages.gz
294
+ 4d428e7ad434df47cffc40cabf8e238ee76ea434 138 universe/binary-amd64/Release
295
+ da39a3ee5e6b4b0d3255bfef95601890afd80709 0 multiverse/binary-amd64/Packages
296
+ 46c6643f07aa7f6bfe7118de926b86defc5087c4 20 multiverse/binary-amd64/Packages.gz
297
+ c8a7d2eb24ece57d460106506fcff99cb2ada015 140 multiverse/binary-amd64/Release
298
+ SHA256:
299
+ dd8283f06beb4a5fc06ac62d3ae098e5ba2717daef2a15b5f3e9233eb64e0227 5813 main/binary-amd64/Packages
300
+ b197c5a3c1fe6a6d286e9f066a0cade289e3a2fc485c90407179951634788aa8 2148 main/binary-amd64/Packages.gz
301
+ 690b44df6fe65f40f260b73394e87804df78c9ccf13999889259faeed3eec40d 134 main/binary-amd64/Release
302
+ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 universe/binary-amd64/Packages
303
+ 59869db34853933b239f1e2219cf7d431da006aa919635478511fabbfc8849d2 20 universe/binary-amd64/Packages.gz
304
+ 32f35b1fc2bdc5a11b53abeadaaa77771b15acb5305777484bf4390d697ae5bd 138 universe/binary-amd64/Release
305
+ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 multiverse/binary-amd64/Packages
306
+ 59869db34853933b239f1e2219cf7d431da006aa919635478511fabbfc8849d2 20 multiverse/binary-amd64/Packages.gz
307
+ f29816e3a4f90a8b4c688fdb2ac3056d5fb7349857c9ea8da2fbccf8e931baca 140 multiverse/binary-amd64/Release"
308
+ end
309
+
310
+
311
+ def generate_package_line(key='',value='')
312
+ valid_options = %w{Package Version Architecture Maintainer Standards-Version Homepage Priority Depends Filename Size SHA256 SHA1 MD5sum Description}
313
+ raise "Bogus option passed: #{key}" unless valid_options.include?(key)
314
+
315
+ case key
316
+ when 'Depends'
317
+ return "Depends: #{value.join(', ')}\n"
318
+ when 'Maintainer'
319
+ return "Maintainer: <#{value}>\n"
320
+ else
321
+ return "#{key}: #{value}\n"
322
+ end
323
+ end
324
+
325
+ end
326
+
327
+ end
data/lib/frm/s3.rb ADDED
@@ -0,0 +1,89 @@
1
+ my_dir = File.dirname __FILE__
2
+ STDERR.puts "#{File.join my_dir, 's3'}"
3
+ require File.join my_dir, 'base'
4
+
5
+
6
+ module FRM
7
+ class S3 < Base
8
+ attr_reader :max_retries
9
+ @connection
10
+ def initialize(access_key_id,secret_access_key,server='s3.amazonaws.com')
11
+ require 'aws/s3'
12
+ @max_retries = 10
13
+ @connection = AWS::S3::Base.establish_connection!(:access_key_id => access_key_id,
14
+ :secret_access_key => secret_access_key,
15
+ :server => server )
16
+ end
17
+
18
+ def key?(key,bucket)
19
+ AWS::S3::S3Object.exists?(key,bucket)
20
+ end
21
+
22
+ def put(key,value,bucket)
23
+ @max_retries.times do |i|
24
+ begin
25
+ AWS::S3::S3Object.store(key,value,bucket,:server => 's3-us-west-1.amazonaws.com',:access => :public_read)
26
+ return true
27
+ rescue Object => o
28
+ print_retry(__method__,o)
29
+ end
30
+ raise "could not put object!!!" if i == (@max_retries - 1)
31
+ end
32
+ raise "could not put object!!!"
33
+ end
34
+
35
+ def get(key,bucket)
36
+ @max_retries.times do |i|
37
+ begin
38
+ value = AWS::S3::S3Object.value(key,bucket)
39
+ return value
40
+ rescue Object => o
41
+ print_retry(__method__,o)
42
+ end
43
+ raise "could not get object!!!" if i == (@max_retries - 1)
44
+ end
45
+ raise "could not get object!!!"
46
+ end
47
+
48
+ def get_stream(key,bucket)
49
+ @max_retries.times do |i|
50
+ begin
51
+ stream = AWS::S3::S3Object.stream(key,bucket)
52
+ return stream
53
+ rescue Object => o
54
+ print_retry(__method__,o)
55
+ end
56
+ raise "could not get object!!!" if i == (@max_retries - 1)
57
+ end
58
+ raise "could not get object!!!"
59
+ end
60
+
61
+ def delete(key,bucket)
62
+ begin
63
+ AWS::S3::S3Object.delete(key,bucket)
64
+ true
65
+ rescue Object => o
66
+ print_retry(__method__,o)
67
+ end
68
+ end
69
+
70
+ def move(old_key,new_key,vucket)
71
+ begin
72
+ AWS::S3::S3Object.rename(old_key,new_key,bucket)
73
+ return
74
+ rescue Object => o
75
+ print_retry(__method__,o)
76
+ end
77
+ end
78
+
79
+ protected
80
+
81
+ def print_retry(action,error)
82
+ STDERR.puts "coudld not #{action} object because of:"
83
+ STDERR.puts error.inspect
84
+ STDERR.puts ", retrying..."
85
+ sleep 2
86
+ end
87
+
88
+ end
89
+ end
data/lib/frm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Frm
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/test/deb_test.rb ADDED
@@ -0,0 +1,457 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minitest/autorun'
4
+
5
+ my_dir = File.dirname __FILE__
6
+ require File.join my_dir, 'deb'
7
+
8
+ class TestReleasePusher < MiniTest::Unit::TestCase
9
+ def setup
10
+ @tempfile1 = File.open('/tmp/foo_1.2.68_amd64.deb','w+') { |f| f.write 'foo' }
11
+ @tempfile2 = File.open('/tmp/bar_1.2.3.4_amd64.deb','w+') { |f| f.write 'bar' }
12
+ @tempfile3 = File.open('/tmp/martin_1.2.3.4_amd64.deb','w+') { |f| f.write 'martin' }
13
+
14
+ hashes = [{
15
+ "Package" => "foo",
16
+ "Version" => "1.2.68",
17
+ "Architecture" => "amd64",
18
+ "Maintainer" => "support@cloudscaling.com",
19
+ "Homepage" => "http://www.cloudscaling.com",
20
+ "Priority" => "extra",
21
+ "Depends" => %w{one two three},
22
+ "section" => "main",
23
+ "path_to_deb" => '/tmp/foo_1.2.68_amd64.deb',
24
+ "Description" => 'some
25
+ multiline
26
+ description'
27
+ },
28
+ {
29
+ "Package" => "bar",
30
+ "Version" => "1.2.3.4",
31
+ "Architecture" => "amd64",
32
+ "Maintainer" => "support@cloudscaling.com",
33
+ "Homepage" => "http://www.cloudscaling.com",
34
+ "Priority" => "extra",
35
+ "Depends" => %w{one two three},
36
+ "section" => "main",
37
+ "path_to_deb" => '/tmp/bar_1.2.3.4_amd64.deb'
38
+ },
39
+ {
40
+ "Package" => "martin",
41
+ "Version" => "1.2.3.4",
42
+ "Architecture" => "amd64",
43
+ "Maintainer" => "support@cloudscaling.com",
44
+ "Homepage" => "http://www.cloudscaling.com",
45
+ "Priority" => "extra",
46
+ "section" => "main",
47
+ "path_to_deb" => '/tmp/martin_1.2.3.4_amd64.deb'
48
+ },
49
+ {
50
+ "Package" => "cs-chef",
51
+ "Version" => "1.2.3.4",
52
+ "Architecture" => "amd64",
53
+ "Maintainer" => "support@cloudscaling.com",
54
+ "Homepage" => "http://www.cloudscaling.com",
55
+ "Priority" => "extra",
56
+ "section" => "main",
57
+ "path_to_deb" => '/tmp/debs/cs-chef-0.9.1-1782-all.deb'
58
+ }
59
+ ]
60
+
61
+ @package_release = FRM::PackageRelease.new(hashes)
62
+ @release_pusher = FRM::ReleasePusher.new(@package_release,'abcd','1234',\
63
+ 'some-bucket','testing/tmp/martin/foo')
64
+ end
65
+
66
+ def test
67
+ puts "@release_pusher.inspect = #{@release_pusher.inspect}"
68
+ end
69
+
70
+ end
71
+
72
+ class TestPackageRelease < MiniTest::Unit::TestCase
73
+ def setup
74
+ @tempfile1 = File.open('/tmp/foo_1.2.68_amd64.deb','w+') { |f| f.write 'foo' }
75
+ @tempfile2 = File.open('/tmp/bar_1.2.3.4_amd64.deb','w+') { |f| f.write 'bar' }
76
+
77
+ hashes = [{
78
+ "Package" => "foo",
79
+ "Version" => "1.2.68",
80
+ "Architecture" => "amd64",
81
+ "Maintainer" => "support@cloudscaling.com",
82
+ "Homepage" => "http://www.cloudscaling.com",
83
+ "Priority" => "extra",
84
+ "Depends" => %w{one two three},
85
+ "section" => "main",
86
+ "path_to_deb" => '/tmp/foo_1.2.68_amd64.deb',
87
+ "Description" => 'some
88
+ multiline
89
+ description'
90
+ },
91
+ {
92
+ "Package" => "bar",
93
+ "Version" => "1.2.3.4",
94
+ "Architecture" => "amd64",
95
+ "Maintainer" => "support@cloudscaling.com",
96
+ "Homepage" => "http://www.cloudscaling.com",
97
+ "Priority" => "extra",
98
+ "Depends" => %w{one two three},
99
+ "section" => "main",
100
+ "path_to_deb" => '/tmp/bar_1.2.3.4_amd64.deb'
101
+ }
102
+ ]
103
+
104
+ @package_release = FRM::PackageRelease.new(hashes)
105
+ end
106
+
107
+ def test()
108
+ correct_output = "Package: foo
109
+ Version: 1.2.68
110
+ Architecture: amd64
111
+ Maintainer: <support@cloudscaling.com>
112
+ Standards-Version: 3.9.1
113
+ Homepage: http://www.cloudscaling.com
114
+ Priority: extra
115
+ Depends: one, two, three
116
+ Filename: pool/main/f/foo/foo_1.2.68_amd64.deb
117
+ Size: 3
118
+ MD5sum: acbd18db4cc2f85cedef654fccc4a4d8
119
+ SHA1: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
120
+ SHA256: 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
121
+ Description: some
122
+ multiline
123
+ description
124
+
125
+ Package: bar
126
+ Version: 1.2.3.4
127
+ Architecture: amd64
128
+ Maintainer: <support@cloudscaling.com>
129
+ Standards-Version: 3.9.1
130
+ Homepage: http://www.cloudscaling.com
131
+ Priority: extra
132
+ Depends: one, two, three
133
+ Filename: pool/main/b/bar/bar_1.2.3.4_amd64.deb
134
+ Size: 3
135
+ MD5sum: 37b51d194a7513e45b56f6524f2d51f2
136
+ SHA1: 62cdb7020ff920e5aa642c3d4066950dd1f01f4d
137
+ SHA256: fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9
138
+ Description: no description given
139
+
140
+ "
141
+ assert @package_release.package_file == correct_output
142
+ end
143
+
144
+ def test_generate_short_release_file
145
+ correct_short_release_file = "Component: main
146
+ Origin: apt.cloudscaling.com
147
+ Label: apt repository natty
148
+ Architecture: amd64
149
+ Description: Cloudscaling APT repository
150
+ "
151
+ assert @package_release.short_release_file == correct_short_release_file
152
+ end
153
+
154
+ def test_generate_release
155
+ # skip 'need to finish generate_release function'
156
+ correct_release_file = "Origin: apt.cloudscaling.com
157
+ Label: apt repository natty
158
+ Codename: natty
159
+ Date: Thu, 22 Dec 2011 00:29:55 UTC
160
+ Architectures: amd64
161
+ Components: main universe multiverse
162
+ Description: Cloudscaling APT repository
163
+ MD5Sum:
164
+ 32aed966f2f629d6229d14cd37da740e 896 main/binary-amd64/Packages
165
+ a2ea734a1d863873d0acd98845bd0573 438 main/binary-amd64/Packages.gz
166
+ 79dd2fee35fba7255dcd40e1f6529591 134 main/binary-amd64/Release
167
+ SHA1:
168
+ b2f872140a4e651609c1ce7538dba871a4ad49de 896 main/binary-amd64/Packages
169
+ 86b1fc7c8905cf35a9ff2544bb277c332e93b7d1 438 main/binary-amd64/Packages.gz
170
+ 6d932af9af761f418e5374f73dcd09badb4fe57e 134 main/binary-amd64/Release
171
+ SHA256:
172
+ 14139ad7300259e51e2c0d75891966d10f9382adbda61c7348990ccf125e4d4f 896 main/binary-amd64/Packages
173
+ 67014ee7cc96108af726aae5636d26225c2cd833301765e44cf6cb6ea7719698 438 main/binary-amd64/Packages.gz
174
+ 690b44df6fe65f40f260b73394e87804df78c9ccf13999889259faeed3eec40d 134 main/binary-amd64/Release
175
+ "
176
+ assert @package_release.release_file == correct_release_file
177
+ end
178
+
179
+ end
180
+
181
+
182
+ class TestPackage < MiniTest::Unit::TestCase
183
+ def setup
184
+ @tempfile1 = File.open('/tmp/foo','w+') { |f| f.write 'foo' }
185
+ @tempfile2 = File.open('/tmp/bar','w+') { |f| f.write 'bar' }
186
+
187
+ @hash = {
188
+ "Package" => "foo",
189
+ "Version" => "1.2.68",
190
+ "Architecture" => "amd64",
191
+ "Maintainer" => "support@cloudscaling.com",
192
+ "Homepage" => "http://www.cloudscaling.com",
193
+ "Priority" => "extra",
194
+ "Depends" => %w{one two three},
195
+ "section" => "main",
196
+ "path_to_deb" => '/tmp/foo',
197
+ "Description" => 'some
198
+ multiline
199
+ description'
200
+ }
201
+
202
+ @package1 = FRM::Package.new(@hash)
203
+ end
204
+
205
+ def test()
206
+ assert @package1.name == 'foo'
207
+ assert @package1.content == 'foo'
208
+ end
209
+
210
+ def test_bad_file()
211
+ bad_hash = {
212
+ "Package" => "foo",
213
+ "Version" => "1.2.68",
214
+ "Architecture" => "amd64",
215
+ "Maintainer" => "support@cloudscaling.com",
216
+ "Homepage" => "http://www.cloudscaling.com",
217
+ "Priority" => "extra",
218
+ "Depends" => %w{one two three},
219
+ "section" => "main",
220
+ "path_to_deb" => '/some/bad/path',
221
+ "Description" => 'some
222
+ multiline
223
+ description'
224
+ }
225
+ assert_raises(RuntimeError) { FRM::Package.new(bad_hash) }
226
+ end
227
+
228
+ def test_good_file()
229
+ assert @package1.content == 'foo'
230
+ end
231
+
232
+ def test_hashes()
233
+ assert @package1.md5 == 'acbd18db4cc2f85cedef654fccc4a4d8'
234
+ assert @package1.sha1 == '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
235
+ assert @package1.sha2 == '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'
236
+
237
+ end
238
+
239
+
240
+ end
241
+
242
+
243
+ class TestDeb < MiniTest::Unit::TestCase
244
+
245
+ def setup
246
+ @deb = FRM::Deb.new()
247
+ @tempfile1 = File.open('/tmp/foo_1.2.68_amd64.deb','w+') { |f| f.write 'foo' }
248
+ @tempfile2 = File.open('/tmp/bar_1.2.3.4_amd64.deb','w+') { |f| f.write 'bar' }
249
+
250
+ @hash = [
251
+ {
252
+ "Package" => "foo",
253
+ "Version" => "1.2.68",
254
+ "Architecture" => "amd64",
255
+ "Maintainer" => "support@cloudscaling.com",
256
+ "Homepage" => "http://www.cloudscaling.com",
257
+ "Priority" => "extra",
258
+ "Depends" => %w{one two three},
259
+ "section" => "main",
260
+ "path_to_deb" => '/tmp/foo_1.2.68_amd64.deb',
261
+ "Description" => 'some
262
+ multiline
263
+ description'
264
+ },
265
+ {
266
+ "Package" => "bar",
267
+ "Version" => "1.2.3.4",
268
+ "Architecture" => "amd64",
269
+ "Maintainer" => "support@cloudscaling.com",
270
+ "Homepage" => "http://www.cloudscaling.com",
271
+ "Priority" => "extra",
272
+ "Depends" => %w{one two three},
273
+ "section" => "main",
274
+ "path_to_deb" => '/tmp/bar_1.2.3.4_amd64.deb'
275
+ }
276
+ ]
277
+ end
278
+
279
+ def teardown
280
+ File.delete '/tmp/foo_1.2.68_amd64.deb' if File.exists? '/tmp/foo_1.2.68_amd64.deb'
281
+ File.delete '/tmp/bar_1.2.3.4_amd64.deb' if File.exists? '/tmp/bar_1.2.3.4_amd64.deb'
282
+ end
283
+
284
+
285
+ def test_generate_package_stub
286
+ correct_output = "Package: foo
287
+ Version: 1.2.68
288
+ Architecture: amd64
289
+ Maintainer: <support@cloudscaling.com>
290
+ Homepage: http://www.cloudscaling.com
291
+ Priority: extra
292
+ Depends: one, two, three
293
+ Filename: pool/main/f/foo/foo_1.2.68_amd64.deb
294
+ Size: 3
295
+ MD5sum: acbd18db4cc2f85cedef654fccc4a4d8
296
+ SHA1: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
297
+ SHA256: 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
298
+ Description: some
299
+ multiline
300
+ description
301
+
302
+ "
303
+
304
+ duplicate_hash = @hash[0].dup
305
+ assert @deb.generate_package_stub(duplicate_hash) == correct_output
306
+ assert @hash[0] == duplicate_hash
307
+ end
308
+
309
+
310
+ def test_generate_package_file
311
+ correct_output = "Package: foo
312
+ Version: 1.2.68
313
+ Architecture: amd64
314
+ Maintainer: <support@cloudscaling.com>
315
+ Homepage: http://www.cloudscaling.com
316
+ Priority: extra
317
+ Depends: one, two, three
318
+ Filename: pool/main/f/foo/foo_1.2.68_amd64.deb
319
+ Size: 3
320
+ MD5sum: acbd18db4cc2f85cedef654fccc4a4d8
321
+ SHA1: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
322
+ SHA256: 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
323
+ Description: some
324
+ multiline
325
+ description
326
+
327
+ Package: bar
328
+ Version: 1.2.3.4
329
+ Architecture: amd64
330
+ Maintainer: <support@cloudscaling.com>
331
+ Homepage: http://www.cloudscaling.com
332
+ Priority: extra
333
+ Depends: one, two, three
334
+ Filename: pool/main/b/bar/bar_1.2.3.4_amd64.deb
335
+ Size: 3
336
+ MD5sum: 37b51d194a7513e45b56f6524f2d51f2
337
+ SHA1: 62cdb7020ff920e5aa642c3d4066950dd1f01f4d
338
+ SHA256: fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9
339
+ Description: no description given
340
+
341
+ "
342
+ assert @deb.generate_package_file(@hash) == correct_output
343
+ end
344
+
345
+ def test_gzip
346
+ input = generate_random_string
347
+ gziped_pipe = @deb.generate_gzip_pipe(input)
348
+ output = @deb.gunzip_pipe gziped_pipe
349
+ assert input == output
350
+ end
351
+
352
+
353
+ def test_md5
354
+ input = 'foo'
355
+ assert @deb.compute_md5(input) == 'acbd18db4cc2f85cedef654fccc4a4d8'
356
+ end
357
+
358
+ def test_sha1
359
+ input = 'foo'
360
+ assert @deb.compute_sha1(input) == '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
361
+ end
362
+
363
+ def test_sha256
364
+ input = 'foo'
365
+ assert @deb.compute_sha2(input) == '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'
366
+ end
367
+
368
+ def test_generate_package_release
369
+ package_release_file = "Component: main
370
+ Origin: apt.cloudscaling.com
371
+ Label: apt repository natty
372
+ Architecture: amd64
373
+ Description: Cloudscaling APT repository
374
+ "
375
+ assert @deb.generate_package_release == package_release_file
376
+ end
377
+
378
+ def test_generate_release
379
+ skip 'need to finish generate_release function'
380
+ release_file = "Origin: apt.cloudscaling.com
381
+ Label: apt repository natty
382
+ Codename: natty
383
+ Date: Thu, 22 Dec 2011 00:29:55 UTC
384
+ Architectures: amd64
385
+ ;Components: main universe multiverse
386
+ Description: Cloudscaling APT repository
387
+ MD5Sum:
388
+ a4b943ff89790ccdc186875dad67827b 5813 main/binary-amd64/Packages
389
+ 004fd3f868ebbe7501fb2e1c0c54e2a7 2148 main/binary-amd64/Packages.gz
390
+ 79dd2fee35fba7255dcd40e1f6529591 134 main/binary-amd64/Release
391
+ SHA1:
392
+ 6e03924030eab56cb9735a52ec710537e682bcfc 5813 main/binary-amd64/Packages
393
+ 5f2989bae96e148cb5f18accc4357305926ab1e1 2148 main/binary-amd64/Packages.gz
394
+ 6d932af9af761f418e5374f73dcd09badb4fe57e 134 main/binary-amd64/Release
395
+ SHA256:
396
+ dd8283f06beb4a5fc06ac62d3ae098e5ba2717daef2a15b5f3e9233eb64e0227 5813 main/binary-amd64/Packages
397
+ b197c5a3c1fe6a6d286e9f066a0cade289e3a2fc485c90407179951634788aa8 2148 main/binary-amd64/Packages.gz
398
+ 690b44df6fe65f40f260b73394e87804df78c9ccf13999889259faeed3eec40d 134 main/binary-amd64/Release
399
+ "
400
+ assert @deb.generate_release == release_file
401
+ end
402
+
403
+ def generate_random_string
404
+ rand(36**rand(50)).to_s(36)
405
+ end
406
+
407
+ def test_parse_package_stub
408
+ input_stub = "Package: foo
409
+ Version: 1.2.68
410
+ Architecture: amd64
411
+ Maintainer: <support@cloudscaling.com>
412
+ Homepage: http://www.cloudscaling.com
413
+ Priority: extra
414
+ Depends: one, two, three
415
+ Filename: pool/main/f/foo/foo_1.2.68_amd64.deb
416
+ Size: 3
417
+ MD5sum: acbd18db4cc2f85cedef654fccc4a4d8
418
+ SHA1: 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
419
+ SHA256: 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae
420
+ Description: some
421
+ multiline
422
+ description
423
+
424
+ Package: bar
425
+ Version: 1.2.3.4
426
+ Architecture: amd64
427
+ Maintainer: <support@cloudscaling.com>
428
+ Homepage: http://www.cloudscaling.com
429
+ Priority: extra
430
+ Depends: one, two, three
431
+ Filename: pool/main/b/bar/bar_1.2.3.4_amd64.deb
432
+ Size: 3
433
+ MD5sum: 37b51d194a7513e45b56f6524f2d51f2
434
+ SHA1: 62cdb7020ff920e5aa642c3d4066950dd1f01f4d
435
+ SHA256: fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9
436
+ Description: no description given
437
+
438
+ "
439
+ correct_hash = {"Package"=>"foo", "Version"=>"1.2.68", "Architecture"=>"amd64", "Maintainer"=>"<support@cloudscaling.com>", "Homepage"=>"http://www.cloudscaling.com", "Priority"=>"extra", "Depends"=>"one, two, three", "Filename"=>"pool/main/f/foo/foo_1.2.68_amd64.deb", "Size"=>"3", "MD5sum"=>"acbd18db4cc2f85cedef654fccc4a4d8", "SHA1"=>"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", "SHA256"=>"2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", "Description"=>"some multiline\n description"}
440
+ read_buffer, write_buffer = IO.pipe
441
+ write_buffer.write input_stub
442
+ write_buffer.close
443
+ assert @deb.parse_package_stub(read_buffer.dup)[0] == correct_hash
444
+ assert_raises(RuntimeError) { @deb.parse_package_stub File.open('/tmp/foo') }
445
+ end
446
+
447
+
448
+ def test_merge_package_file
449
+ package_file = File.open 'Packages.txt'
450
+ read_buffer, write_buffer = IO.pipe
451
+
452
+ @deb.merge_package_file(package_file,write_buffer,@hash)
453
+
454
+ end
455
+
456
+
457
+ end
data/test/deb_test2.rb ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minitest/autorun'
4
+
5
+ my_dir = File.dirname __FILE__
6
+ require File.join my_dir, 'deb'
7
+
8
+ class TestReleasePusher < MiniTest::Unit::TestCase
9
+ def setup
10
+ @tempfile1 = File.open('/tmp/foo_1.2.68_amd64.deb','w+') { |f| f.write 'foo' }
11
+ @tempfile2 = File.open('/tmp/bar_1.2.3.4_amd64.deb','w+') { |f| f.write 'bar' }
12
+ @tempfile3 = File.open('/tmp/martin_1.2.3.4_amd64.deb','w+') { |f| f.write 'martin' }
13
+
14
+ hashes = %w{
15
+ /home/martin/sheep/modules/substratum/debs/pod-services-0.5.0-967-amd64.deb
16
+ /home/martin/sheep/modules/substratum/debs/cs-chef-0.9.1-1782-all.deb
17
+ /home/martin/sheep/modules/substratum/debs/ruby1.9.2-1-amd64.deb
18
+ }
19
+
20
+
21
+ @package_release = FRM::PackageRelease.new(hashes)
22
+ @release_pusher = FRM::ReleasePusher.new(@package_release,'1234','abcd',\
23
+ 'some-bucket','testing/tmp/frm')
24
+ end
25
+
26
+ def test
27
+
28
+ end
29
+
30
+ end
31
+
data/test/s3.rb ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minitest/autorun'
4
+ my_dir = File.dirname __FILE__
5
+ require File.join my_dir, 's3'
6
+
7
+
8
+ # this is a stupid hack to get the @@bucket region set properly
9
+ DEFAULT_HOST = 's3-us-west-1.amazonaws.com'
10
+
11
+ class TestFRM < MiniTest::Unit::TestCase
12
+
13
+ # these credentials only have access inside of cloudscaling-us-west-develop/testing/
14
+ @@access_key_id = 'abcd'
15
+ @@secret_key_id = '1234'
16
+ @@bucket = 'some-bucket'
17
+ @@prefix = 'testing/tmp/' + Time.now.strftime("%Y/%m/%d/%H:%M:%S ")
18
+ @@server = 's3-us-west-1.amazonaws.com'
19
+ @@timestamp = rand(9999).to_s
20
+
21
+
22
+ @@key = @@prefix + "testing-" + @@timestamp.to_s
23
+ @@value = "rand: " + @@timestamp
24
+
25
+ # we need minitest to run in order
26
+ def self.test_order
27
+ :alpha
28
+ end
29
+
30
+ def setup
31
+ @frm = FRM::S3.new(@@access_key_id,@@secret_key_id,@@server)
32
+ end
33
+
34
+ def test_aput
35
+ assert @frm.put @@key,@@value,@@bucket
36
+ end
37
+
38
+ def test_bkey?
39
+ assert @frm.key? @@key,@@bucket
40
+ end
41
+
42
+ def test_cget
43
+ assert_equal @@value, @frm.get(@@key,@@bucket)
44
+ end
45
+
46
+ def test_ddelete
47
+ assert @frm.delete @@key, @@bucket
48
+ end
49
+
50
+ # this is broken :(
51
+ def test_ekey?
52
+ skip 'need to debug key?'
53
+ refute @frm.key?(@@key,@@bucket)
54
+ end
55
+
56
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Martin Rhoads
@@ -21,8 +21,8 @@ dependencies: []
21
21
  description: FRM makes it easy to build package repositories on S3
22
22
  email:
23
23
  - ermal14@gmail.com
24
- executables: []
25
-
24
+ executables:
25
+ - fpm
26
26
  extensions: []
27
27
 
28
28
  extra_rdoc_files: []
@@ -30,11 +30,17 @@ extra_rdoc_files: []
30
30
  files:
31
31
  - .gitignore
32
32
  - Gemfile
33
+ - LICENSE
33
34
  - Rakefile
35
+ - bin/fpm
34
36
  - frm.gemspec
35
- - frm/.gitignore
36
37
  - lib/frm.rb
38
+ - lib/frm/deb.rb
39
+ - lib/frm/s3.rb
37
40
  - lib/frm/version.rb
41
+ - test/deb_test.rb
42
+ - test/deb_test2.rb
43
+ - test/s3.rb
38
44
  has_rdoc: true
39
45
  homepage: https://github.com/ermal14/frm
40
46
  licenses: []
@@ -67,5 +73,7 @@ rubygems_version: 1.3.7
67
73
  signing_key:
68
74
  specification_version: 3
69
75
  summary: Effin Repo Manager
70
- test_files: []
71
-
76
+ test_files:
77
+ - test/deb_test.rb
78
+ - test/deb_test2.rb
79
+ - test/s3.rb
data/frm/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*