~nabijaczleweli/klapki.deb

ref: 50de836242adb578bc1bb6c288ddc450c4a4765c klapki.deb/src/context_propagate.cpp -rw-r--r-- 3.5 KiB
50de8362наб Fix upstream homepage link 1 year, 2 months ago
                                                                                
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
// The MIT License (MIT)

// Copyright (c) 2020 наб <nabijaczleweli@nabijaczleweli.xyz>

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


#include "config.hpp"
#include "context.hpp"


std::optional<std::string> klapki::context::context::propagate(const config & cfg, state::state & state) {
	std::map<std::string, std::map<std::uint16_t, std::string>> version_variants;  // Can't be string_views because we write over wanted_entries later
	for(auto && went : state.statecfg.wanted_entries)
		version_variants[went.version][went.bootnum_hint] = went.variant;

	for(auto && [ver, vars] : version_variants) {
		const auto baseline_bootnum = vars.begin()->first;

		std::set<std::string_view> missing_variants;

		auto var_cbk = [&, &vars = vars](std::string_view var) {
			if(const auto vitr = std::find_if(std::begin(vars), std::end(vars), [&](auto && vv) { return vv.second == var; }); vitr != std::end(vars))
				vars.extract(vitr);
			else
				missing_variants.emplace(var);
		};
		var_cbk("");
		for(auto && var : state.statecfg.variants)
			var_cbk(var);

		for(auto && mvar : missing_variants)
			if(!vars.empty()) {  // At this point vars has entries which didn't match any currently stated variant. Try to relocate missing variants onto them.
				const auto bootnum = vars.extract(vars.begin()).key();

				const auto went = std::find_if(std::begin(state.statecfg.wanted_entries), std::end(state.statecfg.wanted_entries),
				                               [&](auto && went) { return went.bootnum_hint == bootnum; });
				if(went == std::end(state.statecfg.wanted_entries))
					throw __func__;

				went->variant = mvar;
			} else {
				const auto baseline_went = std::find_if(std::begin(state.statecfg.wanted_entries), std::end(state.statecfg.wanted_entries),
				                                        [&](auto && went) { return went.bootnum_hint == baseline_bootnum; });
				if(baseline_went == std::end(state.statecfg.wanted_entries))
					throw __func__;
				const auto baseline_kern = this->our_kernels.find(baseline_bootnum);
				if(baseline_kern == std::end(this->our_kernels))
					throw __func__;

				this->allocate_kernel_variant(cfg, state, std::string{ver}, std::string{mvar}, baseline_went->kernel_dirname, baseline_went->kernel_image_sha,
				                              baseline_went->initrd_dirnames, baseline_kern->second.image_path.second, baseline_kern->second.initrd_paths);
			}

		if(!vars.empty())
			this->purge_allocations(state, [&, &vars = vars](auto && skern) { return vars.find(skern.bootnum_hint) != std::end(vars); });
	}

	return {};
}