github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/pkg/products/products.go (about) 1 // Copyright 2016 Palantir Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package products 16 17 import ( 18 "fmt" 19 "os/exec" 20 "path" 21 "runtime" 22 "strings" 23 ) 24 25 // List returns a slice that contains all of the products in the project. 26 func List() ([]string, error) { 27 gödelw, err := newGödelwRunner() 28 if err != nil { 29 return nil, err 30 } 31 products, err := gödelw.run("products") 32 if err != nil { 33 return nil, err 34 } 35 return strings.Split(products, "\n"), nil 36 } 37 38 // Bin returns the path to the executable for the given product for the current OS/Architecture, building the executable 39 // using "godelw build" if the executable does not already exist or is not up-to-date. 40 func Bin(product string) (string, error) { 41 gödelw, err := newGödelwRunner() 42 if err != nil { 43 return "", err 44 } 45 currOSArchFlag := fmt.Sprintf("--os-arch=%s-%s", runtime.GOOS, runtime.GOARCH) 46 requiresBuildOutput, err := gödelw.run("artifacts", "build", "--absolute", currOSArchFlag, "--requires-build", product) 47 if err != nil { 48 return "", err 49 } 50 if requiresBuildOutput != "" { 51 if _, err := gödelw.run("build", currOSArchFlag, product); err != nil { 52 return "", err 53 } 54 } 55 binPath, err := gödelw.run("artifacts", "build", "--absolute", currOSArchFlag, product) 56 if err != nil { 57 return "", err 58 } 59 if binPath == "" { 60 return "", fmt.Errorf("no build artifact for product %s with GOOS %s and GOARCH %s", product, runtime.GOOS, runtime.GOARCH) 61 } 62 return binPath, nil 63 } 64 65 // Dist builds the distribution for the specified product using the "godelw dist" command and returns the path to the 66 // created distribution artifact. 67 func Dist(product string) (string, error) { 68 gödelw, err := newGödelwRunner() 69 if err != nil { 70 return "", err 71 } 72 if _, err := gödelw.run("dist", product); err != nil { 73 return "", err 74 } 75 return gödelw.run("artifacts", "dist", "--absolute", product) 76 } 77 78 type gödelwRunner interface { 79 run(args ...string) (string, error) 80 } 81 82 type gödelwRunnerStruct struct { 83 path string 84 } 85 86 func (g *gödelwRunnerStruct) run(args ...string) (string, error) { 87 cmd := exec.Command(g.path, args...) 88 output, err := cmd.CombinedOutput() 89 outputStr := strings.TrimSpace(string(output)) 90 if err != nil { 91 err = fmt.Errorf("command %v failed with output:\n%s\nError: %v", cmd.Args, outputStr, err) 92 } 93 return outputStr, err 94 } 95 96 func newGödelwRunner() (gödelwRunner, error) { 97 path, err := gödelwPath() 98 if err != nil { 99 return nil, err 100 } 101 return &gödelwRunnerStruct{ 102 path: path, 103 }, nil 104 } 105 106 func gödelwPath() (string, error) { 107 projectDir, err := projectDir() 108 if err != nil { 109 return "", err 110 } 111 return path.Join(projectDir, "godelw"), nil 112 } 113 114 func projectDir() (string, error) { 115 cmd := exec.Command("git", "rev-parse", "--show-toplevel") 116 output, err := cmd.CombinedOutput() 117 outputStr := strings.TrimSpace(string(output)) 118 if err != nil { 119 err = fmt.Errorf("command %v failed with output:\n%s\nError: %v", cmd.Args, outputStr, err) 120 } 121 return outputStr, err 122 }