enhancerepo 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/CHANGELOG.rdoc +18 -0
  2. data/Manifest.txt +85 -0
  3. data/README +10 -0
  4. data/README.rdoc +15 -0
  5. data/Rakefile +48 -0
  6. data/TODO.rdoc +4 -0
  7. data/bin/enhancerepo +4 -0
  8. data/lib/enhance_repo.rb +36 -0
  9. data/lib/enhance_repo/cli.rb +150 -0
  10. data/lib/enhance_repo/config_opts.rb +98 -0
  11. data/lib/enhance_repo/logger.rb +67 -0
  12. data/lib/enhance_repo/other.rb +80 -0
  13. data/lib/enhance_repo/package_id.rb +81 -0
  14. data/lib/enhance_repo/product_id.rb +30 -0
  15. data/lib/enhance_repo/rpm_md.rb +27 -0
  16. data/lib/enhance_repo/rpm_md/data.rb +55 -0
  17. data/lib/enhance_repo/rpm_md/delta_info.rb +205 -0
  18. data/lib/enhance_repo/rpm_md/extra_primary_data.rb +45 -0
  19. data/lib/enhance_repo/rpm_md/file_lists.rb +81 -0
  20. data/lib/enhance_repo/rpm_md/index.rb +144 -0
  21. data/lib/enhance_repo/rpm_md/other.rb +69 -0
  22. data/lib/enhance_repo/rpm_md/primary.rb +123 -0
  23. data/lib/enhance_repo/rpm_md/products.rb +142 -0
  24. data/lib/enhance_repo/rpm_md/repo.rb +202 -0
  25. data/lib/enhance_repo/rpm_md/resource.rb +44 -0
  26. data/lib/enhance_repo/rpm_md/suse_data.rb +191 -0
  27. data/lib/enhance_repo/rpm_md/suse_info.rb +88 -0
  28. data/lib/enhance_repo/rpm_md/update.rb +141 -0
  29. data/lib/enhance_repo/rpm_md/update_info.rb +244 -0
  30. data/lib/enhance_repo/rpm_md/update_smart_fields.rb +127 -0
  31. data/lib/enhance_repo/xml_comparer.rb +117 -0
  32. data/lib/tempdir.rb +62 -0
  33. data/lib/tempdir/tempfile.rb +21 -0
  34. data/test/all_tests.rb +27 -0
  35. data/test/data/packages/a-1.0.spec +19 -0
  36. data/test/data/packages/a-2.0.spec +24 -0
  37. data/test/data/repodata/update-test-11.1/filelists.xml.gz +0 -0
  38. data/test/data/repodata/update-test-11.1/other.xml.gz +0 -0
  39. data/test/data/repodata/update-test-11.1/primary.xml.gz +0 -0
  40. data/test/data/repodata/update-test-11.1/repomd.xml +21 -0
  41. data/test/data/repomd.xml +21 -0
  42. data/test/data/rpms/repo-1/a-1.0-0.x86_64.rpm +0 -0
  43. data/test/data/rpms/repo-1/a-1.0_2.0-0_0.x86_64.delta.rpm +0 -0
  44. data/test/data/rpms/repo-1/a-2.0-0.x86_64.rpm +0 -0
  45. data/test/data/rpms/repo-1/repodata/deltainfo.xml.gz +0 -0
  46. data/test/data/rpms/repo-1/repodata/deltainfo.xml.gz.gz +0 -0
  47. data/test/data/rpms/repo-1/repodata/filelists.xml.gz +0 -0
  48. data/test/data/rpms/repo-1/repodata/other.xml.gz +0 -0
  49. data/test/data/rpms/repo-1/repodata/primary.xml.gz +0 -0
  50. data/test/data/rpms/repo-1/repodata/repomd.xml +45 -0
  51. data/test/data/rpms/repo-1/repodata/susedata.xml.gz +0 -0
  52. data/test/data/rpms/repo-1/repodata/updateinfo.xml.gz +0 -0
  53. data/test/data/rpms/repo-1/repoparts/update-a-1.xml +22 -0
  54. data/test/data/rpms/repo-with-product/a-1.0-0.x86_64.rpm +0 -0
  55. data/test/data/rpms/repo-with-product/openSUSE-release-11.2-1.6.i586.rpm +0 -0
  56. data/test/data/rpms/repo-with-product/openSUSE-release-dvd-11.2-1.6.i586.rpm +0 -0
  57. data/test/data/rpms/repo-with-product/repodata/filelists.xml.gz +0 -0
  58. data/test/data/rpms/repo-with-product/repodata/other.xml.gz +0 -0
  59. data/test/data/rpms/repo-with-product/repodata/primary.xml.gz +0 -0
  60. data/test/data/rpms/repo-with-product/repodata/products.xml.gz +0 -0
  61. data/test/data/rpms/repo-with-product/repodata/repomd.xml +27 -0
  62. data/test/data/rpms/update-test-11.1/update-test-affects-package-manager.rpm +0 -0
  63. data/test/data/rpms/update-test-11.1/update-test-interactive.rpm +0 -0
  64. data/test/data/rpms/update-test-11.1/update-test-optional.rpm +0 -0
  65. data/test/data/rpms/update-test-11.1/update-test-reboot-needed.rpm +0 -0
  66. data/test/data/rpms/update-test-11.1/update-test-security.rpm +0 -0
  67. data/test/data/rpms/update-test-11.1/update-test-trival.rpm +0 -0
  68. data/test/data/rpms/update-test-factory/update-test-affects-package-manager-0-9999.1.2.noarch.rpm +0 -0
  69. data/test/data/rpms/update-test-factory/update-test-interactive-0-9999.1.2.noarch.rpm +0 -0
  70. data/test/data/rpms/update-test-factory/update-test-optional-0-9999.1.2.noarch.rpm +0 -0
  71. data/test/data/rpms/update-test-factory/update-test-reboot-needed-0-9999.1.2.noarch.rpm +0 -0
  72. data/test/data/rpms/update-test-factory/update-test-relogin-suggested-0-9999.1.2.noarch.rpm +0 -0
  73. data/test/data/rpms/update-test-factory/update-test-security-0-9999.1.2.noarch.rpm +0 -0
  74. data/test/deltainfo_test.rb +50 -0
  75. data/test/extensions_test.rb +31 -0
  76. data/test/index_test.rb +51 -0
  77. data/test/primary_test.rb +51 -0
  78. data/test/products_test.rb +51 -0
  79. data/test/repo_test.rb +72 -0
  80. data/test/repomdindex_test.rb +58 -0
  81. data/test/rpmmd_test.rb +60 -0
  82. data/test/susedata_test.rb +53 -0
  83. data/test/tempdir_test.rb +62 -0
  84. data/test/test_helper.rb +53 -0
  85. data/test/update_test.rb +80 -0
  86. data/test/updateinfo_test.rb +59 -0
  87. metadata +267 -0
@@ -0,0 +1,45 @@
1
+ #--
2
+ #
3
+ # enhancerepo is a rpm-md repository metadata tool.
4
+ # Copyright (C) 2008, 2009 Novell Inc.
5
+ # Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
21
+ # also available at http://www.gnu.org/copyleft/gpl.html.
22
+ #
23
+ #++
24
+ #
25
+
26
+ require 'rubygems'
27
+ require 'builder'
28
+
29
+ module EnhanceRepo
30
+ module RpmMd
31
+
32
+ # represents a set non standard data tags
33
+ # but it is not part of the standard, yet still associated
34
+ # with a particular package (so with primary.xml semantics
35
+ class ExtraPrimaryData
36
+ include Logger
37
+
38
+ # initialize the extra data with a name
39
+ def initialize(name)
40
+ @name = name
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,81 @@
1
+ #--
2
+ #
3
+ # enhancerepo is a rpm-md repository metadata tool.
4
+ # Copyright (C) 2008, 2009 Novell Inc.
5
+ # Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
21
+ # also available at http://www.gnu.org/copyleft/gpl.html.
22
+ #
23
+ #++
24
+ #
25
+
26
+ module EnhanceRepo
27
+ module RpmMd
28
+
29
+ # represents
30
+ # filelist data
31
+ #
32
+ # See:
33
+ # http://en.opensuse.org/Standards/Rpm_Metadata
34
+ #
35
+ class FileLists
36
+
37
+ include Logger
38
+
39
+ def initialize(dir)
40
+ @dir = dir
41
+ @rpmfiles = []
42
+ end
43
+
44
+ def read
45
+ Dir["#{@dir}/**/*.rpm"].each do |rpmfile|
46
+ @rpmfiles << rpmfile
47
+ end
48
+ end
49
+
50
+ def empty?
51
+ @rpmfiles.empty?
52
+ end
53
+
54
+ def write_package(file, rpmfile)
55
+ b = Builder::XmlMarkup.new(:target=>file, :indent=>2, :initial=>2)
56
+ pkgid = PackageId.new(rpmfile)
57
+ b.package('pkgid'=>pkgid.checksum, 'name' => pkgid.name, 'arch'=>pkgid.arch ) do | b |
58
+ b.version('epoch' => pkgid.version.e, 'ver' => pkgid.version.v, 'rel' => pkgid.version.r)
59
+ pkgid.files.each do |f|
60
+ b.file f
61
+ end
62
+ end
63
+ # done package tag
64
+ end
65
+
66
+ # write filelists.xml
67
+ def write(file)
68
+ builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
69
+ builder.instruct!
70
+ xml = builder.tag!("filelists", 'xmlns' => 'xmlns="http://linux.duke.edu/metadata/filelists"', 'packages'=> @rpmfiles.size ) do |b|
71
+ @rpmfiles.each do |rpmfile|
72
+ write_package(file, rpmfile)
73
+ end
74
+ # next package
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,144 @@
1
+ #--
2
+ #
3
+ # enhancerepo is a rpm-md repository metadata tool.
4
+ # Copyright (C) 2008, 2009 Novell Inc.
5
+ # Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
21
+ # also available at http://www.gnu.org/copyleft/gpl.html.
22
+ #
23
+ #++
24
+ #
25
+
26
+ require 'enhance_repo/rpm_md/resource'
27
+
28
+ module EnhanceRepo
29
+ module RpmMd
30
+
31
+ # represents the repomd index
32
+ class Index < Data
33
+
34
+ include EnhanceRepo::Logger
35
+
36
+ attr_accessor :products, :keywords
37
+ attr_accessor :resources
38
+
39
+ # constructor
40
+ # log logger object
41
+ def initialize
42
+ super('repomd')
43
+ @resources = []
44
+ end
45
+
46
+ # Reimplemented from EnhanceRepo::RpmMd::Data
47
+ def should_compress?
48
+ false
49
+ end
50
+
51
+ # add a file resource. Takes care of setting
52
+ # all the metadata.
53
+ def add_file_resource(abspath, path, type=nil)
54
+ r = Resource.new
55
+ r.type = type
56
+ # figure out the type of resource
57
+ # the extname to remove is different if it is gzipped
58
+ ext = File.extname(path)
59
+ base = File.basename(path, ext)
60
+
61
+ # if it was gzipped, repeat the operation
62
+ # to get the real basename
63
+ if ext == '.gz'
64
+ ext = File.extname(base)
65
+ base = File.basename(base, ext)
66
+ end
67
+
68
+ r.type = base if r.type.nil?
69
+ r.location = path
70
+ r.timestamp = File.mtime(abspath).to_i.to_s
71
+ r.checksum = Digest::SHA1.hexdigest(File.new(abspath).read)
72
+ r.openchecksum = r.checksum
73
+ if File.extname(abspath) == '.gz'
74
+ # we have a different openchecksum
75
+ r.openchecksum = Digest::SHA1.hexdigest(Zlib::GzipReader.new(File.new(abspath)).read)
76
+ end
77
+ add_resource(r)
78
+
79
+ end
80
+
81
+ # add resource
82
+ # any resource of the same location
83
+ # is overwritten
84
+ def add_resource(r)
85
+ # first check if this resource is already in
86
+ # if yes then override it
87
+ if (index = @resources.index(r)).nil?
88
+ # add it
89
+ @resources << r
90
+ else
91
+ # replace it
92
+ #log.warn("Resource #{r.location} already exists. Replacing.")
93
+ @resources[index] = r
94
+ end
95
+ end
96
+
97
+ # read data from a file
98
+ def read_file(file)
99
+ doc = REXML::Document.new(file)
100
+ doc.elements.each('repomd/data') do |datael|
101
+ resource = Resource.new
102
+ resource.type = datael.attributes['type']
103
+ datael.elements.each do |attrel|
104
+ case attrel.name
105
+ when 'location'
106
+ resource.location = attrel.attributes['href']
107
+ when 'checksum'
108
+ resource.checksum = attrel.text
109
+ when 'timestamp'
110
+ resource.timestamp = attrel.text
111
+ when 'open-checksum'
112
+ resource.openchecksum = attrel.text
113
+ else
114
+ raise "unknown tag #{attrel.name}"
115
+ end # case
116
+ end # iterate over data subelements
117
+ add_resource(resource)
118
+ end # iterate over data elements
119
+ end
120
+
121
+ # write the index to xml file
122
+ def write(file)
123
+ builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
124
+ builder.instruct!
125
+ xml = builder.repomd('xmlns' => "http://linux.duke.edu/metadata/repo") do |b|
126
+ @resources.each do |resource|
127
+ b.data('type' => resource.type) do |b|
128
+ b.location('href' => resource.location)
129
+ b.checksum(resource.checksum, 'type' => 'sha')
130
+ b.timestamp(resource.timestamp)
131
+ b.tag!('open-checksum', resource.openchecksum, 'type' => 'sha')
132
+ end
133
+ end
134
+
135
+ end #builder
136
+
137
+ end
138
+
139
+ end
140
+
141
+
142
+ end
143
+
144
+ end
@@ -0,0 +1,69 @@
1
+ #--
2
+ #
3
+ # enhancerepo is a rpm-md repository metadata tool.
4
+ # Copyright (C) 2008, 2009 Novell Inc.
5
+ # Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
21
+ # also available at http://www.gnu.org/copyleft/gpl.html.
22
+ #
23
+ #++
24
+ #
25
+ module EnhanceRepo
26
+ module RpmMd
27
+ # represents
28
+ # filelist data
29
+ #
30
+ # See:
31
+ # http://en.opensuse.org/Standards/Rpm_Metadata
32
+ #
33
+ class Other < Data
34
+
35
+ def initialize(dir)
36
+ @dir = dir
37
+ @rpmfiles = []
38
+ end
39
+
40
+ def read
41
+ Dir["#{@dir}/**/*.rpm"].each do |rpmfile|
42
+ @rpmfiles << rpmfile
43
+ end
44
+ end
45
+
46
+ def empty?
47
+ @rpmfiles.empty?
48
+ end
49
+
50
+ # write filelists.xml
51
+ def write(file)
52
+ builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
53
+ builder.instruct!
54
+ xml = builder.tag!("otherdata", 'xmlns' => 'xmlns="http://linux.duke.edu/metadata/other"', 'packages'=> @rpmfiles.size ) do |b|
55
+ @rpmfiles.each do |rpmfile|
56
+ pkgid = PackageId.new(rpmfile)
57
+ b.package('pkgid'=>pkgid.checksum, 'name' => pkgid.name, 'arch'=>pkgid.arch ) do | b |
58
+ b.version('epoch' => pkgid.version.e, 'ver' => pkgid.version.v, 'rel' => pkgid.version.r)
59
+ end
60
+ # done package tag
61
+ end
62
+ # next package
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,123 @@
1
+ #--
2
+ #
3
+ # enhancerepo is a rpm-md repository metadata tool.
4
+ # Copyright (C) 2008, 2009 Novell Inc.
5
+ # Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
+ # MA 02110-1301, USA. A copy of the GNU General Public License is
21
+ # also available at http://www.gnu.org/copyleft/gpl.html.
22
+ #
23
+ #++
24
+ #
25
+ module EnhanceRepo
26
+ module RpmMd
27
+ # represents
28
+ # primary data
29
+ #
30
+ # See:
31
+ # http://en.opensuse.org/Standards/Rpm_Metadata
32
+ #
33
+ class Primary < Data
34
+ attr_accessor :indent
35
+
36
+ def initialize(dir)
37
+ @indent = false
38
+ @dir = dir
39
+ @rpmfiles = []
40
+ end
41
+
42
+ def read_packages
43
+ Dir["#{@dir}/**/*.rpm"].each do |rpmfile|
44
+ @rpmfiles << rpmfile
45
+ end
46
+ end
47
+
48
+ def size
49
+ @rpmfiles.size
50
+ end
51
+
52
+ def empty?
53
+ @rpmfiles.empty?
54
+ end
55
+
56
+ def write_package(file, rpmfile)
57
+ b = Builder::XmlMarkup.new(:target=>file, :indent=> @indent ? 2 : 0, :indent=> @indent ? 2 : 0)
58
+ b.package('type' => 'rpm') do | b |
59
+ pkgid = PackageId.new(rpmfile)
60
+ b.name pkgid.name
61
+ b.arch pkgid.arch
62
+ b.version('epoch' => pkgid.version.e.nil? ? "0" : pkgid.version.e.to_s, 'ver' => pkgid.version.v, 'rel' => pkgid.version.r)
63
+ b.checksum(pkgid.checksum, 'type'=>'sha', 'pkgid'=>'YES')
64
+ b.summary pkgid[RPM::TAG_SUMMARY]
65
+ b.description pkgid[RPM::TAG_DESCRIPTION]
66
+ b.packager pkgid[RPM::TAG_PACKAGER]
67
+ b.url pkgid[RPM::TAG_URL]
68
+ b.time('file'=>File.mtime(rpmfile).to_i, 'build'=>pkgid[RPM::TAG_BUILDTIME])
69
+ b.tag!('size', 'archive'=>pkgid[RPM::TAG_ARCHIVESIZE], 'installed'=>pkgid[RPM::TAG_SIZE], 'package'=>File.size(rpmfile))
70
+ b.location('href'=>File.basename(rpmfile))
71
+ # now the format tags
72
+ b.format do |b|
73
+ b.tag!('rpm:license', pkgid[RPM::TAG_LICENSE])
74
+ b.tag!('rpm:vendor', pkgid[RPM::TAG_VENDOR])
75
+ b.tag!('rpm:group', pkgid[RPM::TAG_GROUP])
76
+ b.tag!('rpm:buildhost', pkgid[RPM::TAG_BUILDHOST])
77
+ b.tag!('rpm:sourcerpm', pkgid[RPM::TAG_SOURCERPM])
78
+ #b.tag!('rpm:header-range', pkgid[RPM::TAG_SOURCERPM])
79
+
80
+ # serialize dependencies
81
+ [:provides, :requires, :obsoletes, :conflicts, :obsoletes].each do |deptype|
82
+ b.tag!("rpm:#{deptype}") do |b|
83
+ pkgid.send(deptype).reverse.each { |dep|
84
+ flag = nil
85
+ flag = 'LT' if dep.lt?
86
+ flag = 'GT' if dep.gt?
87
+ flag = 'EQ' if dep.eq?
88
+ flag = 'LE' if dep.le?
89
+ flag = 'GE' if dep.ge?
90
+ attrs = {'name'=>dep.name}
91
+ if not flag.nil?
92
+ attrs['pre'] = 1 if (deptype == :requires) and dep.pre?
93
+ attrs['flags'] = flag
94
+ attrs['ver'] =dep.version.v
95
+ attrs['epoch'] = dep.version.e.nil? ? "0" : dep.version.e.to_s
96
+ attrs['rel'] =dep.version.r
97
+ end
98
+ b.tag!('rpm:entry', attrs)
99
+ }
100
+ end
101
+ #####
102
+ end
103
+ end
104
+ # done with format section
105
+ end
106
+ # done package tag
107
+ end
108
+
109
+ # write primary.xml
110
+ def write(file)
111
+ builder = Builder::XmlMarkup.new(:target=>file, :indent=> @indent ? 2 : 0)
112
+ builder.instruct!
113
+ builder.tag!("metadata", 'xmlns' => 'http://linux.duke.edu/metadata/common', 'xmlns:rpm' => 'http://linux.duke.edu/metadata/rpm', 'xmlns:suse'=>'http://novell.com/package/metadata/suse/common', 'packages'=> @rpmfiles.size ) do |b|
114
+ @rpmfiles.each do |rpmfile|
115
+ write_package(file, rpmfile)
116
+ end
117
+ end# next package
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+ end