enhancerepo 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|