Home | History | Annotate | Download | only in blueprint
      1 // Copyright 2014 Google Inc. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package blueprint
     16 
     17 import (
     18 	"fmt"
     19 )
     20 
     21 type Singleton interface {
     22 	GenerateBuildActions(SingletonContext)
     23 }
     24 
     25 type SingletonContext interface {
     26 	Config() interface{}
     27 
     28 	ModuleName(module Module) string
     29 	ModuleDir(module Module) string
     30 	ModuleSubDir(module Module) string
     31 	BlueprintFile(module Module) string
     32 
     33 	ModuleErrorf(module Module, format string, args ...interface{})
     34 	Errorf(format string, args ...interface{})
     35 	Failed() bool
     36 
     37 	Variable(pctx PackageContext, name, value string)
     38 	Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
     39 	Build(pctx PackageContext, params BuildParams)
     40 	RequireNinjaVersion(major, minor, micro int)
     41 
     42 	// SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
     43 	// that controls where Ninja stores its build log files.  This value can be
     44 	// set at most one time for a single build, later calls are ignored.
     45 	SetNinjaBuildDir(pctx PackageContext, value string)
     46 
     47 	VisitAllModules(visit func(Module))
     48 	VisitAllModulesIf(pred func(Module) bool, visit func(Module))
     49 	VisitDepsDepthFirst(module Module, visit func(Module))
     50 	VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
     51 		visit func(Module))
     52 
     53 	VisitAllModuleVariants(module Module, visit func(Module))
     54 
     55 	PrimaryModule(module Module) Module
     56 	FinalModule(module Module) Module
     57 
     58 	AddNinjaFileDeps(deps ...string)
     59 }
     60 
     61 var _ SingletonContext = (*singletonContext)(nil)
     62 
     63 type singletonContext struct {
     64 	context *Context
     65 	config  interface{}
     66 	scope   *localScope
     67 
     68 	ninjaFileDeps []string
     69 	errs          []error
     70 
     71 	actionDefs localBuildActions
     72 }
     73 
     74 func (s *singletonContext) Config() interface{} {
     75 	return s.config
     76 }
     77 
     78 func (s *singletonContext) ModuleName(logicModule Module) string {
     79 	return s.context.ModuleName(logicModule)
     80 }
     81 
     82 func (s *singletonContext) ModuleDir(logicModule Module) string {
     83 	return s.context.ModuleDir(logicModule)
     84 }
     85 
     86 func (s *singletonContext) ModuleSubDir(logicModule Module) string {
     87 	return s.context.ModuleSubDir(logicModule)
     88 }
     89 
     90 func (s *singletonContext) BlueprintFile(logicModule Module) string {
     91 	return s.context.BlueprintFile(logicModule)
     92 }
     93 
     94 func (s *singletonContext) error(err error) {
     95 	if err != nil {
     96 		s.errs = append(s.errs, err)
     97 	}
     98 }
     99 
    100 func (s *singletonContext) ModuleErrorf(logicModule Module, format string,
    101 	args ...interface{}) {
    102 
    103 	s.error(s.context.ModuleErrorf(logicModule, format, args...))
    104 }
    105 
    106 func (s *singletonContext) Errorf(format string, args ...interface{}) {
    107 	// TODO: Make this not result in the error being printed as "internal error"
    108 	s.error(fmt.Errorf(format, args...))
    109 }
    110 
    111 func (s *singletonContext) Failed() bool {
    112 	return len(s.errs) > 0
    113 }
    114 
    115 func (s *singletonContext) Variable(pctx PackageContext, name, value string) {
    116 	s.scope.ReparentTo(pctx)
    117 
    118 	v, err := s.scope.AddLocalVariable(name, value)
    119 	if err != nil {
    120 		panic(err)
    121 	}
    122 
    123 	s.actionDefs.variables = append(s.actionDefs.variables, v)
    124 }
    125 
    126 func (s *singletonContext) Rule(pctx PackageContext, name string,
    127 	params RuleParams, argNames ...string) Rule {
    128 
    129 	s.scope.ReparentTo(pctx)
    130 
    131 	r, err := s.scope.AddLocalRule(name, &params, argNames...)
    132 	if err != nil {
    133 		panic(err)
    134 	}
    135 
    136 	s.actionDefs.rules = append(s.actionDefs.rules, r)
    137 
    138 	return r
    139 }
    140 
    141 func (s *singletonContext) Build(pctx PackageContext, params BuildParams) {
    142 	s.scope.ReparentTo(pctx)
    143 
    144 	def, err := parseBuildParams(s.scope, &params)
    145 	if err != nil {
    146 		panic(err)
    147 	}
    148 
    149 	s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def)
    150 }
    151 
    152 func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) {
    153 	s.context.requireNinjaVersion(major, minor, micro)
    154 }
    155 
    156 func (s *singletonContext) SetNinjaBuildDir(pctx PackageContext, value string) {
    157 	s.scope.ReparentTo(pctx)
    158 
    159 	ninjaValue, err := parseNinjaString(s.scope, value)
    160 	if err != nil {
    161 		panic(err)
    162 	}
    163 
    164 	s.context.setNinjaBuildDir(ninjaValue)
    165 }
    166 
    167 func (s *singletonContext) VisitAllModules(visit func(Module)) {
    168 	s.context.VisitAllModules(visit)
    169 }
    170 
    171 func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool,
    172 	visit func(Module)) {
    173 
    174 	s.context.VisitAllModulesIf(pred, visit)
    175 }
    176 
    177 func (s *singletonContext) VisitDepsDepthFirst(module Module,
    178 	visit func(Module)) {
    179 
    180 	s.context.VisitDepsDepthFirst(module, visit)
    181 }
    182 
    183 func (s *singletonContext) VisitDepsDepthFirstIf(module Module,
    184 	pred func(Module) bool, visit func(Module)) {
    185 
    186 	s.context.VisitDepsDepthFirstIf(module, pred, visit)
    187 }
    188 
    189 func (s *singletonContext) PrimaryModule(module Module) Module {
    190 	return s.context.PrimaryModule(module)
    191 }
    192 
    193 func (s *singletonContext) FinalModule(module Module) Module {
    194 	return s.context.FinalModule(module)
    195 }
    196 
    197 func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Module)) {
    198 	s.context.VisitAllModuleVariants(module, visit)
    199 }
    200 
    201 func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
    202 	s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
    203 }
    204