File: pkgmanager.h

package info (click to toggle)
rust-rust-apt 0.8.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 620 kB
  • sloc: cpp: 703; makefile: 8
file content (112 lines) | stat: -rw-r--r-- 3,841 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#pragma once
#include <apt-pkg/acquire.h>
#include <apt-pkg/algorithms.h>
#include <apt-pkg/cachefile.h>
#include <apt-pkg/install-progress.h>
#include <apt-pkg/packagemanager.h>
#include <apt-pkg/pkgsystem.h>
#include <apt-pkg/sourcelist.h>
#include <memory>

#include "cache.h"
#include "rust-apt/src/progress.rs"

struct PackageManager {
	pkgPackageManager mutable* pkgmanager;

	void get_archives(
		const PkgCacheFile& cache,
		const PkgRecords& records,
		AcqTextStatus& archive_progress
	) const {
		pkgAcquire acquire(&archive_progress);

		// We probably need to let the user set their own pkgSourcePkgCacheFileList,
		// but there hasn't been a need to expose such in the Rust interface
		// yet. pkgSourceList sourcelist = *cache->GetSourceList();

		if (!pkgmanager->GetArchives(
				&acquire, cache.unconst()->GetSourceList(), &records.records
			)) {
			handle_errors();
			throw std::runtime_error(
				"Internal Issue with rust-apt in pkgmanager_get_archives."
				" Please report this as an issue."
			);
		}

		pkgAcquire::RunResult result = acquire.Run(archive_progress.callback->pulse_interval());

		if (result != pkgAcquire::Continue) {
			// The other variants are either Failed or Cancelled
			// Failed will always have an error for us to handle
			// It's unsure if Cancelled would even require a bool
			// I believe this may be a Keyboard Interrupt situation
			handle_errors();
		}
	}

	void do_install(InstallProgress& callback) const {
		PackageManagerWrapper install_progress(callback);
		pkgPackageManager::OrderResult res = pkgmanager->DoInstall(&install_progress);

		if (res == pkgPackageManager::OrderResult::Completed) {
			return;
		} else if (res == pkgPackageManager::OrderResult::Failed) {
			handle_errors();
			throw std::runtime_error(
				"Internal Issue with rust-apt in pkgmanager_do_install."
				" DoInstall has failed but there was no error from apt."
				" Please report this as an issue."
			);
		} else if (res == pkgPackageManager::OrderResult::Incomplete) {
			// It's not clear that there would be any apt errors here,
			// But we'll try anyway. This is believed to be only for media swapping
			handle_errors();
			throw std::runtime_error(
				"Internal Issue with rust-apt in pkgmanager_do_install."
				" DoInstall returned Incomplete, media swaps are unsupported."
				" Please request media swapping as a feature."
			);
		} else {
			// If for whatever reason we manage to make it here (We shouldn't)
			// Attempt to handle any apt errors
			// And then fallback with a message to report with the result code.
			handle_errors();
			throw std::runtime_error(
				"Internal Issue with rust-apt in pkgmanager_do_install."
				" Please report this as an issue. OrderResult: " +
				res
			);
		}
	}

	PackageManager(pkgDepCache* depcache) : pkgmanager(_system->CreatePM(depcache)){};
};

struct ProblemResolver {
	pkgProblemResolver mutable resolver;

	/// Mark a package as protected, i.e. don't let its installation/removal state change when
	/// modifying packages during resolution.
	void protect(const PkgIterator& pkg) const { resolver.Protect(pkg); }

	/// Try to resolve dependency problems by marking packages for installation and removal.
	void resolve(bool fix_broken, OperationProgress& callback) const {
		OpProgressWrapper op_progress(callback);
		resolver.Resolve(fix_broken, &op_progress);
		handle_errors();
	}

	ProblemResolver(pkgDepCache* depcache) : resolver(depcache){};
};

/// Create the problem resolver.
UniquePtr<ProblemResolver> create_problem_resolver(const PkgDepCache& cache) {
	return std::make_unique<ProblemResolver>(cache.ptr);
}

UniquePtr<PackageManager> create_pkgmanager(const PkgDepCache& cache) {
	// Package Manager needs the DepCache initialized or else invalid memory reference.
	return std::make_unique<PackageManager>(cache.ptr);
}