Class: EnhanceRepo::RpmMd::DeltaInfo

Inherits:
Data
  • Object
show all
Defined in:
lib/enhance_repo/rpm_md/delta_info.rb

Instance Method Summary collapse

Methods inherited from Data

#metadata_filename, #name, #should_compress?

Methods included from Logger

#log

Constructor Details

#initialize(dir) ⇒ DeltaInfo

Returns a new instance of DeltaInfo.



62
63
64
65
66
67
68
69
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 62

def initialize(dir)
  @dir = dir
  # here we store known deltas
  # we index by new package
  # and in every slot we store an
  # array with such deltas
  @deltas = {}
end

Instance Method Details

#add_deltasObject



156
157
158
159
160
161
162
163
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 156

def add_deltas
  Dir["#{@dir}/**/*.delta.rpm"].each do |deltafile|
    delta = DeltaRpm.new(deltafile)
    # puts "Delta: #{deltafile} for '#{delta.ident}'"
    @deltas[delta] = [] if @deltas[delta].nil?
    @deltas[delta] << delta
  end
end

#create_deltas(opts = {}) ⇒ Object

Create delta rpms for the last n versions of some rpm.

So if you have foo-4.rpm foo-3.rpm foo-2.rpm foo-1.rpm

Creating deltas with n = 1 will create a delta for going to version 3 to 4. While n = 2 would create a delta to go from 2 to 4 too.

options are :n => number of deltas (default 1) and :outputdir => defaulting to the same input directory



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 96

def create_deltas(opts = {})
  outputdir = opts[:outputdir] || @dir
  n = opts[:n] || 1

  log.info "Scanning rpms for delta generation (#{n} levels)"
  # log.info "Creating deltarpms : level #{n}"
  # make a hash name -> array of packages
  pkgs = {}

  Dir["#{@dir}/**/*.rpm"].each do |rpmfile|
    # puts "Delta: #{rpmfile}"
    rpm = PackageId.new(rpmfile)

    pkgs[rpm.name] = [] unless pkgs.key?(rpm.name)
    pkgs[rpm.name] << rpm
  end

  # now that we have al packages, sort them by version
  pkgs.each do |_pkgname, pkglist|
    pkglist.sort! { |a, b| a.version <=> b.version }
    pkglist.reverse!
    # now that the list is sorted, the new rpm is the first
    newpkg = pkglist.shift
    c = 0
    next if pkglist.empty?
    for pkg in pkglist
      break if c == n
      # do not create a delta for the same package
      next if newpkg.version == pkg.version
      # do not create a delta for different archs
      next if newpkg.arch != pkg.arch
      oldpkg = pkg
      # use the same dir as the new rpm
      log.info "`-> creating delta - #{oldpkg} -> #{newpkg} (#{c + 1}/#{n})"
      # calculate directory where to save the delta. Use the newpkg
      # relative to the origin directory,
      # this only works because we know the rpm is inside @dir
      subdir = Pathname.new(newpkg.path).relative_path_from(Pathname.new(@dir)).dirname
      # calculate the deltarpm name
      deltafile = File.join(outputdir, subdir, delta_package_name(oldpkg, newpkg))
      FileUtils.mkdir_p File.dirname(deltafile)
      # puts "makedeltarpm #{oldpkg.path} #{newpkg.path} #{deltafile}"
      `makedeltarpm '#{oldpkg.path}' '#{newpkg.path}' '#{deltafile}'`
      c += 1
    end
  end
end

#delta_countObject



71
72
73
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 71

def delta_count
  @deltas.size
end

#delta_package_name(oldpkg, newpkg) ⇒ Object

figure out the name of a delta rpm



145
146
147
148
149
150
151
152
153
154
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 145

def delta_package_name(oldpkg, newpkg)
  deltarpm = ''
  deltarpm = if oldpkg.version.v == newpkg.version.v
               # if the version is the same, then it is specified only once, and the range
               # is used for the releases
               "#{oldpkg.name}-#{oldpkg.version.v}-#{oldpkg.version.r}_#{newpkg.version.r}.#{oldpkg.arch}.delta.rpm"
             else
               "#{oldpkg.name}-#{oldpkg.version.v}_#{newpkg.version.v}-#{oldpkg.version.r}_#{newpkg.version.r}.#{oldpkg.arch}.delta.rpm"
             end
end

#empty?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 75

def empty?
  @deltas.empty?
end

#write(file) ⇒ Object

write a update out



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 166

def write(file)
  builder = Nokogiri::XML::Builder.new do |b|
    b.deltainfo do
      @deltas.each do |ident, deltas|
        b.newpackage('name' => ident.name, 'arch' => ident.arch,
                     'version' => ident.version.v,
                     'release' => ident.version.r) do
          deltas.each do |delta|
            # get the edition by getting the name out
            version = RPM::Version.new(delta.sourcerpm.gsub(/#{Regexp.escape(delta.name)}-/, ''))
            b.delta('oldepoch' => 0, 'oldversion' => version.v, 'oldrelease' => version.r) do
              # remove the base dir, make it relative
              delta_abs_path = Pathname.new(delta.path).realpath
              base_dir_abs_path = Pathname.new(@dir).realpath
              relative_path = delta_abs_path.relative_path_from(base_dir_abs_path)
              b.filename relative_path
              b.sequence(delta.sequence)
              b.size(File.size(delta.path))
              b.checksum(delta.checksum, 'type' => EnhanceRepo::ConfigOpts.instance.digest_name)
            end # </delta>
          end
        end # </newpackage>
      end # each delta
    end # </deltainfo>
  end
  # ready builder
  file.write(builder.doc.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML))
end