]> Cypherpunks repositories - gostls13.git/commitdiff
goinstall: support building executable commands
authorAndrew Gerrand <adg@golang.org>
Wed, 20 Apr 2011 02:02:29 +0000 (12:02 +1000)
committerAndrew Gerrand <adg@golang.org>
Wed, 20 Apr 2011 02:02:29 +0000 (12:02 +1000)
This CL gives goinstall the ability to build commands,
not just packages.

"goinstall foo.googlecode.com/hg/bar" will build the command named
"bar" and install it to GOBIN. "goinstall ." will use the name of the
local directory as the command name.

R=rsc, niemeyer
CC=golang-dev
https://golang.org/cl/4426045

src/cmd/goinstall/main.go
src/cmd/goinstall/make.go

index 8fec8e312a9770bf2cf3a0b9bd3b55a787c6dff4..8082ace6b48d13c4fe8721b38dd5e6f6f38cda80 100644 (file)
@@ -192,18 +192,11 @@ func install(pkg, parent string) {
                        install(p, pkg)
                }
        }
-       if dirInfo.pkgName == "main" {
-               if !errors {
-                       fmt.Fprintf(os.Stderr, "%s: %s's dependencies are installed.\n", argv0, pkg)
-               }
-               errors = true
-               visit[pkg] = done
-               return
-       }
 
        // Install this package.
        if !errors {
-               if err := domake(dir, pkg, local); err != nil {
+               isCmd := dirInfo.pkgName == "main"
+               if err := domake(dir, pkg, local, isCmd); err != nil {
                        fmt.Fprintf(os.Stderr, "%s: installing %s: %s\n", argv0, pkg, err)
                        errors = true
                } else if !local && *logPkgs {
index ceb119e5a4734aba85abbc75e453589d9fda7def..8714204352182609a1f62fb316958d1b4b1a1860 100644 (file)
@@ -9,6 +9,7 @@ package main
 import (
        "bytes"
        "os"
+       "path/filepath"
        "template"
 )
 
@@ -17,7 +18,7 @@ import (
 // For non-local packages or packages without Makefiles,
 // domake generates a standard Makefile and passes it
 // to make on standard input.
-func domake(dir, pkg string, local bool) (err os.Error) {
+func domake(dir, pkg string, local, isCmd bool) (err os.Error) {
        needMakefile := true
        if local {
                _, err := os.Stat(dir + "/Makefile")
@@ -28,7 +29,7 @@ func domake(dir, pkg string, local bool) (err os.Error) {
        cmd := []string{"gomake"}
        var makefile []byte
        if needMakefile {
-               if makefile, err = makeMakefile(dir, pkg); err != nil {
+               if makefile, err = makeMakefile(dir, pkg, isCmd); err != nil {
                        return err
                }
                cmd = append(cmd, "-f-")
@@ -43,11 +44,24 @@ func domake(dir, pkg string, local bool) (err os.Error) {
 // makeMakefile computes the standard Makefile for the directory dir
 // installing as package pkg.  It includes all *.go files in the directory
 // except those in package main and those ending in _test.go.
-func makeMakefile(dir, pkg string) ([]byte, os.Error) {
-       if !safeName(pkg) {
+func makeMakefile(dir, pkg string, isCmd bool) ([]byte, os.Error) {
+       targ := pkg
+       if isCmd {
+               // use the last part of the package name only
+               _, targ = filepath.Split(pkg)
+               // if building the working dir use the directory name
+               if targ == "." {
+                       d, err := filepath.Abs(dir)
+                       if err != nil {
+                               return nil, os.NewError("finding path: " + err.String())
+                       }
+                       _, targ = filepath.Split(d)
+               }
+       }
+       if !safeName(targ) {
                return nil, os.ErrorString("unsafe name: " + pkg)
        }
-       dirInfo, err := scanDir(dir, false)
+       dirInfo, err := scanDir(dir, isCmd)
        if err != nil {
                return nil, err
        }
@@ -94,7 +108,10 @@ func makeMakefile(dir, pkg string) ([]byte, os.Error) {
        }
 
        var buf bytes.Buffer
-       md := makedata{pkg, goFiles, oFiles, cgoFiles, cgoOFiles}
+       md := makedata{targ, "pkg", goFiles, oFiles, cgoFiles, cgoOFiles}
+       if isCmd {
+               md.Type = "cmd"
+       }
        if err := makefileTemplate.Execute(&buf, &md); err != nil {
                return nil, err
        }
@@ -104,6 +121,9 @@ func makeMakefile(dir, pkg string) ([]byte, os.Error) {
 var safeBytes = []byte("+-./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz")
 
 func safeName(s string) bool {
+       if len(s) == 0 {
+               return false
+       }
        for i := 0; i < len(s); i++ {
                if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
                        return false
@@ -114,7 +134,8 @@ func safeName(s string) bool {
 
 // makedata is the data type for the makefileTemplate.
 type makedata struct {
-       Pkg       string   // package import path
+       Targ      string   // build target
+       Type      string   // build type: "pkg" or "cmd"
        GoFiles   []string // list of non-cgo .go files
        OFiles    []string // list of .$O files
        CgoFiles  []string // list of cgo .go files
@@ -124,7 +145,7 @@ type makedata struct {
 var makefileTemplate = template.MustParse(`
 include $(GOROOT)/src/Make.inc
 
-TARG={Pkg}
+TARG={Targ}
 
 {.section GoFiles}
 GOFILES=\
@@ -154,6 +175,6 @@ CGO_OFILES=\
 {.end}
 
 {.end}
-include $(GOROOT)/src/Make.pkg
+include $(GOROOT)/src/Make.{Type}
 `,
        nil)