Skip to content

Commit 48492ae

Browse files
committed
Problem: building RPMs with mock is quite slow
Especially when there is a lot of dependencies. Solution: ensure we order them correctly This way, mock doesn't have to dynamically re-retry when it is missing dependencies.
1 parent 57755eb commit 48492ae

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

exe/pgpm

+1-3
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ module Pgpm
111111
os.with_scope do
112112
arch.with_scope do
113113
selected_pgdist.with_scope do
114-
pkgs = pkgs.flat_map do |pkg|
115-
[pkg, *pkg.all_requirements]
116-
end.reject(&:contrib?)
114+
pkgs = pkgs.flat_map(&:topologically_ordered_with_dependencies).uniq.reject(&:contrib?)
117115

118116
b = pkgs.reduce(nil) do |c, p|
119117
if p.broken?

lib/pgpm/package/dependencies.rb

+29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "tsort"
4+
35
module Pgpm
46
class Package
57
module Dependencies
@@ -21,6 +23,33 @@ def all_requirements
2123
requires.flat_map { |r| [r, *r.all_requirements] }.uniq
2224
end
2325

26+
def topologically_ordered_with_dependencies
27+
TopologicalPackageSorter.new([self, *all_requirements]).sorted_packages
28+
end
29+
30+
class TopologicalPackageSorter
31+
include TSort
32+
33+
def initialize(packages)
34+
@packages = packages.each_with_object({}) do |pkg, hash|
35+
hash[pkg.name] = pkg
36+
end
37+
end
38+
39+
def tsort_each_node(&block)
40+
@packages.each_key(&block)
41+
end
42+
43+
def tsort_each_child(node, &block)
44+
package = @packages[node]
45+
package.requires.each { |req| block.call(req) if @packages.key?(req) }
46+
end
47+
48+
def sorted_packages
49+
tsort.map { |name| @packages[name] }.reverse
50+
end
51+
end
52+
2453
def c_files_present?
2554
Dir.glob("*.c", base: source).any?
2655
end

0 commit comments

Comments
 (0)