Merge pull request #52 from kulakowski/patch-1

Add new line to fatal error messages in bootstrap
diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go
index b157440..4deb3cf 100644
--- a/bootstrap/bootstrap.go
+++ b/bootstrap/bootstrap.go
@@ -23,8 +23,8 @@
 	"github.com/google/blueprint/pathtools"
 )
 
-const bootstrapDir = "$buildDir/.bootstrap"
-const miniBootstrapDir = "$buildDir/.minibootstrap"
+const bootstrapSubDir = ".bootstrap"
+const miniBootstrapSubDir = ".minibootstrap"
 
 var (
 	pctx = blueprint.NewPackageContext("github.com/google/blueprint/bootstrap")
@@ -102,6 +102,9 @@
 	minibpFile = filepath.Join("$BinDir", "minibp")
 
 	docsDir = filepath.Join(bootstrapDir, "docs")
+
+	bootstrapDir = filepath.Join("$buildDir", bootstrapSubDir)
+	miniBootstrapDir = filepath.Join("$buildDir", miniBootstrapSubDir)
 )
 
 type bootstrapGoCore interface {
@@ -837,7 +840,7 @@
 		// cleanup
 		ctx.Build(pctx, blueprint.BuildParams{
 			Rule:    blueprint.Phony,
-			Outputs: []string{mainNinjaFile, docsFile},
+			Outputs: []string{mainNinjaFile, docsFile, "$bootstrapManifest"},
 		})
 
 		if primaryBuilderName == "minibp" {
diff --git a/bootstrap/cleanup.go b/bootstrap/cleanup.go
index 1e1fc03..89c4b3e 100644
--- a/bootstrap/cleanup.go
+++ b/bootstrap/cleanup.go
@@ -32,12 +32,12 @@
 func removeAbandonedFiles(ctx *blueprint.Context, config *Config,
 	srcDir, manifestFile string) error {
 
-	buildDir := "."
+	buildDir := BuildDir
 	switch config.stage {
 	case StageBootstrap:
-		buildDir = miniBootstrapDir
+		buildDir = filepath.Join(buildDir, miniBootstrapSubDir)
 	case StagePrimary:
-		buildDir = bootstrapDir
+		buildDir = filepath.Join(buildDir, bootstrapSubDir)
 	}
 
 	targetRules, err := ctx.AllTargets()
diff --git a/context.go b/context.go
index 0109dd3..c5e8b15 100644
--- a/context.go
+++ b/context.go
@@ -69,7 +69,7 @@
 	moduleGroups        map[string]*moduleGroup
 	moduleInfo          map[Module]*moduleInfo
 	modulesSorted       []*moduleInfo
-	singletonInfo       map[string]*singletonInfo
+	singletonInfo       []*singletonInfo
 	mutatorInfo         []*mutatorInfo
 	earlyMutatorInfo    []*earlyMutatorInfo
 	variantMutatorNames []string
@@ -195,6 +195,7 @@
 	// set during RegisterSingletonType
 	factory   SingletonFactory
 	singleton Singleton
+	name      string
 
 	// set during PrepareBuildActions
 	actionDefs localBuildActions
@@ -227,7 +228,6 @@
 		moduleFactories:  make(map[string]ModuleFactory),
 		moduleGroups:     make(map[string]*moduleGroup),
 		moduleInfo:       make(map[Module]*moduleInfo),
-		singletonInfo:    make(map[string]*singletonInfo),
 		moduleNinjaNames: make(map[string]*moduleGroup),
 	}
 }
@@ -312,20 +312,24 @@
 
 // RegisterSingletonType registers a singleton type that will be invoked to
 // generate build actions.  Each registered singleton type is instantiated and
-// and invoked exactly once as part of the generate phase.
+// and invoked exactly once as part of the generate phase.  Each registered
+// singleton is invoked in registration order.
 //
 // The singleton type names given here must be unique for the context.  The
 // factory function should be a named function so that its package and name can
 // be included in the generated Ninja file for debugging purposes.
 func (c *Context) RegisterSingletonType(name string, factory SingletonFactory) {
-	if _, present := c.singletonInfo[name]; present {
-		panic(errors.New("singleton name is already registered"))
+	for _, s := range c.singletonInfo {
+		if s.name == name {
+			panic(errors.New("singleton name is already registered"))
+		}
 	}
 
-	c.singletonInfo[name] = &singletonInfo{
+	c.singletonInfo = append(c.singletonInfo, &singletonInfo{
 		factory:   factory,
 		singleton: factory(),
-	}
+		name:      name,
+	})
 }
 
 func singletonPkgPath(singleton Singleton) string {
@@ -1706,11 +1710,11 @@
 	var deps []string
 	var errs []error
 
-	for name, info := range c.singletonInfo {
+	for _, info := range c.singletonInfo {
 		// The parent scope of the singletonContext's local scope gets overridden to be that of the
 		// calling Go package on a per-call basis.  Since the initial parent scope doesn't matter we
 		// just set it to nil.
-		scope := newLocalScope(nil, singletonNamespacePrefix(name))
+		scope := newLocalScope(nil, singletonNamespacePrefix(info.name))
 
 		sctx := &singletonContext{
 			context: c,
@@ -2492,15 +2496,7 @@
 
 	buf := bytes.NewBuffer(nil)
 
-	singletonNames := make([]string, 0, len(c.singletonInfo))
-	for name := range c.singletonInfo {
-		singletonNames = append(singletonNames, name)
-	}
-	sort.Strings(singletonNames)
-
-	for _, name := range singletonNames {
-		info := c.singletonInfo[name]
-
+	for _, info := range c.singletonInfo {
 		if len(info.actionDefs.variables)+len(info.actionDefs.rules)+len(info.actionDefs.buildDefs) == 0 {
 			continue
 		}
@@ -2512,7 +2508,7 @@
 
 		buf.Reset()
 		infoMap := map[string]interface{}{
-			"name":      name,
+			"name":      info.name,
 			"goFactory": factoryName,
 		}
 		err = headerTemplate.Execute(buf, infoMap)