pulumi/pkg/backend/cloud/context.go
2018-05-22 15:02:47 -07:00

83 lines
2.8 KiB
Go

// Copyright 2016-2018, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cloud
import (
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/pulumi/pulumi/pkg/util/fsutil"
"github.com/pulumi/pulumi/pkg/workspace"
)
// getContextAndMain computes the root path of the archive as well as the relative path (from the archive root)
// to the main function. In the case where there is no custom archive root, things are simple, the archive root
// is the root of the project, and main can remain unchanged. When an context is set, however, we need to do some
// work:
//
// 1. We need to ensure the archive root is "above" the project root.
// 2. We need to change "main" which was relative to the project root to be relative to the archive root.
//
// Note that the relative paths in Pulumi.yaml for Context and Main are always unix style paths, but the returned
// context is an absolute path, using file system specific seperators. We continue use a unix style partial path for
// Main.
func getContextAndMain(proj *workspace.Project, projectRoot string) (string, string, error) {
context, err := filepath.Abs(projectRoot)
if err != nil {
return "", "", err
}
main := proj.Main
if proj.Context != "" {
context, err = filepath.Abs(filepath.Join(context,
strings.Replace(proj.Context, "/", string(filepath.Separator), -1)))
if err != nil {
return "", "", err
}
if !strings.HasPrefix(projectRoot, context) {
return "", "", errors.Errorf("Context directory '%v' is not a parent of '%v'", context, projectRoot)
}
// Walk up to the archive root, starting from the project root, recording the directories we see,
// we'll combine these with the existing main value to get a main relative to the root of the archive
// which is what the pulumi-service expects. We use fsutil.WalkUp here, so we have to provide a dummy
// function which ignores every file we visit.
ignoreFileVisitFunc := func(string) bool {
// return false so fsutil.Walk does not stop early
return false
}
prefix := ""
_, err := fsutil.WalkUp(projectRoot, ignoreFileVisitFunc, func(p string) bool {
if p != context {
prefix = filepath.Base(p) + "/" + prefix
return true
}
return false
})
if err != nil {
return "", "", err
}
main = prefix + main
}
return context, main, nil
}