summaryrefslogtreecommitdiff
path: root/build/instructions.go
blob: 41c959d43d447445ced0d8436665d3b0da079340 (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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package build

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
)

type Instruction interface {
	Compile() []string
}

type Run struct {
	Command   string
	Arguments []string
}

func (run Run) Compile() []string {
	numInnerArgs := strings.Count(run.Command, `%`) - strings.Count(run.Command, `%%`)
	command := sprintf(run.Command, run.Arguments[0:numInnerArgs])

	if len(run.Arguments) > numInnerArgs {
		command += " " + strings.Join(quoteAll(run.Arguments[numInnerArgs:]), " ")
	}

	return []string{command}
}

type RunAll struct {
	Runs []Run
}

func (runAll RunAll) Compile() []string {
	commands := make([]string, len(runAll.Runs))

	for i, run := range runAll.Runs {
		commands[i] = run.Compile()[0]
	}

	return []string{strings.Join(commands, " && ")}
}

type Copy struct {
	Sources     []string
	Destination string
}

func (copy Copy) Compile() []string {
	return append(quoteAll(copy.Sources), quote(copy.Destination))
}

type CopyFrom struct {
	From string
	Copy
}

func (cf CopyFrom) Compile() []string {
	return append([]string{cf.From}, cf.Copy.Compile()...)
}

type Env struct {
	Definitions map[string]string
}

func (env Env) Compile() []string {
	return compileSortedKeyValues(env.Definitions)
}

// Label represents a number of meta-data key/value pairs
type Label struct {
	Definitions map[string]string
}

// Compile returns the label key/value pairs as a number of `key="value"`
// strings where the values are properly quoted
func (label Label) Compile() []string {
	return compileSortedKeyValues(label.Definitions)
}

type Volume struct {
	Path string
}

func (vol Volume) Compile() []string {
	return []string{quote(vol.Path)}
}

func compileSortedKeyValues(keyValues map[string]string) []string {
	defs := make([]string, 0, len(keyValues))
	names := make([]string, 0, len(keyValues))

	for name := range keyValues {
		names = append(names, name)
	}

	sort.Strings(names)

	for _, name := range names {
		defs = append(defs, name+"="+quote(keyValues[name]))
	}

	return defs
}

func quote(arg string) string {
	return strconv.Quote(arg)
}

func quoteAll(arguments []string) []string {
	quoted := make([]string, len(arguments))

	for i, arg := range arguments {
		quoted[i] = quote(arg)
	}

	return quoted
}

func sprintf(format string, arguments []string) string {
	args := make([]interface{}, len(arguments))

	for i, v := range arguments {
		args[i] = quote(v)
	}

	return fmt.Sprintf(format, args...)
}