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.



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

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 = Hash.new
end

Instance Method Details

#add_deltasObject



161
162
163
164
165
166
167
168
169
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 161

def add_deltas
  Dir["#{@dir}/**/*.delta.rpm"].each do |deltafile|
    delta = DeltaRpm.new(deltafile)
    #puts "Delta: #{deltafile} for '#{delta.ident}'"      
    @deltas[delta] = Array.new 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



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
143
144
145
146
147
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 97

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 = Hash.new
  
  Dir["#{@dir}/**/*.rpm"].each do |rpmfile|
    #puts "Delta: #{rpmfile}"
    rpm = PackageId.new(rpmfile)
    
    pkgs[rpm.name] = Array.new if not pkgs.has_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 
    if not 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.to_s} -> #{newpkg.to_s} (#{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

end

#delta_countObject



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

def delta_count
  @deltas.size
end

#delta_package_name(oldpkg, newpkg) ⇒ Object

figure out the name of a delta rpm



150
151
152
153
154
155
156
157
158
159
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 150

def delta_package_name(oldpkg, newpkg)
  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
    deltarpm = "#{oldpkg.name}-#{oldpkg.version.v}-#{oldpkg.version.r}_#{newpkg.version.r}.#{oldpkg.arch}.delta.rpm"
  else
    deltarpm = "#{oldpkg.name}-#{oldpkg.version.v}_#{newpkg.version.v}-#{oldpkg.version.r}_#{newpkg.version.r}.#{oldpkg.arch}.delta.rpm"
  end
end

#empty?Boolean

Returns:

  • (Boolean)


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

def empty?
  return @deltas.empty?
end

#write(file) ⇒ Object

write a update out



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/enhance_repo/rpm_md/delta_info.rb', line 172

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 |b|
          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 |b|
              # 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'=>'sha')
            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