AptDownloader 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ === 1.0.0 / 2008-12-21
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+ * Can download to a given directory for any architecture
7
+ * no reuse of temp files
8
+ * no uninstall
9
+
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/apt_downloader
6
+ lib/apt_downloader.rb
7
+ test/test_apt_downloader.rb
@@ -0,0 +1,88 @@
1
+ = AptDownloader
2
+
3
+ http://rubyforge.org/projects/uwruby/
4
+ http://uwruby/rubyforge.org/apt_downloader
5
+
6
+ == DESCRIPTION:
7
+
8
+ Apt-Downloader is intended as a useful tool for
9
+ developers working on embedded linux.
10
+
11
+ When working on embedded linux it can be difficult to get programs working
12
+ on your target due to the shear number of dependencies needed to run
13
+ them. Debian has done an excellent job of building and testing their
14
+ software packages on a large number of architectures. The debian apt system
15
+ makes it easy for debian users to get access to this software on their own
16
+ platforms, but it's a bit obsfuscated how to use thier software to say,
17
+ download a package and all of it's dependencies to the root filesystem of
18
+ your target and target architecture.
19
+
20
+ Apt-Downloader is front end to apt that is intended to make this easy.
21
+
22
+ == FEATURES/PROBLEMS:
23
+
24
+ Features:
25
+ *Automatically builds up package lists from debian
26
+ *Automatically determines all dependency packages and dowloads them.
27
+ *Allows users to pick an output directory for either deb packages, the
28
+ extraction of such packages, or both.
29
+ *Cleans up after itself - all temp files are deleted at program exit.
30
+ *Clean and simple to use.
31
+
32
+ Problems:
33
+ *Takes a little while: building package lists is a slow process, especially
34
+ over a slow internet connection
35
+ *Does not (yet) support reusing the temp files that take a while to generate/
36
+ download before packages can be installed.
37
+ *Does not (yet) support reusing any downloaded files. Files are re-downloaded
38
+ from scratch each time they are needed.
39
+ *Checks your package names against the host system. If host and target servers
40
+ don't match, this could create a problem.
41
+ *Not capable of uninstall. If you don't like what you get, you will need to
42
+ regenerate your rootFS (however you could just install apt in your root fs
43
+ with this tool and then use it nativiely if your target has an internet
44
+ connection
45
+
46
+ == SYNOPSIS:
47
+
48
+ ad = AptDownloader.new
49
+ ad.architecture = 'arm'
50
+ ad.addPackages 'perl', 'ruby', 'ffmpeg'
51
+ ad.output_directory = '~/arm_deb_packages'
52
+ ad.go
53
+
54
+ == REQUIREMENTS:
55
+
56
+ You must have the apt (Advanced Package Tool) toolset
57
+ installed on your distrobution of linux. Apt is was designed for
58
+ Debian and is also in use on Ubuntu and FIXME-- ADD OTHER DISTROS HERE
59
+
60
+ == INSTALL:
61
+
62
+ sudo gem install
63
+ thats it.
64
+
65
+ == LICENSE:
66
+
67
+ (The MIT License)
68
+
69
+ Copyright (c) 2008 FIX
70
+
71
+ Permission is hereby granted, free of charge, to any person obtaining
72
+ a copy of this software and associated documentation files (the
73
+ 'Software'), to deal in the Software without restriction, including
74
+ without limitation the rights to use, copy, modify, merge, publish,
75
+ distribute, sublicense, and/or sell copies of the Software, and to
76
+ permit persons to whom the Software is furnished to do so, subject to
77
+ the following conditions:
78
+
79
+ The above copyright notice and this permission notice shall be
80
+ included in all copies or substantial portions of the Software.
81
+
82
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
83
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
84
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
85
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
86
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
87
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
88
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/apt_downloader.rb'
6
+
7
+ Hoe.new('AptDownloader', AptDownloader::VERSION) do |p|
8
+ p.rubyforge_name = 'uwruby'
9
+ p.developer('Mathew Chasan', 'aftermathew@gmail.com')
10
+ end
11
+
12
+ # vim: syntax=Ruby
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ require 'pp'
6
+ require 'bin/apt_downloader'
7
+
8
+ class ThisApplication
9
+ def parse_options ops = ARGV
10
+ @option_parser = OptionParser.new do |opts|
11
+ opts.banner = "Usage apt_downloader [ops] debian-package [more packages]"
12
+
13
+ opts.on("-a", "--architecture ARCH", "Debian architecure to download " +
14
+ "packages for. Options are:" +
15
+ "#{AptDownloader::VALID_DEBIAN_ARCHITECTURES.map{|x| "\n" +"\t"*5+"#{x}"} }") do |a|
16
+ @architecure = a
17
+ end
18
+
19
+ opts.on("-o", "--output-dir DIR", "Copy all deb files to directory " +
20
+ "(directory created if needed)") do |dir|
21
+ puts dir
22
+ @output_dir = dir
23
+ end
24
+
25
+ opts.on("-x", "--extract-dir DIR", "Extract all downloaded deb files to" +
26
+ " the supplied directory. Debs will be extracted without" +
27
+ " root privelages.") do |x|
28
+ @extract_dir = x
29
+ @sudo_extract = false
30
+ end
31
+
32
+ opts.on("-X", "--sudo-extract-dir DIR", "Extract all downloaded deb files" +
33
+ " to the supplied directory. Debs will be extracted with" +
34
+ " root privelages (for extracting to your target root" +
35
+ " filesystem). Users will be asked for sudo password.") do |x|
36
+ @extract_dir = x
37
+ @sudo_extract = true
38
+ end
39
+
40
+ # these features not yet implemented
41
+ if nil
42
+ opts.on("-s", "--save-dir-structure", "NOT YET IMPLEMENTED " +
43
+ "Save the temp filesystem so that the" +
44
+ " next call to apt_downloader can build on what you have" +
45
+ " already downloaded and not from scratch") do |s|
46
+ @save_fs = true
47
+ end
48
+
49
+ opts.on("-r", "--reuse-dir-structure", "NOT YET IMPLEMENTED " +
50
+ "Reuse a previously saved directory structure" +
51
+ " (and save new downloads to it)." +
52
+ " Structure should have been created with a previous run" +
53
+ " of apt_downloader with the -s option") do |dir|
54
+ @reuse_fs = dir
55
+ end
56
+ end
57
+
58
+ opts.on("--", "--end",
59
+ "Don't parse any more options") do
60
+ OptionParser.terminate
61
+ end
62
+ end #end option parser block
63
+
64
+ @packages = begin @option_parser.parse ops
65
+ rescue OptionParser::InvalidOption => e
66
+ puts e
67
+ puts option_parser
68
+ exit 1
69
+ end
70
+ end
71
+
72
+ def end_badly
73
+ puts @option_parser
74
+ exit 1
75
+ end
76
+
77
+ def initialize
78
+ @output_dir = nil
79
+ @extract_dir = nil
80
+ @sudo_extract =false
81
+ @architecture = nil
82
+
83
+ parse_options
84
+
85
+ unless @packages.size > 0
86
+ end_badly
87
+ end
88
+
89
+ unless @output_dir || @extract_dir
90
+ puts "This program is being run without saving or extracting *any* deb" +
91
+ " files! Cowardly refusing to run!"
92
+ end_badly
93
+ end
94
+
95
+ ad = AptDownloader.new
96
+ ad.download_dir = @output_dir if @output_dir
97
+ ad.extract_dir = @extract_dir if @extract_dir
98
+ ad.sudo_extract = @sudo_extract
99
+
100
+ begin
101
+ unless @architecture then
102
+ puts "Architecture left blank, defaulting to armel"
103
+ @architecture = 'armel'
104
+ end
105
+ ad.architecture = @architecture
106
+ rescue
107
+ puts "#{@architecture} is not a valid architecture"
108
+ puts 'Giving up...'
109
+ end_badly
110
+ end
111
+
112
+ @packages.each{ |package|
113
+ begin
114
+ ad.addPackage package
115
+ rescue
116
+ puts "#{package} was not found as a valid package!"
117
+ puts 'Giving up...'
118
+ end_badly
119
+ end
120
+ }
121
+
122
+ ad.go
123
+ end
124
+ end
125
+
126
+ ThisApplication.new
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/ruby -w
2
+
3
+
4
+ require 'pp'
5
+ require 'tempfile'
6
+ require 'fileutils'
7
+
8
+ class AptDownloader
9
+ VERSION = '1.0.0'
10
+ VALID_DEBIAN_ARCHITECTURES = %w[alpha amd64 arm armel hppa i386 ia64 mips
11
+ mipsel powerpc s390 sparc]
12
+ APT_FS_PATH = "#{Dir::tmpdir}/apt_fs_#{$$}_"
13
+
14
+ DEFAULT_DEBIAN_SERVER_LIST= ['deb http://security.debian.org/ testing/updates main contrib non-free',
15
+ 'deb-src http://security.debian.org/ testing/updates main contrib non-free',
16
+ 'deb http://security.debian.org/ stable/updates main contrib non-free',
17
+ 'deb-src http://security.debian.org/ stable/updates main contrib non-free',
18
+ # Main archives
19
+ 'deb http://ftp.us.debian.org/debian/ stable main non-free contrib',
20
+ 'deb-src http://ftp.us.debian.org/debian/ stable main non-free contrib',
21
+ 'deb http://ftp.us.debian.org/debian/ testing main non-free contrib',
22
+ 'deb-src http://ftp.us.debian.org/debian/ testing main non-free contrib',
23
+ 'deb http://ftp.us.debian.org/debian/ unstable main non-free contrib',
24
+ 'deb-src http://ftp.us.debian.org/debian/ unstable main non-free contrib',
25
+
26
+ 'deb http://ftp.us.debian.org/debian/ ' +
27
+ 'experimental main non-free contrib',
28
+
29
+ 'deb-src http://ftp.us.debian.org/debian/ ' +
30
+ 'experimental main non-free contrib',
31
+
32
+ # --- debian-multimedia
33
+ # deb http://www.debian-multimedia.org etch main'
34
+ 'deb http://www.debian-multimedia.org unstable main',
35
+ 'deb http://www.debian-multimedia.org testing main',
36
+ 'deb http://www.debian-multimedia.org experimental main',
37
+ 'deb-src http://www.debian-multimedia.org sid main',
38
+ ]
39
+
40
+ def config_file_contents
41
+ return <<-EOS
42
+ APT "";
43
+ APT::Architecture "#{@architecture}";
44
+ APT::Build-Essential "";
45
+ APT::Build-Essential:: "build-essential";
46
+ APT::Install-Recommends "1";
47
+ APT::Install-Suggests "0";
48
+ APT::Acquire "";
49
+ APT::Acquire::Translation "environment";
50
+ APT::Authentication "";
51
+ APT::Authentication::TrustCDROM "true";
52
+ APT::NeverAutoRemove "";
53
+ APT::NeverAutoRemove:: "^linux-image.*";
54
+ APT::NeverAutoRemove:: "^linux-restricted-modules.*";
55
+ APT::Default-Release "testing";
56
+ APT::Cache-Limit "141943904";
57
+ Dir "#{APT_FS_PATH}/";
58
+ Dir::State "#{APT_FS_PATH}/var/lib/apt/";
59
+ Dir::State::lists "lists/";
60
+ Dir::State::cdroms "cdroms.list";
61
+ Dir::State::userstatus "status.user";
62
+ Dir::State::status "#{APT_FS_PATH}/var/lib/dpkg/status";
63
+ Dir::Cache "#{APT_FS_PATH}/var/cache/apt/";
64
+ Dir::Cache::archives "archives/";
65
+ Dir::Cache::srcpkgcache "srcpkgcache.bin";
66
+ Dir::Cache::pkgcache "pkgcache.bin";
67
+ Dir::Etc "etc/apt/";
68
+ Dir::Etc::sourcelist "sources.list";
69
+ Dir::Etc::sourceparts "sources.list.d";
70
+ Dir::Etc::vendorlist "vendors.list";
71
+ Dir::Etc::vendorparts "vendors.list.d";
72
+ Dir::Etc::main "apt.conf";
73
+ Dir::Etc::parts "apt.conf.d";
74
+ Dir::Etc::preferences "preferences";
75
+ Dir::Bin "";
76
+ Dir::Bin::methods "/usr/lib/apt/methods";
77
+ Dir::Bin::dpkg "/usr/bin/dpkg";
78
+ Dir::Log "#{APT_FS_PATH}/var/log/apt";
79
+ Dir::Log::Terminal "term.log";
80
+ DPkg "";
81
+ DPkg::Pre-Install-Pkgs "";
82
+ DPkg::Pre-Install-Pkgs:: "/usr/sbin/dpkg-preconfigure --apt || true";
83
+ DPkg::Post-Invoke "";
84
+ DPkg::Post-Invoke:: "if [ -x /usr/bin/debsums ]; then /usr/bin/debsums --generate=nocheck -sp /var/cache/apt/archives; fi";
85
+
86
+ EOS
87
+
88
+ end
89
+
90
+
91
+ attr_accessor :architecture, :download_dir, :apt_tmp_fs, :extract_dir
92
+ attr_accessor :sudo_extract
93
+
94
+ # at this point packages once added can't be deleted,
95
+ # until i implement apt-remove to get rid of them from
96
+ # apt-tmp-fs
97
+ attr_reader :packages
98
+
99
+ def create_config_file
100
+ @apt_config = Tempfile.new 'config_file'
101
+ @apt_config.sync = true
102
+ @apt_config.write config_file_contents
103
+ end
104
+
105
+ # create a temprorary directory structure that imititates the parts of the
106
+ # linux filesystem that apt cares about
107
+ def create_apt_fs
108
+ # create a temporary directory to do all downloads to
109
+ @apt_tmp_fs = FileUtils.mkpath APT_FS_PATH
110
+
111
+ %w[/etc/apt/
112
+ /var/cache/apt/archives/partial
113
+ /var/lib/apt/lists/partial
114
+ /var/lib/dpkg/
115
+ ].each{ |directory| FileUtils.mkpath(APT_FS_PATH + directory) }
116
+
117
+ %w[/var/lib/dpkg/lock
118
+ /var/lib/dpkg/status
119
+ /var/lib/apt/lists/lock
120
+ /etc/apt/sources.list
121
+ ].each{ |file| FileUtils.touch(APT_FS_PATH + file) }
122
+
123
+ File.open(APT_FS_PATH + "/etc/apt/sources.list",
124
+ File::WRONLY |
125
+ File::TRUNC |
126
+ File::CREAT ) { |sources_file|
127
+ DEFAULT_DEBIAN_SERVER_LIST.each{ |source| sources_file.puts source }
128
+ }
129
+
130
+ # set up directory for removal on program delete
131
+ at_exit{ FileUtils.rm_rf APT_FS_PATH }
132
+ end
133
+
134
+
135
+ def download packages
136
+ call = "apt-get -c #{@apt_config.path} update"
137
+ puts "** apt-downloader: #{call}"
138
+ system(call) unless @already_updated
139
+
140
+ @already_updated = true
141
+
142
+ call = "apt-get -c #{@apt_config.path} --download-only " +
143
+ "--assume-yes --force-yes install #{packages}"
144
+ puts "\n** apt-downloader: #{call}"
145
+ system(call)
146
+ end
147
+
148
+ def initialize architecture='armel', *packages
149
+ @packages = []
150
+ packages.each{ |package| addPackage package }
151
+
152
+ @already_updated = false
153
+ @apt_config = nil
154
+ @apt_tmp_fs = nil
155
+
156
+ @architecture = architecture
157
+ @download_dir = nil
158
+ @extract_dir = nil
159
+ @sudo_extract = false
160
+ @dependencies = []
161
+ @suggestions = []
162
+ @all_dependencies = []
163
+ @all_suggestions = []
164
+ end
165
+
166
+ protected
167
+ def _handle_debs path
168
+ mypath = File.expand_path path
169
+ unless File.exist?(mypath)
170
+ FileUtils.mkpath mypath
171
+ end
172
+
173
+ unless File.directory?(mypath)
174
+ raise(ArgumentError,
175
+ "Cannot save to #{mypath} since it is not a directory")
176
+ end
177
+
178
+ yield mypath
179
+ end
180
+
181
+ # internal use only
182
+ def _copy_debs_to path
183
+ _handle_debs(@download_dir){ |path|
184
+ FileUtils.cp(Dir.glob(@apt_tmp_fs + "/var/cache/apt/archives/*.deb"),path)
185
+ }
186
+ end
187
+
188
+ def _extract_debs_to path
189
+ _handle_debs(@extract_dir) { |path|
190
+ Dir.glob(@apt_tmp_fs + "/var/cache/apt/archives/*.deb").each { |archive|
191
+ puts "** Extracting: #{archive}"
192
+ sudo = @sudo_extract ? 'sudo' : ''
193
+ system "#{sudo} dpkg -x #{archive} #{path}"
194
+ }
195
+ }
196
+ end
197
+
198
+ public
199
+ def go
200
+ create_config_file unless @apt_config
201
+ create_apt_fs unless @apt_tmp_fs
202
+
203
+ packages_string = ''
204
+ packages.each{ |package| packages_string += package + ' ' }
205
+ download packages_string
206
+
207
+ _copy_debs_to @download_dir if (@download_dir)
208
+ _extract_debs_to @extract_dir if(@extract_dir)
209
+ end
210
+
211
+ # Returns true if packageName is a real debian package, and false otherwise
212
+ def AptDownloader.validPackage? packageName
213
+ result = %x[apt-cache pkgnames]
214
+ result.split("\n").include?(packageName)
215
+ end
216
+
217
+ def addPackages(*packageNames)
218
+ packageNames.each { |name|
219
+ unless AptDownloader::validPackage? name
220
+ raise ArgumentError, "Package #{name} does not exist."
221
+ end
222
+ @packages << name
223
+ }
224
+ end
225
+
226
+ def addPackage(package)
227
+ addPackages package
228
+ end
229
+
230
+ def architecture= ( architecture )
231
+ arch = architecture.downcase
232
+ unless VALID_DEBIAN_ARCHITECTURES.include? arch
233
+ raise ArgumentError, "Invalid architecture"
234
+ end
235
+ @architecture = arch
236
+ end
237
+
238
+ #internal use only
239
+ def _get_dependencies_backend callword, searchword, recurse=false
240
+ unless @packages
241
+ raise StandardError, "No packages set!"
242
+ end
243
+ dependencies = packages.map { |package|
244
+ deps = %x[apt-cache #{recurse ? '--recurse' : ''} #{callword} #{package}]
245
+ deps = deps.map{ |x|
246
+ # get rid of coflicts/and other messages we aren't lookign for
247
+ x = x.sub!(searchword, '') ? x.strip! : ''
248
+ x = x.include?('|') ? '' : x
249
+ }
250
+ }
251
+ dependencies.flatten!.uniq!
252
+ dependencies.delete ''
253
+ dependencies
254
+ end
255
+
256
+ def depends
257
+ @dependencies = _get_dependencies_backend 'depends', 'Depends:'
258
+ end
259
+
260
+ def suggests
261
+ @suggestions = _get_dependencies_backend 'depends', 'Suggests:'
262
+ end
263
+
264
+ def recursiveDepends
265
+ @all_dependencies = _get_dependencies_backend 'depends', 'Depends:', true
266
+ end
267
+
268
+ def recursiveSuggests
269
+ @all_suggestions = _get_dependencies_backend 'depends', 'Suggests:', true
270
+ end
271
+ end
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ require 'test/unit'
4
+ require 'apt_downloader'
5
+
6
+
7
+
8
+ class TestAptDownloader < Test::Unit::TestCase
9
+ def setup
10
+ @downloader = AptDownloader.new
11
+ end
12
+
13
+ def test_invalid_package
14
+ assert_raise(ArgumentError){
15
+ @downloader.addPackages "FakePackageName"
16
+ }
17
+ end
18
+
19
+ def test_valid_package
20
+ assert(AptDownloader.validPackage?('ruby'))
21
+ end
22
+
23
+ def test_add_many_packages
24
+ assert_nothing_raised{
25
+ @downloader.addPackages 'ruby', 'ruby1.9', 'ruby1.8'
26
+ }
27
+ assert_equal(@downloader.packages, %w[ruby ruby1.9 ruby1.8])
28
+ assert_nothing_raised{
29
+ @downloader.addPackages 'rake', 'ruby-dev'
30
+ }
31
+ assert_equal(@downloader.packages, %w[ruby ruby1.9 ruby1.8 rake ruby-dev])
32
+ end
33
+
34
+ def test_invalid_architecture
35
+ assert_raise(ArgumentError){
36
+ @downloader.architecture = "vax"
37
+ }
38
+ end
39
+
40
+ def test_valid_architecture
41
+ assert_nothing_raised{
42
+ @downloader.architecture = "arm"
43
+ }
44
+ end
45
+
46
+ def test_dependencies
47
+ @downloader.addPackage "ruby1.8"
48
+ assert_equal( %w[libc6 libruby1.8], @downloader.depends )
49
+ assert_equal( %w[ruby1.8-examples rdoc1.8 ri1.8], @downloader.suggests )
50
+ end
51
+
52
+ def test_recursive_dependencies
53
+ @downloader.addPackage 'ffmpeg'
54
+ assert_equal(["libavcodec51", "libavdevice52", "libavformat52", \
55
+ "libavutil49", "libc6", "libfreetype6", "libimlib2",\
56
+ "libsdl1.2debian", "libswscale0"], @downloader.depends)
57
+ # i thought a lot about how to handle this. It actually returns 1967
58
+ # different dependencies but that is liable to change as debian changes.
59
+ # Mostly i wanted make sure this is big
60
+ d = @downloader.recursiveDepends
61
+ assert(d.size > 1900)
62
+ assert_equal(d.compact, d)
63
+ assert_equal(d.uniq, d)
64
+ end
65
+
66
+ def test_download
67
+ end
68
+
69
+ def teardown
70
+ end
71
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: AptDownloader
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mathew Chasan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-23 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.8.2
24
+ version:
25
+ description: Apt-Downloader is intended as a useful tool for developers working on embedded linux. When working on embedded linux it can be difficult to get programs working on your target due to the shear number of dependencies needed to run them. Debian has done an excellent job of building and testing their software packages on a large number of architectures. The debian apt system makes it easy for debian users to get access to this software on their own platforms, but it's a bit obsfuscated how to use thier software to say, download a package and all of it's dependencies to the root filesystem of your target and target architecture. Apt-Downloader is front end to apt that is intended to make this easy.
26
+ email:
27
+ - aftermathew@gmail.com
28
+ executables:
29
+ - apt_downloader
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ files:
37
+ - History.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - bin/apt_downloader
42
+ - lib/apt_downloader.rb
43
+ - test/test_apt_downloader.rb
44
+ has_rdoc: true
45
+ homepage: http://rubyforge.org/projects/uwruby/
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --main
49
+ - README.txt
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project: uwruby
67
+ rubygems_version: 1.2.0
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: Apt-Downloader is intended as a useful tool for developers working on embedded linux
71
+ test_files:
72
+ - test/test_apt_downloader.rb