1e62d422cSespie# ex:ts=8 sw=4: 2*8773e53fSespie# $OpenBSD: Tracker.pm,v 1.33 2023/10/08 09:16:39 espie Exp $ 3e62d422cSespie# 4e62d422cSespie# Copyright (c) 2009 Marc Espie <espie@openbsd.org> 5e62d422cSespie# 6e62d422cSespie# Permission to use, copy, modify, and distribute this software for any 7e62d422cSespie# purpose with or without fee is hereby granted, provided that the above 8e62d422cSespie# copyright notice and this permission notice appear in all copies. 9e62d422cSespie# 10e62d422cSespie# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11e62d422cSespie# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12e62d422cSespie# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13e62d422cSespie# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14e62d422cSespie# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15e62d422cSespie# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16e62d422cSespie 1759730165Sespie# In order to deal with dependencies, we have to know what's actually installed, 1859730165Sespie# and what can actually be updated. 1959730165Sespie# Specifically, to solve a dependency: 2059730165Sespie# - look at packages to_install 2159730165Sespie# - look at installed packages 2259730165Sespie# - if it's marked to_update, then we must process the update first 2359730165Sespie# - if it's marked as installed, or as cant_update, or uptodate, then 2459730165Sespie# we can use the installed packages. 2559730165Sespie# - otherwise, in update mode, put a request to update the package (e.g., 2659730165Sespie# create a new UpdateSet. 2759730165Sespie 2859730165Sespie# the Tracker object does maintain that information globally so that 2959730165Sespie# Update/Dependencies can do its job. 30e62d422cSespie 31039cbdaaSespieuse v5.36; 320fbefeddSespieuse warnings; 330fbefeddSespie 34e62d422cSespiepackage OpenBSD::Tracker; 35b48b4bf7Sespie 36b48b4bf7Sespie# XXX we're a singleton class 37af9539a4Sespieour $s; 38af9539a4Sespie 39039cbdaaSespiesub new($class) 40e62d422cSespie{ 41b48b4bf7Sespie return $s //= bless {}, $class; 42af9539a4Sespie} 43af9539a4Sespie 44039cbdaaSespiesub dump2($set) 45af9539a4Sespie{ 46af9539a4Sespie if (defined $set->{merged}) { 47af9539a4Sespie return "merged from ".dump2($set->{merged}); 48af9539a4Sespie } 49af9539a4Sespie return join("/", 50af9539a4Sespie join(",", $set->newer_names), 51af9539a4Sespie join(",", $set->older_names), 52af9539a4Sespie join(",", $set->kept_names), 53af9539a4Sespie join(",", $set->hint_names)); 54af9539a4Sespie} 55af9539a4Sespie 56*8773e53fSespiesub dump($) 57af9539a4Sespie{ 58af9539a4Sespie return unless defined $s; 59af9539a4Sespie for my $l ('to_install', 'to_update') { 60af9539a4Sespie next unless defined $s->{$l}; 61af9539a4Sespie print STDERR "$l:\n"; 62af9539a4Sespie while (my ($k, $e) = each %{$s->{$l}}) { 63af9539a4Sespie print STDERR "\t$k => ", dump2($e), "\n"; 64af9539a4Sespie } 65af9539a4Sespie } 66af9539a4Sespie for my $l ('uptodate', 'can_install', 'cant_update') { 67af9539a4Sespie next unless defined $s->{$l}; 68af9539a4Sespie print STDERR "$l: ", join(' ', keys %{$s->{$l}}), "\n"; 69af9539a4Sespie } 70e62d422cSespie} 71e62d422cSespie 72039cbdaaSespiesub sets_todo($self, $offset = 0) 73fbfa215eSespie{ 7400f714c9Sespie return sprintf("%u/%u", (scalar keys %{$self->{done}})-$offset, 7500f714c9Sespie scalar keys %{$self->{total}}); 76fbfa215eSespie} 7700f714c9Sespie 78039cbdaaSespiesub handle_set($self, $set) 79fbfa215eSespie{ 80fd2511f6Sespie $self->{total}{$set} = 1; 81fbfa215eSespie if ($set->{finished}) { 82fd2511f6Sespie $self->{done}{$set} = 1; 83fbfa215eSespie } 84fbfa215eSespie} 85fbfa215eSespie 86039cbdaaSespiesub known($self, $set) 877dd5c23bSespie{ 887dd5c23bSespie for my $n ($set->newer, $set->older, $set->hints) { 89fd2511f6Sespie $self->{known}{$n->pkgname} = 1; 907dd5c23bSespie } 917dd5c23bSespie} 927dd5c23bSespie 93039cbdaaSespiesub add_set($self, $set) 94e62d422cSespie{ 95e62d422cSespie for my $n ($set->newer) { 96fd2511f6Sespie $self->{to_install}{$n->pkgname} = $set; 97e62d422cSespie } 984c82e4b5Sespie for my $n ($set->older, $set->hints) { 99fd2511f6Sespie $self->{to_update}{$n->pkgname} = $set; 100e62d422cSespie } 1012172b28bSespie for my $n ($set->kept) { 102fd2511f6Sespie delete $self->{to_update}{$n->pkgname}; 103fd2511f6Sespie $self->{uptodate}{$n->pkgname} = 1; 10435d93a1aSespie if ($n->{is_firmware}) { 10535d93a1aSespie $self->{firmware}{$n->pkgname} = 1; 10635d93a1aSespie } 1072172b28bSespie } 1087dd5c23bSespie $self->known($set); 109fbfa215eSespie $self->handle_set($set); 110e62d422cSespie return $self; 111e62d422cSespie} 112e62d422cSespie 113039cbdaaSespiesub todo($self, @sets) 114e62d422cSespie{ 115e62d422cSespie for my $set (@sets) { 116e62d422cSespie $self->add_set($set); 117e62d422cSespie } 118e62d422cSespie return $self; 119e62d422cSespie} 120e62d422cSespie 121039cbdaaSespiesub remove_set($self, $set) 122e62d422cSespie{ 123e62d422cSespie for my $n ($set->newer) { 124fd2511f6Sespie delete $self->{to_install}{$n->pkgname}; 125fd2511f6Sespie delete $self->{cant_install}{$n->pkgname}; 126e62d422cSespie } 1272172b28bSespie for my $n ($set->kept, $set->older, $set->hints) { 128fd2511f6Sespie delete $self->{to_update}{$n->pkgname}; 129fd2511f6Sespie delete $self->{cant_update}{$n->pkgname}; 130e62d422cSespie } 131fbfa215eSespie $self->handle_set($set); 132e62d422cSespie} 133e62d422cSespie 134039cbdaaSespiesub uptodate($self, $set) 1356f8f2da9Sespie{ 136fbfa215eSespie $set->{finished} = 1; 1377dd5c23bSespie $self->remove_set($set); 1382172b28bSespie for my $n ($set->older, $set->kept) { 139fd2511f6Sespie $self->{uptodate}{$n->pkgname} = 1; 14035d93a1aSespie if ($n->{is_firmware}) { 14135d93a1aSespie $self->{firmware}{$n->pkgname} = 1; 14235d93a1aSespie } 1436f8f2da9Sespie } 1446f8f2da9Sespie} 1456f8f2da9Sespie 146039cbdaaSespiesub cant($self, $set) 1476f8f2da9Sespie{ 148fbfa215eSespie $set->{finished} = 1; 1497dd5c23bSespie $self->remove_set($set); 1501a749f56Sespie $self->known($set); 1516f8f2da9Sespie for my $n ($set->older) { 152fd2511f6Sespie $self->{cant_update}{$n->pkgname} = 1; 1536f8f2da9Sespie } 1541a749f56Sespie for my $n ($set->newer) { 155fd2511f6Sespie $self->{cant_install}{$n->pkgname} = 1; 1561a749f56Sespie } 1571a749f56Sespie for my $n ($set->kept) { 158fd2511f6Sespie $self->{uptodate}{$n->pkgname} = 1; 1591a749f56Sespie } 1606f8f2da9Sespie} 1616f8f2da9Sespie 162039cbdaaSespiesub done($self, $set) 1636af57ca2Sespie{ 164fbfa215eSespie $set->{finished} = 1; 16505982d0bSespie $self->remove_set($set); 1667dd5c23bSespie $self->known($set); 16705982d0bSespie 1686af57ca2Sespie for my $n ($set->newer) { 169fd2511f6Sespie $self->{uptodate}{$n->pkgname} = 1; 170fd2511f6Sespie $self->{installed}{$n->pkgname} = 1; 1716af57ca2Sespie } 172d51783afSespie for my $n ($set->kept) { 173fd2511f6Sespie $self->{uptodate}{$n->pkgname} = 1; 174d51783afSespie } 1756af57ca2Sespie} 1766af57ca2Sespie 177039cbdaaSespiesub is($self, $k, $pkg) 17898cf79f0Sespie{ 179fd2511f6Sespie my $set = $self->{$k}{$pkg}; 18098cf79f0Sespie if (ref $set) { 18198cf79f0Sespie return $set->real_set; 18298cf79f0Sespie } else { 18398cf79f0Sespie return $set; 18498cf79f0Sespie } 18598cf79f0Sespie} 18698cf79f0Sespie 187039cbdaaSespiesub is_known($self, $pkg) 18807219e17Sespie{ 1897dd5c23bSespie return $self->is('known', $pkg); 19007219e17Sespie} 19107219e17Sespie 192039cbdaaSespiesub is_installed($self, $pkg) 193c6267a63Sespie{ 19498cf79f0Sespie return $self->is('installed', $pkg); 19598cf79f0Sespie} 19698cf79f0Sespie 197039cbdaaSespiesub is_to_update($self, $pkg) 19898cf79f0Sespie{ 19998cf79f0Sespie return $self->is('to_update', $pkg); 200c6267a63Sespie} 201c6267a63Sespie 202039cbdaaSespiesub cant_list($self) 2036f8f2da9Sespie{ 2046f8f2da9Sespie return keys %{$self->{cant_update}}; 2056f8f2da9Sespie} 2066f8f2da9Sespie 20735d93a1aSespiesub did_something($self) 20835d93a1aSespie{ 20935d93a1aSespie for my $k (keys %{$self->{uptodate}}) { 21035d93a1aSespie next if $self->{firmware}{$k}; 21135d93a1aSespie return 1; 21235d93a1aSespie } 21335d93a1aSespie return 0; 21435d93a1aSespie} 21535d93a1aSespie 216039cbdaaSespiesub cant_install_list($self) 2179ab6974eSespie{ 2189ab6974eSespie return keys %{$self->{cant_install}}; 2199ab6974eSespie} 2209ab6974eSespie 221e62d422cSespie1; 222