github.com/Xenoex/gopm@v0.6.5/cmd/bin.go (about) 1 // Copyright 2013-2014 gopm authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // 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, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package cmd 16 17 import ( 18 "fmt" 19 "os" 20 "path" 21 "path/filepath" 22 "runtime" 23 "strings" 24 25 "github.com/Unknwon/com" 26 "github.com/codegangsta/cli" 27 28 "github.com/gpmgo/gopm/doc" 29 "github.com/gpmgo/gopm/log" 30 ) 31 32 var CmdBin = cli.Command{ 33 Name: "bin", 34 Usage: "download and link dependencies and build executable binary", 35 Description: `Command bin downloads and links dependencies according to gopmfile, 36 and build executable binary to work directory 37 38 gopm bin <import path>@[<tag|commit|branch>:<value>] 39 gopm bin <package name>@[<tag|commit|branch>:<value>] 40 41 Can only specify one each time, and only works for projects that 42 contain main package`, 43 Action: runBin, 44 Flags: []cli.Flag{ 45 cli.BoolFlag{"dir, d", "build binary to given directory(second argument)"}, 46 cli.BoolFlag{"update, u", "update pakcage(s) and dependencies if any"}, 47 cli.BoolFlag{"verbose, v", "show process details"}, 48 }, 49 } 50 51 func runBin(ctx *cli.Context) { 52 setup(ctx) 53 54 if len(ctx.Args()) == 0 { 55 log.Error("bin", "Cannot start command:") 56 log.Fatal("", "\tNo package specified") 57 } 58 59 installRepoPath = doc.HomeDir + "/repos" 60 log.Log("Local repository path: %s", installRepoPath) 61 62 // Check arguments. 63 num := 1 64 if ctx.Bool("dir") { 65 num = 2 66 } 67 if len(ctx.Args()) != num { 68 log.Error("bin", "Cannot start command:") 69 log.Fatal("", "\tMissing indicated path to build binary") 70 } 71 72 // Check if given directory exists. 73 if ctx.Bool("dir") && !com.IsDir(ctx.Args()[1]) { 74 log.Error("bin", "Cannot start command:") 75 log.Fatal("", "\tIndicated path does not exist or is not a directory") 76 } 77 78 // Parse package version. 79 info := ctx.Args()[0] 80 pkgPath := info 81 node := doc.NewNode(pkgPath, pkgPath, doc.BRANCH, "", true) 82 if i := strings.Index(info, "@"); i > -1 { 83 pkgPath = info[:i] 84 node.Type, node.Value = validPath(info[i+1:]) 85 } 86 87 // Check package name. 88 if !strings.Contains(pkgPath, "/") { 89 pkgPath = doc.GetPkgFullPath(pkgPath) 90 } 91 92 node.ImportPath = pkgPath 93 node.DownloadURL = pkgPath 94 95 // Get code. 96 downloadPackages(ctx, []*doc.Node{node}) 97 98 // Check if previous steps were successful. 99 repoPath := installRepoPath + "/" + pkgPath + versionSuffix(node.Value) 100 if !com.IsDir(repoPath) { 101 log.Error("bin", "Cannot continue command:") 102 log.Fatal("", "\tPrevious steps weren't successful") 103 } 104 105 wd, err := os.Getwd() 106 if err != nil { 107 log.Error("bin", "Cannot get work directory:") 108 log.Fatal("", "\t"+err.Error()) 109 } 110 111 // Change to repository path. 112 log.Log("Changing work directory to %s", repoPath) 113 if err = os.Chdir(repoPath); err != nil { 114 log.Error("bin", "Fail to change work directory:") 115 log.Fatal("", "\t"+err.Error()) 116 } 117 118 defer os.RemoveAll(path.Join(repoPath, doc.VENDOR)) 119 // Build application. 120 buildBinary(ctx) 121 122 includes := make([]string, 0, 3) 123 // Check if previous steps were successful. 124 if com.IsFile(doc.GOPM_FILE_NAME) { 125 log.Trace("Loading gopmfile...") 126 gf := doc.NewGopmfile(".") 127 128 var err error 129 pkgName, err = gf.GetValue("target", "path") 130 if err == nil { 131 log.Log("Target name: %s", pkgName) 132 } 133 134 includes = strings.Split(gf.MustValue("res", "include"), "|") 135 } 136 137 if len(pkgName) == 0 { 138 _, pkgName = filepath.Split(pkgPath) 139 } 140 141 // Because build command moved binary to root path. 142 binName := path.Base(pkgName) 143 if runtime.GOOS == "windows" { 144 binName += ".exe" 145 } 146 if !com.IsFile(binName) { 147 log.Error("bin", "Binary does not exist:") 148 log.Error("", "\t"+binName) 149 log.Fatal("", "\tPrevious steps weren't successful or the project does not contain main package") 150 } 151 152 // Move binary to given directory. 153 movePath := wd 154 if ctx.Bool("dir") { 155 movePath = ctx.Args()[1] 156 } 157 158 if com.IsExist(movePath + "/" + binName) { 159 if err = os.Remove(movePath + "/" + binName); err != nil { 160 log.Warn("Cannot remove binary in work directory:") 161 log.Warn("\t %s", err) 162 } 163 } 164 165 if err = os.Rename(binName, movePath+"/"+binName); err != nil { 166 log.Error("bin", "Fail to move binary:") 167 log.Fatal("", "\t"+err.Error()) 168 } 169 os.Chmod(movePath+"/"+binName, os.ModePerm) 170 171 if len(includes) > 0 { 172 log.Log("Copying resources to %s", movePath) 173 for _, include := range includes { 174 if com.IsDir(include) { 175 if err = com.CopyDir(include, filepath.Join(movePath, include)); err != nil { 176 log.Error("bin", "Fail to copy following resource:") 177 log.Error("", "\t"+include) 178 } 179 } 180 } 181 } 182 183 log.Log("Changing work directory back to %s", wd) 184 os.Chdir(wd) 185 186 log.Success("SUCC", "bin", "Command executed successfully!") 187 fmt.Println("Binary has been built into: " + movePath) 188 }