From aaa6ce230191c53c6a91f06349aa128e0fff2c56 Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Wed, 20 Apr 2011 12:02:29 +1000 Subject: [PATCH] goinstall: support building executable commands 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 | 11 ++--------- src/cmd/goinstall/make.go | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/cmd/goinstall/main.go b/src/cmd/goinstall/main.go index 8fec8e312a..8082ace6b4 100644 --- a/src/cmd/goinstall/main.go +++ b/src/cmd/goinstall/main.go @@ -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 { diff --git a/src/cmd/goinstall/make.go b/src/cmd/goinstall/make.go index ceb119e5a4..8714204352 100644 --- a/src/cmd/goinstall/make.go +++ b/src/cmd/goinstall/make.go @@ -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) -- 2.48.1