forked from box-builder/box
-
Notifications
You must be signed in to change notification settings - Fork 0
/
builder.go
121 lines (101 loc) · 2.83 KB
/
builder.go
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
package builder
import (
"context"
"fmt"
"io/ioutil"
"github.com/box-builder/box/builder/command"
"github.com/box-builder/box/builder/evaluator"
"github.com/box-builder/box/builder/evaluator/mruby"
"github.com/box-builder/box/builder/executor"
"github.com/box-builder/box/builder/executor/docker"
"github.com/box-builder/box/copy"
"github.com/box-builder/box/logger"
"github.com/box-builder/box/types"
"github.com/fatih/color"
)
// BuildConfig is a struct containing the configuration for the builder.
type BuildConfig struct {
Globals *types.Global
Runner chan struct{}
FileName string
Vars map[string]string
}
// Builder implements the builder core.
type Builder struct {
config *BuildConfig
exec executor.Executor
eval evaluator.Evaluator
}
// NewBuilder creates a new builder. Returns error on docker or mruby issues.
func NewBuilder(bc BuildConfig) (*Builder, error) {
if bc.Globals == nil {
bc.Globals = &types.Global{Context: context.Background()}
}
color.NoColor = !bc.Globals.Color
copy.NoTTY = !bc.Globals.TTY
if bc.Globals.Logger == nil {
bc.Globals.Logger = logger.New(bc.FileName, true)
}
exec, err := NewExecutor("docker", bc.Globals)
if err != nil {
return nil, err
}
eval, err := mruby.NewMRuby(&mruby.Config{
Filename: bc.FileName,
Globals: bc.Globals,
Exec: exec,
Interp: command.NewInterpreter(bc.Globals, exec, bc.Vars),
})
if err != nil {
return nil, err
}
return &Builder{
config: &bc,
exec: exec,
eval: eval,
}, nil
}
// Config returns the BuildConfig associated with this builder
func (b *Builder) Config() *BuildConfig {
return b.config
}
// Result returns the latest cached result from any run invocation. The
// behavior is undefined if called before any Run()-style invocation.
func (b *Builder) Result() types.BuildResult {
return b.eval.Result()
}
// Run runs the script set by the BuildConfig. It closes the run channel when
// it finishes.
func (b *Builder) Run() types.BuildResult {
defer close(b.config.Runner)
script, err := ioutil.ReadFile(b.config.FileName)
if err != nil {
return types.BuildResult{
FileName: b.config.FileName,
Err: err,
}
}
b.eval.RunScript(string(script))
return b.Result()
}
// Wait waits for the build to complete.
func (b *Builder) Wait() types.BuildResult {
<-b.config.Runner
return b.Result()
}
// Tag the image with the name
func (b *Builder) Tag(tag string) error {
return b.exec.Image().Tag(tag)
}
// Close tears down all functions of the builder, preparing it for exit.
func (b *Builder) Close() error {
return b.eval.Close()
}
// NewExecutor returns a valid executor for the given name, or error.
func NewExecutor(name string, globals *types.Global) (executor.Executor, error) {
switch name {
case "docker":
return docker.NewDocker(globals)
}
return nil, fmt.Errorf("Executor %q not found", name)
}