pulumi/pkg/workspace/paths.go
joeduffy e75f06bb2b Sketch a mu build command and its scaffolding
This adds a bunch of general scaffolding and the beginning of a `build` command.

The general engineering scaffolding includes:

* Glide for dependency management.
* A Makefile that runs govet and golint during builds.
* Google's Glog library for logging.
* Cobra for command line functionality.

The Mu-specific scaffolding includes some packages:

* mu/pkg/diag: A package for compiler-like diagnostics.  It's fairly barebones
  at the moment, however we can embellish this over time.
* mu/pkg/errors: A package containing Mu's predefined set of errors.
* mu/pkg/workspace: A package containing workspace-related convenience helpers.

in addition to a main entrypoint that simply wires up and invokes the CLI.  From
there, the mu/cmd package takes over, with the Cobra-defined CLI commands.

Finally, the mu/pkg/compiler package actually implements the compiler behavior.
Or, it will.  For now, it simply parses a JSON or YAML Mufile into the core
mu/pkg/api types, and prints out the result.
2016-11-15 14:30:34 -05:00

73 lines
1.5 KiB
Go

// Copyright 2016 Marapongo, Inc. All rights reserved.
package workspace
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
)
const mufileBase = "Mu"
var mufileExts = []string{"json", "yaml"}
// DetectMufile locates the closest Mufile from the given path, searching "upwards" in the directory hierarchy. If
// no Mufile is found, a non-nil error is returned.
func DetectMufile(from string) (string, error) {
abs, err := filepath.Abs(from)
if err != nil {
return "", err
}
// It's possible the target is already the file we seek; if so, return right away.
if IsMufile(abs) {
return abs, nil
}
curr := abs
for {
// If the target is a directory, enumerate its files, checking each to see if it's a Mufile.
files, err := ioutil.ReadDir(curr)
if err != nil {
return "", err
}
for _, file := range files {
path := filepath.Join(curr, file.Name())
if IsMufile(path) {
return path, nil
}
}
// If neither succeeded, keep looking in our parent directory.
curr = filepath.Dir(curr)
if os.IsPathSeparator(curr[len(curr)-1]) {
break
}
}
return "", errors.New("No Mufile found")
}
// IsMufile returns true if the path references what appears to be a valid Mufile.
func IsMufile(path string) bool {
info, err := os.Stat(path)
if err != nil {
return false
}
// Directories can't be Mufiles.
if info.IsDir() {
return false
}
// Check all supported extensions.
for _, ext := range mufileExts {
if info.Name() == mufileBase+"."+ext {
return true
}
}
return false
}