summaryrefslogtreecommitdiff
path: root/run/run.go
blob: d1758236862a60a219d81229fc4fca25a44c6778 (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
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
package run

import (
	"fmt"
	"os"
	"pik/env"
	"pik/flags"
	"pik/menu"
	"pik/model"
	"slices"
)

func Run(source *model.Source, target model.Target, args ...string) error {
	tags := target.Tags()
	skipTriggers := tags.Has(model.Single) || *flags.Single

	if !skipTriggers {
		err := Pre(source, target)
		if err != nil {
			return err
		}
	}
	err := Exec(source, target, args...)
	fmt.Println()
	if err != nil {
		return err
	}
	if !skipTriggers {
		err := Post(source, target)
		if err != nil {
			return err
		}
		err = Final(source, target)
		if err != nil {
			return err
		}
	}
	return nil
}

func Pre(source *model.Source, target model.Target) error {
	return ExecWithTrigger(source, target, model.Pre)
}

func Post(source *model.Source, target model.Target) error {
	return ExecWithTrigger(source, target, model.Post)
}

func Final(source *model.Source, target model.Target) error {
	return ExecWithTrigger(source, target, model.Final)
}

func ExecWithTrigger(source *model.Source, target model.Target, tag model.Tag) error {
	for _, t := range source.Targets {
		if t.Tags().Has(tag) {
			triggerSub := t.Sub()
			targetSub := target.Sub()

			for _, targetSubPart := range triggerSub {
				if !slices.Contains(targetSub, targetSubPart) {
					continue
				}
			}

			err := Exec(source, t)
			fmt.Println()
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func Exec(source *model.Source, target model.Target, args ...string) error {
	_, _ = fmt.Fprint(os.Stderr, menu.Banner(source, target, args...))
	loc := source.Path
	tags := target.Tags()
	if *flags.At != "" {
		loc = *flags.At
	} else if tags.Has(model.Here) || *flags.Here {
		wd, err := os.Getwd()
		if err != nil {
			return err
		}
		loc = wd
	}
	cmd := target.Create(source)
	cmd.Dir = loc
	cmd.Stdout = os.Stdout
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Args = append(cmd.Args, args...)

	e := env.Get(source)
	if len(e) > 0 {
		cmd.Env = append(os.Environ(), e...)
	}

	if *flags.Dry {
		_, _ = fmt.Fprintln(os.Stderr, menu.InlineCmd(cmd))
		return nil
	}

	if *flags.Root {
		cmd.Args = append([]string{"sudo"}, cmd.Args...)
	}
	_, _ = fmt.Fprintln(os.Stderr)
	return cmd.Run()
}