main 6af0a61

pacman.go RawHistoryFolder

1package system
2
3import "fmt"
4
5// DownloadAndInstallPackages downloads packages from URLs using curl and installs them in chroot.
6// Supports mirror fallbacks: URLs with the same package name but different mirrors.
7func DownloadAndInstallPackages(logPath, chrootPath string, urls ...string) error {
8	if len(urls) == 0 {
9		return fmt.Errorf("no URLs provided")
10	}
11
12	// Group URLs by package (same filename = same package, different mirrors)
13	packageMirrors := make(map[string][]string)
14	for _, url := range urls {
15		var pkgName string
16		for i := len(url) - 1; i >= 0; i-- {
17			if url[i] == '/' {
18				pkgName = url[i+1:]
19				break
20			}
21		}
22		packageMirrors[pkgName] = append(packageMirrors[pkgName], url)
23	}
24
25	// Build command with mirror fallback per package
26	cmd := "mkdir -p /tmp && "
27	for i, pkgName := range getSortedKeys(packageMirrors) {
28		mirrors := packageMirrors[pkgName]
29		cmd += fmt.Sprintf("(curl -L -f -o /tmp/pkg%d.tar.zst '%s'", i, mirrors[0])
30		for _, mirror := range mirrors[1:] {
31			cmd += fmt.Sprintf(" || curl -L -f -o /tmp/pkg%d.tar.zst '%s'", i, mirror)
32		}
33		cmd += ") && "
34	}
35	cmd += "pacman -U --noconfirm /tmp/pkg*.tar.zst && rm -f /tmp/pkg*.tar.zst"
36
37	if err := ChrootExec(logPath, chrootPath, cmd); err != nil {
38		cleanupErr := ChrootExec(logPath, chrootPath, "rm -f /tmp/pkg*.tar.zst")
39		if cleanupErr != nil {
40			return fmt.Errorf("%w (cleanup failed: %v)", err, cleanupErr)
41		}
42		return err
43	}
44
45	return nil
46}
47
48// getSortedKeys returns map keys in stable alphabetical order
49func getSortedKeys(m map[string][]string) []string {
50	keys := make([]string, 0, len(m))
51	for k := range m {
52		keys = append(keys, k)
53	}
54	for i := 0; i < len(keys); i++ {
55		for j := i + 1; j < len(keys); j++ {
56			if keys[i] > keys[j] {
57				keys[i], keys[j] = keys[j], keys[i]
58			}
59		}
60	}
61	return keys
62}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 0

    ↑↓ moveenter openesc close