enhancerepo 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +18 -0
- data/Manifest.txt +85 -0
- data/README +10 -0
- data/README.rdoc +15 -0
- data/Rakefile +48 -0
- data/TODO.rdoc +4 -0
- data/bin/enhancerepo +4 -0
- data/lib/enhance_repo.rb +36 -0
- data/lib/enhance_repo/cli.rb +150 -0
- data/lib/enhance_repo/config_opts.rb +98 -0
- data/lib/enhance_repo/logger.rb +67 -0
- data/lib/enhance_repo/other.rb +80 -0
- data/lib/enhance_repo/package_id.rb +81 -0
- data/lib/enhance_repo/product_id.rb +30 -0
- data/lib/enhance_repo/rpm_md.rb +27 -0
- data/lib/enhance_repo/rpm_md/data.rb +55 -0
- data/lib/enhance_repo/rpm_md/delta_info.rb +205 -0
- data/lib/enhance_repo/rpm_md/extra_primary_data.rb +45 -0
- data/lib/enhance_repo/rpm_md/file_lists.rb +81 -0
- data/lib/enhance_repo/rpm_md/index.rb +144 -0
- data/lib/enhance_repo/rpm_md/other.rb +69 -0
- data/lib/enhance_repo/rpm_md/primary.rb +123 -0
- data/lib/enhance_repo/rpm_md/products.rb +142 -0
- data/lib/enhance_repo/rpm_md/repo.rb +202 -0
- data/lib/enhance_repo/rpm_md/resource.rb +44 -0
- data/lib/enhance_repo/rpm_md/suse_data.rb +191 -0
- data/lib/enhance_repo/rpm_md/suse_info.rb +88 -0
- data/lib/enhance_repo/rpm_md/update.rb +141 -0
- data/lib/enhance_repo/rpm_md/update_info.rb +244 -0
- data/lib/enhance_repo/rpm_md/update_smart_fields.rb +127 -0
- data/lib/enhance_repo/xml_comparer.rb +117 -0
- data/lib/tempdir.rb +62 -0
- data/lib/tempdir/tempfile.rb +21 -0
- data/test/all_tests.rb +27 -0
- data/test/data/packages/a-1.0.spec +19 -0
- data/test/data/packages/a-2.0.spec +24 -0
- data/test/data/repodata/update-test-11.1/filelists.xml.gz +0 -0
- data/test/data/repodata/update-test-11.1/other.xml.gz +0 -0
- data/test/data/repodata/update-test-11.1/primary.xml.gz +0 -0
- data/test/data/repodata/update-test-11.1/repomd.xml +21 -0
- data/test/data/repomd.xml +21 -0
- data/test/data/rpms/repo-1/a-1.0-0.x86_64.rpm +0 -0
- data/test/data/rpms/repo-1/a-1.0_2.0-0_0.x86_64.delta.rpm +0 -0
- data/test/data/rpms/repo-1/a-2.0-0.x86_64.rpm +0 -0
- data/test/data/rpms/repo-1/repodata/deltainfo.xml.gz +0 -0
- data/test/data/rpms/repo-1/repodata/deltainfo.xml.gz.gz +0 -0
- data/test/data/rpms/repo-1/repodata/filelists.xml.gz +0 -0
- data/test/data/rpms/repo-1/repodata/other.xml.gz +0 -0
- data/test/data/rpms/repo-1/repodata/primary.xml.gz +0 -0
- data/test/data/rpms/repo-1/repodata/repomd.xml +45 -0
- data/test/data/rpms/repo-1/repodata/susedata.xml.gz +0 -0
- data/test/data/rpms/repo-1/repodata/updateinfo.xml.gz +0 -0
- data/test/data/rpms/repo-1/repoparts/update-a-1.xml +22 -0
- data/test/data/rpms/repo-with-product/a-1.0-0.x86_64.rpm +0 -0
- data/test/data/rpms/repo-with-product/openSUSE-release-11.2-1.6.i586.rpm +0 -0
- data/test/data/rpms/repo-with-product/openSUSE-release-dvd-11.2-1.6.i586.rpm +0 -0
- data/test/data/rpms/repo-with-product/repodata/filelists.xml.gz +0 -0
- data/test/data/rpms/repo-with-product/repodata/other.xml.gz +0 -0
- data/test/data/rpms/repo-with-product/repodata/primary.xml.gz +0 -0
- data/test/data/rpms/repo-with-product/repodata/products.xml.gz +0 -0
- data/test/data/rpms/repo-with-product/repodata/repomd.xml +27 -0
- data/test/data/rpms/update-test-11.1/update-test-affects-package-manager.rpm +0 -0
- data/test/data/rpms/update-test-11.1/update-test-interactive.rpm +0 -0
- data/test/data/rpms/update-test-11.1/update-test-optional.rpm +0 -0
- data/test/data/rpms/update-test-11.1/update-test-reboot-needed.rpm +0 -0
- data/test/data/rpms/update-test-11.1/update-test-security.rpm +0 -0
- data/test/data/rpms/update-test-11.1/update-test-trival.rpm +0 -0
- data/test/data/rpms/update-test-factory/update-test-affects-package-manager-0-9999.1.2.noarch.rpm +0 -0
- data/test/data/rpms/update-test-factory/update-test-interactive-0-9999.1.2.noarch.rpm +0 -0
- data/test/data/rpms/update-test-factory/update-test-optional-0-9999.1.2.noarch.rpm +0 -0
- data/test/data/rpms/update-test-factory/update-test-reboot-needed-0-9999.1.2.noarch.rpm +0 -0
- data/test/data/rpms/update-test-factory/update-test-relogin-suggested-0-9999.1.2.noarch.rpm +0 -0
- data/test/data/rpms/update-test-factory/update-test-security-0-9999.1.2.noarch.rpm +0 -0
- data/test/deltainfo_test.rb +50 -0
- data/test/extensions_test.rb +31 -0
- data/test/index_test.rb +51 -0
- data/test/primary_test.rb +51 -0
- data/test/products_test.rb +51 -0
- data/test/repo_test.rb +72 -0
- data/test/repomdindex_test.rb +58 -0
- data/test/rpmmd_test.rb +60 -0
- data/test/susedata_test.rb +53 -0
- data/test/tempdir_test.rb +62 -0
- data/test/test_helper.rb +53 -0
- data/test/update_test.rb +80 -0
- data/test/updateinfo_test.rb +59 -0
- metadata +267 -0
@@ -0,0 +1,88 @@
|
|
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 SUSE extensions to repository
|
33
|
+
# metadata (not associated with packages)
|
34
|
+
#
|
35
|
+
# See:
|
36
|
+
# http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29
|
37
|
+
#
|
38
|
+
class SuseInfo < Data
|
39
|
+
|
40
|
+
# expiration time
|
41
|
+
# the generated value is
|
42
|
+
# still calculated from repomd.xml
|
43
|
+
# resources
|
44
|
+
attr_accessor :expire
|
45
|
+
attr_accessor :products
|
46
|
+
attr_accessor :keywords
|
47
|
+
|
48
|
+
def initialize(dir)
|
49
|
+
@dir = dir
|
50
|
+
@expire = nil
|
51
|
+
@keywords = Set.new
|
52
|
+
@products = Set.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def empty?
|
56
|
+
@expire.nil? and @products.empty? and @keywords.empty?
|
57
|
+
end
|
58
|
+
|
59
|
+
def write(file)
|
60
|
+
builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
|
61
|
+
builder.instruct!
|
62
|
+
xml = builder.suseinfo do |b|
|
63
|
+
|
64
|
+
# add expire tag
|
65
|
+
b.expire(@expire.to_i.to_s) if not @expire.nil?
|
66
|
+
|
67
|
+
if not @keywords.empty?
|
68
|
+
b.keywords do |b|
|
69
|
+
@keywords.each do |k|
|
70
|
+
b.k(k)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if not @products.empty?
|
76
|
+
b.products do |b|
|
77
|
+
@products.each do |p|
|
78
|
+
b.id(p)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
#--
|
2
|
+
#
|
3
|
+
# enhancerepo is a rpm-md repository metadata tool.
|
4
|
+
# Copyright (C) 2008, 2009 Novell Inc.
|
5
|
+
# Copyright (C) 2009, Jordi Massager Pla <jordi.massagerpla@opensuse.org>
|
6
|
+
#
|
7
|
+
# Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
|
8
|
+
# Jordi Massager Pla <jordi.massagerpla@opensuse.org>
|
9
|
+
#
|
10
|
+
# This program is free software; you can redistribute it and/or modify
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
12
|
+
# the Free Software Foundation; either version 2 of the License, or
|
13
|
+
# (at your option) any later version.
|
14
|
+
#
|
15
|
+
# This program is distributed in the hope that it will be useful,
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
# GNU General Public License for more details.
|
19
|
+
#
|
20
|
+
# You should have received a copy of the GNU General Public License
|
21
|
+
# along with this program; if not, write to the Free Software
|
22
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
23
|
+
# MA 02110-1301, USA. A copy of the GNU General Public License is
|
24
|
+
# also available at http://www.gnu.org/copyleft/gpl.html.
|
25
|
+
#
|
26
|
+
#++
|
27
|
+
#
|
28
|
+
|
29
|
+
require 'rubygems'
|
30
|
+
require 'active_support/core_ext/module/attr_accessor_with_default'
|
31
|
+
require 'builder'
|
32
|
+
require 'rexml/document'
|
33
|
+
require 'yaml'
|
34
|
+
require 'prettyprint'
|
35
|
+
require 'set'
|
36
|
+
|
37
|
+
require 'enhance_repo/rpm_md/update_smart_fields'
|
38
|
+
|
39
|
+
module EnhanceRepo
|
40
|
+
module RpmMd
|
41
|
+
|
42
|
+
#
|
43
|
+
# Represents a reference to a external bugreport
|
44
|
+
# feature or issue for a software update
|
45
|
+
#
|
46
|
+
class Reference
|
47
|
+
# uri of the reference
|
48
|
+
attr_accessor :href
|
49
|
+
# its type, for example, bnc (novell's bugzilla)
|
50
|
+
attr_accessor :type
|
51
|
+
# the id, for example 34561
|
52
|
+
# the pair type-id should be globally unique
|
53
|
+
attr_accessor :referenceid
|
54
|
+
# label to display to the user
|
55
|
+
attr_accessor :title
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"#{type}##{referenceid}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# initialize a reference, per default a novell
|
62
|
+
# bugzilla type
|
63
|
+
def initialize
|
64
|
+
@href = "http://bugzilla.novell.com"
|
65
|
+
@referenceid = "none"
|
66
|
+
@title = ""
|
67
|
+
@type = "bugzilla"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# represents one update, which can consist of various packages
|
72
|
+
# and references
|
73
|
+
class Update
|
74
|
+
|
75
|
+
# methods to automatically grab data from the
|
76
|
+
# update description
|
77
|
+
include UpdateSmartFields
|
78
|
+
|
79
|
+
attr_accessor_with_default :updateid, "unknown"
|
80
|
+
attr_accessor_with_default :status, "stable"
|
81
|
+
attr_accessor_with_default :from, "#{ENV['USER']}@#{ENV['HOST']}"
|
82
|
+
attr_accessor_with_default :type, "optional"
|
83
|
+
attr_accessor_with_default :version, 1
|
84
|
+
attr_accessor_with_default :release, "unknown"
|
85
|
+
attr_accessor_with_default :issued, Time.now.to_i
|
86
|
+
attr_accessor_with_default :references, []
|
87
|
+
attr_accessor_with_default :description, ""
|
88
|
+
attr_accessor_with_default :title, "untitled update"
|
89
|
+
attr_accessor_with_default :packages, []
|
90
|
+
|
91
|
+
def initialize
|
92
|
+
end
|
93
|
+
|
94
|
+
# an update is not empty if it
|
95
|
+
# updates something
|
96
|
+
def empty?
|
97
|
+
packages.empty?
|
98
|
+
end
|
99
|
+
|
100
|
+
def suggested_filename
|
101
|
+
"update-#{updateid}-#{version}"
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# write a update out
|
106
|
+
def write(file)
|
107
|
+
builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
|
108
|
+
append_to_builder(builder)
|
109
|
+
end
|
110
|
+
|
111
|
+
def append_to_builder(builder)
|
112
|
+
builder.update('status' => 'stable', 'from' => from, 'version' => version, 'type' => type) do |b|
|
113
|
+
b.title(title)
|
114
|
+
b.id(updateid)
|
115
|
+
b.issued(issued)
|
116
|
+
b.release(release)
|
117
|
+
b.description(description)
|
118
|
+
# serialize attr_reader :eferences
|
119
|
+
b.references do |b|
|
120
|
+
references.each do |r|
|
121
|
+
b.reference('href' => r.href, 'id' => r.referenceid, 'title' => r.title, 'type' => r.type )
|
122
|
+
end
|
123
|
+
end
|
124
|
+
# done with references
|
125
|
+
b.pkglist do |b|
|
126
|
+
b.collection do |b|
|
127
|
+
packages.each do |pkg|
|
128
|
+
b.package('name' => pkg.name, 'arch'=> pkg.arch, 'version'=>pkg.version.v, 'release'=>pkg.version.r) do |b|
|
129
|
+
b.filename(File.basename(pkg.path))
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end # </collection>
|
133
|
+
end #</pkglist>
|
134
|
+
# done with the packagelist
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
#--
|
2
|
+
#
|
3
|
+
# enhancerepo is a rpm-md repository metadata tool.
|
4
|
+
# Copyright (C) 2008, 2009 Novell Inc.
|
5
|
+
# Copyright (C) 2009, Jordi Massager Pla <jordi.massagerpla@opensuse.org>
|
6
|
+
#
|
7
|
+
# Author: Duncan Mac-Vicar P. <dmacvicar@suse.de>
|
8
|
+
# Jordi Massager Pla <jordi.massagerpla@opensuse.org>
|
9
|
+
#
|
10
|
+
# This program is free software; you can redistribute it and/or modify
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
12
|
+
# the Free Software Foundation; either version 2 of the License, or
|
13
|
+
# (at your option) any later version.
|
14
|
+
#
|
15
|
+
# This program is distributed in the hope that it will be useful,
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
# GNU General Public License for more details.
|
19
|
+
#
|
20
|
+
# You should have received a copy of the GNU General Public License
|
21
|
+
# along with this program; if not, write to the Free Software
|
22
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
23
|
+
# MA 02110-1301, USA. A copy of the GNU General Public License is
|
24
|
+
# also available at http://www.gnu.org/copyleft/gpl.html.
|
25
|
+
#
|
26
|
+
#++
|
27
|
+
#
|
28
|
+
|
29
|
+
require 'rubygems'
|
30
|
+
require 'builder'
|
31
|
+
require 'rexml/document'
|
32
|
+
require 'yaml'
|
33
|
+
require 'prettyprint'
|
34
|
+
require 'fileutils'
|
35
|
+
require 'zlib'
|
36
|
+
require 'enhance_repo/rpm_md/update'
|
37
|
+
|
38
|
+
module EnhanceRepo
|
39
|
+
module RpmMd
|
40
|
+
|
41
|
+
class UpdateInfo < Data
|
42
|
+
|
43
|
+
def initialize(config)
|
44
|
+
@dir = config.dir
|
45
|
+
@basedir = config.updatesbasedir
|
46
|
+
|
47
|
+
# update files
|
48
|
+
@updates = Set.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def empty?
|
52
|
+
@updates.empty?
|
53
|
+
end
|
54
|
+
|
55
|
+
def size
|
56
|
+
@updates.size
|
57
|
+
end
|
58
|
+
|
59
|
+
# add all updates in a repoparts directory
|
60
|
+
# by default look in repoparts/
|
61
|
+
# otherwise pass the :repoparts_path option
|
62
|
+
def read_repoparts(opts={})
|
63
|
+
repoparts_path = opts[:repoparts_path] || File.join(@dir, 'repoparts')
|
64
|
+
log.info "Reading update parts from #{repoparts_path}"
|
65
|
+
Dir[File.join(repoparts_path, 'update-*.xml')].each do |updatefile|
|
66
|
+
log.info("`-> adding update #{updatefile}")
|
67
|
+
@updates << updatefile
|
68
|
+
end
|
69
|
+
# end of directory iteration
|
70
|
+
end
|
71
|
+
|
72
|
+
# generates a patch from a list of package names
|
73
|
+
# it compares the last version of those package names
|
74
|
+
# with their previous ones
|
75
|
+
#
|
76
|
+
# outputdir is the directory where to save the patch to.
|
77
|
+
def generate_update(packages, outputdir)
|
78
|
+
|
79
|
+
# make a hash name -> array of packages
|
80
|
+
log.info "Generating update part to #{outputdir} for packages #{packages.join(", ")}"
|
81
|
+
package_index = {}
|
82
|
+
|
83
|
+
# look all rpms in the old packages base directory plus
|
84
|
+
# the ones in the current one
|
85
|
+
rpmfiles = [ Dir["#{@dir}/**/*.rpm"], @basedir.nil? ? [] : Dir["#{@basedir}/**/*.rpm"]].flatten
|
86
|
+
log.info "`-> #{rpmfiles.size} rpm packages"
|
87
|
+
# reject unwanted files
|
88
|
+
rpmfiles.reject! do |rpmfile|
|
89
|
+
reject = false
|
90
|
+
# reject all delta and src rpms
|
91
|
+
reject = true if rpmfile =~ /\.delta\.rpm$|\.src\.rpm$/
|
92
|
+
# now reject all the packages for which the rpm file name
|
93
|
+
# does not match the name of the requested packages
|
94
|
+
# so if packages is A, B and we have C-1.0.rpm it does not
|
95
|
+
# match either /A/ nor /B/ so we reject it.
|
96
|
+
reject = true if packages.select { |pkg| rpmfile =~ /#{pkg.gsub(/\+/, "\\\\+")}/ }.empty?
|
97
|
+
reject
|
98
|
+
end
|
99
|
+
|
100
|
+
log.info "`-> #{rpmfiles.size} rpm packages were not discarded"
|
101
|
+
log.debug " #{rpmfiles.map { |x| File.basename(x) }.join(', ')}"
|
102
|
+
|
103
|
+
# now index all rpms per package name in a hash table
|
104
|
+
# which goes from name => list of versions
|
105
|
+
rpmfiles.each do |rpmfile|
|
106
|
+
rpm = PackageId.new(rpmfile)
|
107
|
+
# now that we have the real name, reject if it is not part
|
108
|
+
# of the requested packages to generate updates for
|
109
|
+
next if not packages.include?(rpm.name)
|
110
|
+
|
111
|
+
package_index[rpm.name] = Array.new if not package_index.has_key?(rpm.name)
|
112
|
+
# add the rpm if there is no other rpm with the same version
|
113
|
+
package_index[rpm.name] << rpm if not package_index[rpm.name].select { |x| x.version == rpm.version && x.name == rpm.name }.first
|
114
|
+
end
|
115
|
+
|
116
|
+
log.info "`-> indexed #{package_index.size} unique packages from #{rpmfiles.size} rpms"
|
117
|
+
log.debug " #{package_index.keys.join(', ')}"
|
118
|
+
# do our package hash include every package?
|
119
|
+
packages.reject! do |pkg|
|
120
|
+
reject = false
|
121
|
+
if not package_index.has_key?(pkg)
|
122
|
+
log.warn "`-> the package '#{pkg}' is not available in the repository."
|
123
|
+
reject = true
|
124
|
+
end
|
125
|
+
reject
|
126
|
+
end
|
127
|
+
|
128
|
+
update = Update.new
|
129
|
+
|
130
|
+
packages.each do |pkgname|
|
131
|
+
pkglist = package_index[pkgname]
|
132
|
+
log.info "`-> #{pkglist.size} versions for '#{pkgname}'"
|
133
|
+
log.debug " #{package_index[pkgname].map {|x| x.version}.join(", ")}"
|
134
|
+
# sort them by version
|
135
|
+
pkglist.sort! { |a,b| a.version <=> b.version }
|
136
|
+
pkglist.reverse!
|
137
|
+
# now that the list is sorted, the new rpm is the first
|
138
|
+
|
139
|
+
# if there is only one package then we don't need changelog
|
140
|
+
if pkglist.size > 1
|
141
|
+
# we know that there are no duplicate versions so we can
|
142
|
+
# take the first and the second
|
143
|
+
first = pkglist.shift
|
144
|
+
second = pkglist.shift
|
145
|
+
diff = first.changelog - second.changelog || []
|
146
|
+
#diff = first.changelog[0, first.changelog.size - second.changelog.size] || []
|
147
|
+
log.info "`-> found change #{first.ident} and #{second.ident}."
|
148
|
+
|
149
|
+
log.info "`-> '#{pkgname}' has #{diff.size} change entries (#{first.changelog.size}/#{second.changelog.size})"
|
150
|
+
update.packages << first
|
151
|
+
diff.each do |entry|
|
152
|
+
update.description << entry.text << "\n"
|
153
|
+
end
|
154
|
+
else
|
155
|
+
# jump to next pkgname
|
156
|
+
next
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
# do not save it if there are no packages
|
162
|
+
if update.empty?
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
# before writing the update, figure out more
|
167
|
+
# information
|
168
|
+
update.smart_fill_blank_fields
|
169
|
+
|
170
|
+
log.info "`-> update has #{update.references.size} references"
|
171
|
+
log.debug " #{update.references.join(',')} "
|
172
|
+
|
173
|
+
filename = ""
|
174
|
+
|
175
|
+
FileUtils.mkdir_p outputdir
|
176
|
+
# increase version until version is available
|
177
|
+
while ( File.exists?(filename = File.join(outputdir, update.suggested_filename + ".xml") ))
|
178
|
+
update.version += 1
|
179
|
+
end
|
180
|
+
log.info "Saving update part to '#{filename}'."
|
181
|
+
|
182
|
+
File.open(filename, 'w') do |f|
|
183
|
+
update.write(f)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# splits the updateinfo file into serveral update files
|
188
|
+
# it writes those files into outputdir
|
189
|
+
# output filenames will be id+_splited_version.xml
|
190
|
+
# where id is the update id
|
191
|
+
# version is incremented when there is others update files
|
192
|
+
# with the same id
|
193
|
+
#
|
194
|
+
# outputdir is the directory where to save the patch to.
|
195
|
+
def split_updates(outputdir)
|
196
|
+
FileUtils.mkdir_p outputdir
|
197
|
+
updateinfofile = File.join(@dir, metadata_filename)
|
198
|
+
|
199
|
+
# we can't split without an updateinfo file
|
200
|
+
raise "#{updateinfofile} does not exist" if not File.exist?(updateinfofile)
|
201
|
+
Zlib::GzipReader.open(updateinfofile) do |gz|
|
202
|
+
document = REXML::Document.new(gz)
|
203
|
+
root = document.root
|
204
|
+
root.each_element("update") do |updateElement|
|
205
|
+
id = nil
|
206
|
+
updateElement.each_element("id") do |elementId|
|
207
|
+
id = elementId.text
|
208
|
+
end
|
209
|
+
if id == nil
|
210
|
+
log.warning 'No id found. Setting id to NON_ID_FOUND'
|
211
|
+
id = 'NON_ID_FOUND'
|
212
|
+
end
|
213
|
+
version = 0
|
214
|
+
updatefilename = ""
|
215
|
+
while ( File.exists?(updatefilename = File.join(outputdir, "update-#{id}_splited_#{version.to_s}.xml") ) )
|
216
|
+
version += 1
|
217
|
+
end
|
218
|
+
log.info "Saving update part to '#{updatefilename}'."
|
219
|
+
File.open(updatefilename, 'w') do |updatefile|
|
220
|
+
updatefile << updateElement
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# write a update out
|
227
|
+
def write(file)
|
228
|
+
builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
|
229
|
+
builder.instruct!
|
230
|
+
xml = builder.updates do |b|
|
231
|
+
@updates.each do |update|
|
232
|
+
File.open(update) do |f|
|
233
|
+
file << f.read
|
234
|
+
end
|
235
|
+
#update.append_to_builder(b)
|
236
|
+
end
|
237
|
+
end #done builder
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
end
|
244
|
+
end
|