summaryrefslogtreecommitdiff
path: root/src/BuildOrder.pm
diff options
context:
space:
mode:
authordavidovski <david@davidovski.xyz>2022-01-26 20:40:41 +0000
committerdavidovski <david@davidovski.xyz>2022-01-26 20:40:41 +0000
commitd63c86f983d14c9537d30fb32f76f6eddc717ae4 (patch)
tree3d1bbdaf358d9a28d1ab351d2f3db33f19320e1b /src/BuildOrder.pm
parentbbbade2eb54330c43d2ec938c4fc3ace660851ee (diff)
moved calculating build order to a separate module
Diffstat (limited to 'src/BuildOrder.pm')
-rw-r--r--src/BuildOrder.pm110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/BuildOrder.pm b/src/BuildOrder.pm
new file mode 100644
index 0000000..0836209
--- /dev/null
+++ b/src/BuildOrder.pm
@@ -0,0 +1,110 @@
+package BuildOrder;
+# tools for determining which order to build packages
+
+use strict;
+use warnings;
+
+use File::Basename "basename";
+use Sort::TSort "tsort";
+
+sub list_dependencies{
+ my $file = $_;
+ my @deps = ();
+
+ open (my $fh, "<", $file) or warn "Cannot open $file";
+
+ while (my $line = <$fh>) {
+ if ($line =~ /DEPS=\((.+)\)/) {
+ my @words = split(/ /, $1);
+ push(@deps, @words);
+ }
+ }
+
+ return @deps;
+}
+
+sub list_buildfiles{
+ my @files = glob("$main::buildfiles/repo/*/*.xibuild");
+ # ignore any meta packages during this stage, they can be added later
+ return grep(!/\/meta\//, @files);
+}
+
+sub list_meta_pkgs{
+ return map({basename($_, ".xibuild")} glob("$main::buildfiles/repo/meta/*.xibuild"));
+}
+
+sub get_packages{
+ my %pkgs = ();
+
+ my @files = list_buildfiles();
+
+ foreach (@files) {
+ my $pkg_file = $_;
+ my $pkg_name = basename($pkg_file, ".xibuild");
+
+ my @deps = list_dependencies($pkg_file);
+ $pkgs{$pkg_name} = \@deps;
+ }
+
+ return %pkgs;
+}
+
+# Get a list of all the edges
+sub get_edges{
+ my %pkgs = @_;
+
+ my @edges = ();
+ foreach (keys(%pkgs)) {
+ my $pkg = $_;
+ my @deps = @{$pkgs{$_}};
+ foreach (@deps) {
+ my $dep = $_;
+
+ my @edge = ($pkg, $dep);
+ push @edges, [ @edge ];
+
+ }
+ }
+ return @edges;
+}
+
+# Determine which packages are depended on
+sub get_depended_on{
+ my @edges = @_;
+
+ my %install = ();
+ foreach (@edges) {
+ my @edge = @{$_};
+ $install{$edge[1]} = $edge[0];
+ }
+
+ return keys(%install);
+}
+
+sub determine_build_order{
+ my ($file) = @_;
+ my %pkgs = get_packages();
+
+ my @edges = get_edges(%pkgs);
+
+ my @install = get_depended_on(@edges);
+
+ # use tsort to determine the build order
+ my @sorted = reverse(@{tsort(\@edges)});
+
+ my @meta = list_meta_pkgs();
+ push(@sorted, @meta);
+
+ open (my $fh, ">", $file) or die "Cannot open $file";
+
+ foreach(@sorted) {
+ my $pkg = $_;
+ print($fh "$pkg");
+ print($fh "+") if (grep(/^$pkg/, @install));
+ print($fh "\n");
+ }
+
+ return $file;
+}
+
+1;