blob: f9474097fd26d86df24663d5a5c1dd59f27a7f5e [file] [log] [blame]
Jamie Gennis1bc967e2014-05-27 16:34:41 -07001package blueprint
2
3import (
4 "fmt"
5 "path/filepath"
6)
7
8type Singleton interface {
9 GenerateBuildActions(SingletonContext)
10}
11
12type SingletonContext interface {
Jamie Gennis6eb4d242014-06-11 18:31:16 -070013 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070014
15 ModuleName(module Module) string
16 ModuleDir(module Module) string
17 BlueprintFile(module Module) string
18
19 ModuleErrorf(module Module, format string, args ...interface{})
20 Errorf(format string, args ...interface{})
21
22 Variable(name, value string)
Jamie Genniscbc6f862014-06-05 20:00:22 -070023 Rule(name string, params RuleParams, argNames ...string) Rule
Jamie Gennis1bc967e2014-05-27 16:34:41 -070024 Build(params BuildParams)
25 RequireNinjaVersion(major, minor, micro int)
26
27 // SetBuildDir sets the value of the top-level "builddir" Ninja variable
28 // that controls where Ninja stores its build log files. This value can be
29 // set at most one time for a single build. Setting it multiple times (even
30 // across different singletons) will result in a panic.
31 SetBuildDir(value string)
32
33 VisitAllModules(visit func(Module))
34 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
35}
36
37var _ SingletonContext = (*singletonContext)(nil)
38
39type singletonContext struct {
40 context *Context
Jamie Gennis6eb4d242014-06-11 18:31:16 -070041 config interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070042 scope *localScope
43
44 errs []error
45
46 actionDefs localBuildActions
47}
48
Jamie Gennis6eb4d242014-06-11 18:31:16 -070049func (s *singletonContext) Config() interface{} {
Jamie Gennis1bc967e2014-05-27 16:34:41 -070050 return s.config
51}
52
53func (s *singletonContext) ModuleName(module Module) string {
54 info := s.context.moduleInfo[module]
55 return info.properties.Name
56}
57
58func (s *singletonContext) ModuleDir(module Module) string {
59 info := s.context.moduleInfo[module]
60 return filepath.Dir(info.relBlueprintFile)
61}
62
63func (s *singletonContext) BlueprintFile(module Module) string {
64 info := s.context.moduleInfo[module]
65 return info.relBlueprintFile
66}
67
68func (s *singletonContext) ModuleErrorf(module Module, format string,
69 args ...interface{}) {
70
71 info := s.context.moduleInfo[module]
72 s.errs = append(s.errs, &Error{
73 Err: fmt.Errorf(format, args...),
74 Pos: info.pos,
75 })
76}
77
78func (s *singletonContext) Errorf(format string, args ...interface{}) {
79 // TODO: Make this not result in the error being printed as "internal error"
80 s.errs = append(s.errs, fmt.Errorf(format, args...))
81}
82
83func (s *singletonContext) Variable(name, value string) {
84 v, err := s.scope.AddLocalVariable(name, value)
85 if err != nil {
86 panic(err)
87 }
88
89 s.actionDefs.variables = append(s.actionDefs.variables, v)
90}
91
Jamie Genniscbc6f862014-06-05 20:00:22 -070092func (s *singletonContext) Rule(name string, params RuleParams,
93 argNames ...string) Rule {
94
Jamie Gennis1bc967e2014-05-27 16:34:41 -070095 // TODO: Verify that params.Pool is accessible in this module's scope.
96
Jamie Genniscbc6f862014-06-05 20:00:22 -070097 r, err := s.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070098 if err != nil {
99 panic(err)
100 }
101
102 s.actionDefs.rules = append(s.actionDefs.rules, r)
103
104 return r
105}
106
107func (s *singletonContext) Build(params BuildParams) {
108 // TODO: Verify that params.Rule is accessible in this module's scope.
109
110 def, err := parseBuildParams(s.scope, &params)
111 if err != nil {
112 panic(err)
113 }
114
115 s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def)
116}
117
118func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) {
119 s.context.requireNinjaVersion(major, minor, micro)
120}
121
122func (s *singletonContext) SetBuildDir(value string) {
123 ninjaValue, err := parseNinjaString(s.scope, value)
124 if err != nil {
125 panic(err)
126 }
127
128 s.context.setBuildDir(ninjaValue)
129}
130
131func (s *singletonContext) VisitAllModules(visit func(Module)) {
132 s.context.visitAllModules(visit)
133}
134
135func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool,
136 visit func(Module)) {
137
138 s.context.visitAllModulesIf(pred, visit)
139}