// 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 httpstate 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 }