xref: /openbsd/usr.sbin/pkg_add/OpenBSD/Tracker.pm (revision 8773e53f)
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