summaryrefslogtreecommitdiff
path: root/stdlib/os/debian/apt.go
blob: 6b3baa27a35066a1d6d8444f5e8f2cedb21db4bb (plain)
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
package debian

import (
	"bufio"
	"bytes"
	"log/slog"
	"os"
	"os/exec"
	"strings"

	gonf "git.adyxax.org/adyxax/gonf/pkg"
)

var packages map[string]string

func init() {
	packagesList()
}

func packagesInstall(names []string) (gonf.Status, []string) {
	gonf.FilterSlice(&names, func(n string) bool {
		_, ok := packages[n]
		return !ok
	})
	if len(names) == 0 {
		return gonf.KEPT, nil
	}
	args := append([]string{"install", "-y", "--no-install-recommends"}, names...)
	cmd := gonf.CommandWithEnv([]string{"DEBIAN_FRONTEND=noninteractive", "LC_ALL=C"}, "apt-get", args...)
	cmd.Resolve()
	packagesList()
	return cmd.Status(), names
}

func packagesList() {
	packages = make(map[string]string)
	ecmd := exec.Command("dpkg-query", "-W")
	out, err := ecmd.CombinedOutput()
	if err != nil {
		slog.Error("dpkg-query", "error", err)
		os.Exit(1)
	}
	s := bufio.NewScanner(bytes.NewReader(out))
	s.Split(bufio.ScanWords)
	for s.Scan() {
		name := s.Text()
		if !s.Scan() {
			slog.Error("dpkg-query", "error", "parsing error: no version after name")
			os.Exit(1)
		}
		if strings.Contains(name, ":") { // some packages are named with the arch like something:amd64
			name = strings.Split(name, ":")[0] // in this case we want only the name
		}
		packages[name] = s.Text()
	}
}