diff options
-rw-r--r-- | src/BuildOrder.pm | 110 | ||||
-rwxr-xr-x | src/xib.pl | 97 |
2 files changed, 118 insertions, 89 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; @@ -24,15 +24,17 @@ use strict; use warnings; use Getopt::Long "HelpMessage"; + use File::Basename; -use Sort::TSort "tsort"; +use lib dirname (__FILE__); +use BuildOrder "determine_build_order"; our $BUILDFILES_REPO = "https://xi.davidovski.xyz/git/buildfiles.git"; GetOptions( - "chroot:s" => \(our $chroot = "/var/xilinux/chroot"), - "buildfiles" => \(our $buildfiles = "/var/xilinux/buildfiles"), - "export:s" => \(our $export = "/var/xilinux/export"), + "chroot:s" => \(our $chroot = "/var/lib/xib/chroot"), + "buildfiles" => \(our $buildfiles = "/var/lib/xib/buildfiles"), + "export:s" => \(our $export = "/var/lib/xib/export"), ) or HelpMessage(1); sub prepare_xib_environment{ @@ -51,94 +53,11 @@ sub pull_buildfiles{ } else { system("git clone $BUILDFILES_REPO $buildfiles"); } - list_buildfiles(); } -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("$buildfiles/repo/*/*.xibuild"); - return @files; -} - -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; -} - -sub get_depended_on{ - my (%pkgs) = @_; - my %depended = (); - - foreach (keys(%pkgs)) { - my @empty = (); - $depended{$_} = \@empty; - } - - foreach (keys(%pkgs)) { - my $apkg = $_; - foreach (keys(%pkgs)) { - my $bpkg = $_; - my @deps = @{$pkgs{$_}}; - if (grep(/^$apkg$/, @deps)) { - push(@{$depended{$apkg}}, $bpkg); - } - } - } - - return %depended; -} - -sub determine_build_order{ - my %pkgs = get_packages(); - - my @edges = (); - foreach (keys(%pkgs)) { - my $pkg = $_; - my @deps = @{$pkgs{$_}}; - foreach (@deps) { - my $dep = $_; - - my @edge = ($pkg, $dep); - push @edges, [ @edge ]; - - } - } - - my $sorted = tsort(\@edges); - - foreach(@{$sorted}) { - print("$_\n"); - } -} - unless (caller) { prepare_xib_environment(); - determine_build_order(); + my $file = "$chroot/buildorder"; + BuildOrder::determine_build_order($file); } |