frm 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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/*