pulumi/cmd/lumi/pack.go
joeduffy 35aa6b7559 Rename pulumi/lumi to pulumi/pulumi-fabric
We are renaming Lumi to Pulumi Fabric.  This change simply renames the
pulumi/lumi repo to pulumi/pulumi-fabric, without the CLI tools and other
changes that will follow soon afterwards.
2017-08-02 09:25:22 -07:00

119 lines
3.7 KiB
Go

// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/pulumi/pulumi-fabric/pkg/encoding"
"github.com/pulumi/pulumi-fabric/pkg/pack"
"github.com/pulumi/pulumi-fabric/pkg/util/cmdutil"
"github.com/pulumi/pulumi-fabric/pkg/util/contract"
"github.com/pulumi/pulumi-fabric/pkg/workspace"
)
func newPackCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "pack",
Short: "Manage packages",
}
cmd.AddCommand(newPackEvalCmd())
cmd.AddCommand(newPackInfoCmd())
cmd.AddCommand(newPackGetCmd())
cmd.AddCommand(newPackVerifyCmd())
return cmd
}
// detectPackage returns a package given the path, or returns an error if one could not be located.
func detectPackage(path string) (*pack.Package, error) {
pkgpath, err := workspace.DetectPackage(path, cmdutil.Diag())
if err != nil {
return nil, errors.Errorf("could not locate a package to load: %v", err)
} else if pkgpath == "" {
return nil, errors.Errorf("no package found at: %v", err)
}
pkg, _ := readPackage(pkgpath)
contract.Assert(pkg != nil)
return pkg, nil
}
// readPackageFromArg reads a package from an argument value. It can be "-" to request reading from Stdin, and is
// interpreted as a path otherwise. If an error occurs, it is printed to Stderr, and the returned value will be nil.
// In addition to the package, a root directory is returned that the compiler should be formed over, if any.
func readPackageFromArg(arg string) (*pack.Package, string) {
// If the arg is simply "-", read from stdin.
if arg == "-" {
return readPackageFromStdin(), ""
}
// Read the package from a file.
return readPackage(arg)
}
// readPackageFromStdin attempts to read a package from Stdin; if an error occurs, it will be printed to Stderr, and
// the returned value will be nil.
func readPackageFromStdin() *pack.Package {
// If stdin, read the package from text, and then create a compiler using the working directory.
b, err := ioutil.ReadAll(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "error: could not read from stdin\n")
fmt.Fprintf(os.Stderr, " %v\n", err)
return nil
}
return DecodePackage(encoding.Marshalers[".json"], b, "stdin")
}
// readPackage attempts to read a package from the given path; if an error occurs, it will be printed to Stderr, and
// the returned value will be nil. If the path is a directory, nil is returned.
func readPackage(path string) (*pack.Package, string) {
// If it's a directory, bail early.
info, err := os.Stat(path)
if err != nil {
fmt.Fprintf(os.Stderr, "error: could not read path '%v': %v\n", path, err)
return nil, ""
}
if info.IsDir() {
return nil, path
}
// Lookup the marshaler for this format.
ext := filepath.Ext(path)
m, has := encoding.Marshalers[ext]
if !has {
fmt.Fprintf(os.Stderr, "error: no marshaler found for file format '%v'\n", ext)
return nil, ""
}
// Read the contents.
b, err := ioutil.ReadFile(path)
if err != nil {
fmt.Fprintf(os.Stderr, "error: a problem occurred when reading file '%v'\n", path)
fmt.Fprintf(os.Stderr, " %v\n", err)
return nil, ""
}
return DecodePackage(m, b, path), filepath.Dir(path)
}
// DecodePackage turns a byte array into a package using the given marshaler. If an error occurs, it is printed to
// Stderr, and the returned package value will be nil.
func DecodePackage(m encoding.Marshaler, b []byte, path string) *pack.Package {
// Unmarshal the contents into a fresh package.
pkg, err := encoding.Decode(m, b)
if err != nil {
fmt.Fprintf(os.Stderr, "error: a problem occurred when unmarshaling file '%v'\n", path)
fmt.Fprintf(os.Stderr, " %v\n", err)
return nil
}
return pkg
}