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,67 @@
|
|
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
|
+
|
28
|
+
def self.enable_logger
|
29
|
+
# support both log4r and ruby logger
|
30
|
+
begin
|
31
|
+
require 'log4r'
|
32
|
+
include Log4r
|
33
|
+
@logger = Log4r::Logger.new 'enhancerepo'
|
34
|
+
console_format = Log4r::PatternFormatter.new(:pattern => "%l:\t %m")
|
35
|
+
@logger.add Log4r::StdoutOutputter.new('console', :formatter=>console_format)
|
36
|
+
rescue LoadError
|
37
|
+
require 'logger'
|
38
|
+
@logger = ::Logger.new(STDERR)
|
39
|
+
end
|
40
|
+
EnhanceRepo.logger.level = using_log4r? ? Log4r::INFO : ::Logger::INFO
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.using_log4r?
|
44
|
+
(! (Object.const_get(:Log4r) rescue nil).nil?)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.enable_debug
|
48
|
+
EnhanceRepo.logger.level = using_log4r? ? Log4r::DEBUG : ::Logger::DEBUG
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.logger
|
52
|
+
@logger
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.logger=(logger)
|
56
|
+
@logger = logger
|
57
|
+
end
|
58
|
+
|
59
|
+
# provide easy access to classes to the
|
60
|
+
# global logger
|
61
|
+
module Logger
|
62
|
+
def log
|
63
|
+
EnhanceRepo.logger
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,80 @@
|
|
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
|
+
# represents
|
27
|
+
# filelist data
|
28
|
+
#
|
29
|
+
# See:
|
30
|
+
# http://en.opensuse.org/Standards/Rpm_Metadata
|
31
|
+
#
|
32
|
+
class Other
|
33
|
+
|
34
|
+
def initialize(dir)
|
35
|
+
@dir = dir
|
36
|
+
@rpmfiles = []
|
37
|
+
end
|
38
|
+
|
39
|
+
def read
|
40
|
+
Dir["#{@dir}/**/*.rpm"].each do |rpmfile|
|
41
|
+
@rpmfiles << rpmfile
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def empty?
|
46
|
+
@rpmfiles.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
def write_package(file, rpmfile)
|
50
|
+
b = Builder::XmlMarkup.new(:target=>file, :indent=>2, :initial=>2)
|
51
|
+
pkgid = PackageId.new(rpmfile)
|
52
|
+
puts pkgid.rpm.methods.sort
|
53
|
+
pkgid[RPM::TAG_CHANGELOGTEXT].each do |ch|
|
54
|
+
puts ch
|
55
|
+
end
|
56
|
+
exit
|
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
|
+
end
|
64
|
+
|
65
|
+
# write filelists.xml
|
66
|
+
def write(file)
|
67
|
+
#builder = Builder::XmlMarkup.new(:target=>file, :indent=>2)
|
68
|
+
#builder.instruct!
|
69
|
+
#xml = builder.tag!("otherdata", 'xmlns' => 'xmlns="http://linux.duke.edu/metadata/other"', 'packages'=> @rpmfiles.size ) do |b|
|
70
|
+
@rpmfiles.each do |rpmfile|
|
71
|
+
# done package tag
|
72
|
+
write_package(file, rpmfile)
|
73
|
+
end
|
74
|
+
# next package
|
75
|
+
#end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
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
|
+
require 'digest/sha1'
|
27
|
+
require 'rpm'
|
28
|
+
|
29
|
+
module EnhanceRepo
|
30
|
+
|
31
|
+
# thin wrapper over rpm package
|
32
|
+
class PackageId
|
33
|
+
attr_accessor :checksum
|
34
|
+
attr_accessor :path
|
35
|
+
attr_accessor :rpm
|
36
|
+
|
37
|
+
def initialize(rpmfile)
|
38
|
+
@path = rpmfile
|
39
|
+
@rpm = RPM::Package.open(rpmfile)
|
40
|
+
@checksum = Digest::SHA1.hexdigest(File.new(rpmfile).read)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Forward other methods
|
44
|
+
def method_missing(sym, *args)
|
45
|
+
@rpm.send(sym, *args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def hash
|
49
|
+
@checksum.hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def eql?(other)
|
53
|
+
@checksum == other.checksum
|
54
|
+
end
|
55
|
+
|
56
|
+
# match function at name and nvr level
|
57
|
+
def matches(ident)
|
58
|
+
# if the name matches, then it is sufficient
|
59
|
+
return true if ident == @rpm.name
|
60
|
+
# if not, compare the edition without release
|
61
|
+
return true if ident == "#{@rpm.name}-#{@rpm.version.v}"
|
62
|
+
# if not, compare the edition with release
|
63
|
+
return true if ident == "#{@rpm.name}-#{@rpm.version.v}-#{@rpm.version.r}"
|
64
|
+
# if not, also the architecture
|
65
|
+
return true if ident == "#{@rpm.name}-#{@rpm.version.v}-#{@rpm.version.r}"
|
66
|
+
# and finally arch
|
67
|
+
return true if ident == "#{@rpm.name}-#{@rpm.version.v}-#{@rpm.version.r}.#{@rpm.arch}"
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
@rpm.to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
def ident
|
76
|
+
"#{@rpm.to_s}.#{@rpm.arch}"
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
class ProductId
|
27
|
+
attr_accessor :label
|
28
|
+
attr_accessor :cpeid
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
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
|
+
lib = File.dirname(__FILE__)
|
26
|
+
|
27
|
+
require File.join(lib, 'rpm_md', 'repo.rb')
|
@@ -0,0 +1,55 @@
|
|
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 a metadata unit
|
30
|
+
class Data
|
31
|
+
include Logger
|
32
|
+
|
33
|
+
# initialize the extra data with a name
|
34
|
+
# or use the class name as default
|
35
|
+
def initialize(name)
|
36
|
+
@name = name
|
37
|
+
end
|
38
|
+
|
39
|
+
def name
|
40
|
+
defined?(@name) ? @name : self.class.to_s.split("::").last.downcase
|
41
|
+
end
|
42
|
+
|
43
|
+
def metadata_filename
|
44
|
+
"repodata/#{name}.xml#{should_compress? ? '.gz' : ''}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# wether the metadata should be compressed
|
48
|
+
def should_compress?
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,205 @@
|
|
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 'nokogiri'
|
28
|
+
require 'yaml'
|
29
|
+
require 'rpm'
|
30
|
+
require 'pp'
|
31
|
+
require 'pathname'
|
32
|
+
|
33
|
+
module EnhanceRepo
|
34
|
+
module RpmMd
|
35
|
+
|
36
|
+
include REXML
|
37
|
+
|
38
|
+
class DeltaRpm < PackageId
|
39
|
+
attr_accessor :sequence, :sourcerpm
|
40
|
+
|
41
|
+
def initialize(filename)
|
42
|
+
super(filename)
|
43
|
+
`applydeltarpm -i '#{filename}'`.each_line do |line|
|
44
|
+
key, value = line.chop.split(':')
|
45
|
+
value.gsub!(/ /, '')
|
46
|
+
@sequence = value if key == "sequence"
|
47
|
+
@sourcerpm = value if key == "source rpm"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def hash
|
52
|
+
ident.hash
|
53
|
+
end
|
54
|
+
|
55
|
+
def eql?(other)
|
56
|
+
ident == other.ident
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
class DeltaInfo < Data
|
62
|
+
|
63
|
+
def initialize(dir)
|
64
|
+
@dir = dir
|
65
|
+
# here we store known deltas
|
66
|
+
# we index by new package
|
67
|
+
# and in every slot we store an
|
68
|
+
# array with such deltas
|
69
|
+
@deltas = Hash.new
|
70
|
+
end
|
71
|
+
|
72
|
+
def delta_count
|
73
|
+
@deltas.size
|
74
|
+
end
|
75
|
+
|
76
|
+
def empty?
|
77
|
+
return @deltas.empty?
|
78
|
+
end
|
79
|
+
|
80
|
+
# Create delta rpms for the last
|
81
|
+
# n versions of some rpm.
|
82
|
+
#
|
83
|
+
# So if you have
|
84
|
+
# foo-4.rpm
|
85
|
+
# foo-3.rpm
|
86
|
+
# foo-2.rpm
|
87
|
+
# foo-1.rpm
|
88
|
+
#
|
89
|
+
# Creating deltas with n = 1 will
|
90
|
+
# create a delta for going to
|
91
|
+
# version 3 to 4. While n = 2 would
|
92
|
+
# create a delta to go from 2 to 4 too.
|
93
|
+
#
|
94
|
+
# options are :n => number of deltas (default 1)
|
95
|
+
# and :outputdir => defaulting to the same
|
96
|
+
# input directory
|
97
|
+
def create_deltas(opts={})
|
98
|
+
outputdir = opts[:outputdir] || @dir
|
99
|
+
n = opts[:n] || 1
|
100
|
+
|
101
|
+
log.info "Scanning rpms for delta generation (#{n} levels)"
|
102
|
+
#log.info "Creating deltarpms : level #{n}"
|
103
|
+
# make a hash name -> array of packages
|
104
|
+
pkgs = Hash.new
|
105
|
+
|
106
|
+
Dir["#{@dir}/**/*.rpm"].each do |rpmfile|
|
107
|
+
#puts "Delta: #{rpmfile}"
|
108
|
+
rpm = PackageId.new(rpmfile)
|
109
|
+
|
110
|
+
pkgs[rpm.name] = Array.new if not pkgs.has_key?(rpm.name)
|
111
|
+
pkgs[rpm.name] << rpm
|
112
|
+
end
|
113
|
+
|
114
|
+
# now that we have al packages, sort them by version
|
115
|
+
pkgs.each do |pkgname, pkglist|
|
116
|
+
|
117
|
+
pkglist.sort! { |a,b| a.version <=> b.version }
|
118
|
+
pkglist.reverse!
|
119
|
+
# now that the list is sorted, the new rpm is the first
|
120
|
+
newpkg = pkglist.shift
|
121
|
+
c = 0
|
122
|
+
if not pkglist.empty?
|
123
|
+
for pkg in pkglist
|
124
|
+
break if c == n
|
125
|
+
# do not create a delta for the same package
|
126
|
+
next if newpkg.version == pkg.version
|
127
|
+
# do not create a delta for different archs
|
128
|
+
next if newpkg.arch != pkg.arch
|
129
|
+
oldpkg = pkg
|
130
|
+
# use the same dir as the new rpm
|
131
|
+
log.info "`-> creating delta - #{oldpkg.to_s} -> #{newpkg.to_s} (#{c+1}/#{n})"
|
132
|
+
# calculate directory where to save the delta. Use the newpkg
|
133
|
+
# relative to the origin directory,
|
134
|
+
# this only works because we know the rpm is inside @dir
|
135
|
+
subdir = Pathname.new(newpkg.path).relative_path_from(Pathname.new(@dir)).dirname
|
136
|
+
# calculate the deltarpm name
|
137
|
+
deltafile = File.join(outputdir, subdir, delta_package_name(oldpkg,newpkg))
|
138
|
+
FileUtils.mkdir_p File.dirname(deltafile)
|
139
|
+
#puts "makedeltarpm #{oldpkg.path} #{newpkg.path} #{deltafile}"
|
140
|
+
`makedeltarpm '#{oldpkg.path}' '#{newpkg.path}' '#{deltafile}'`
|
141
|
+
c += 1
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
# figure out the name of a delta rpm
|
150
|
+
def delta_package_name(oldpkg, newpkg)
|
151
|
+
deltarpm = ""
|
152
|
+
if ( oldpkg.version.v == newpkg.version.v )
|
153
|
+
# if the version is the same, then it is specified only once, and the range
|
154
|
+
# is used for the releases
|
155
|
+
deltarpm = "#{oldpkg.name}-#{oldpkg.version.v}-#{oldpkg.version.r}_#{newpkg.version.r}.#{oldpkg.arch}.delta.rpm"
|
156
|
+
else
|
157
|
+
deltarpm = "#{oldpkg.name}-#{oldpkg.version.v}_#{newpkg.version.v}-#{oldpkg.version.r}_#{newpkg.version.r}.#{oldpkg.arch}.delta.rpm"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_deltas
|
162
|
+
Dir["#{@dir}/**/*.delta.rpm"].each do |deltafile|
|
163
|
+
delta = DeltaRpm.new(deltafile)
|
164
|
+
#puts "Delta: #{deltafile} for '#{delta.ident}'"
|
165
|
+
@deltas[delta] = Array.new if @deltas[delta].nil?
|
166
|
+
@deltas[delta] << delta
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
# write a update out
|
172
|
+
def write(file)
|
173
|
+
builder = Nokogiri::XML::Builder.new do |b|
|
174
|
+
b.deltainfo do
|
175
|
+
@deltas.each do |ident, deltas|
|
176
|
+
b.newpackage( 'name' => ident.name, 'arch' => ident.arch,
|
177
|
+
'version' => ident.version.v,
|
178
|
+
'release' => ident.version.r ) do |b|
|
179
|
+
deltas.each do |delta|
|
180
|
+
# get the edition by getting the name out
|
181
|
+
version = RPM::Version.new(delta.sourcerpm.gsub(/#{Regexp.escape(delta.name)}-/, ''))
|
182
|
+
b.delta('oldepoch'=>0, 'oldversion'=>version.v, 'oldrelease'=>version.r) do |b|
|
183
|
+
# remove the base dir, make it relative
|
184
|
+
delta_abs_path = Pathname.new(delta.path).realpath
|
185
|
+
base_dir_abs_path = Pathname.new(@dir).realpath
|
186
|
+
relative_path = delta_abs_path.relative_path_from(base_dir_abs_path)
|
187
|
+
b.filename relative_path
|
188
|
+
b.sequence(delta.sequence)
|
189
|
+
b.size(File.size(delta.path))
|
190
|
+
b.checksum(delta.checksum, 'type'=>'sha')
|
191
|
+
end # </delta>
|
192
|
+
end
|
193
|
+
end # </newpackage>
|
194
|
+
end # each delta
|
195
|
+
end #</deltainfo>
|
196
|
+
end
|
197
|
+
# ready builder
|
198
|
+
file.write(builder.doc.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML))
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|