Skip to content

Commit

Permalink
Support for compile library(non-main package)。close #10
Browse files Browse the repository at this point in the history
  • Loading branch information
voidint committed Jan 29, 2017
1 parent 890ed99 commit d603586
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 51 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ It only covers the most common items, and tries to guess sensible defaults.
Press ^C at any time to quit.
tool: (go_install) go_build
Do you want to continue?[y/n] y
package: (main) github.com/voidint/gbb/build
importpath: (main) github.com/voidint/gbb/build
variable: Date
value: {{.Date}}
Do you want to continue?[y/n] y
Expand All @@ -219,7 +219,7 @@ About to write to /Users/voidint/cloud/workspace/go/lib/src/github.com/voidint/g
{
"version": "0.2.0",
"tool": "go build",
"package": "github.com/voidint/gbb/build",
"importpath": "github.com/voidint/gbb/build",
"variables": [
{
"variable": "Date",
Expand Down Expand Up @@ -261,7 +261,7 @@ commit: db8b606cfc2b24a24e2e09acac24a52c47b68401
{
"version": "0.2.0",
"tool": "go build",
"package": "github.com/voidint/gbb/build",
"importpath": "github.com/voidint/gbb/build",
"variables": [
{
"variable": "Date",
Expand Down Expand Up @@ -289,6 +289,10 @@ commit: db8b606cfc2b24a24e2e09acac24a52c47b68401


## changelog
### 0.4.0 -
- `gbb.json`中的配置项`package`重命名为`importpath`[#9](https://github.com/voidint/gbb/issues/9)
- 新增命令行选项`--config`用于自定义配置文件路径。[#16](https://github.com/voidint/gbb/issues/16)

### 0.3.0 - 2017/01/09
- 若开启debug模式`gbb --debug`,那么变量表达式求值过程详情也一并输出。[#12](https://github.com/voidint/gbb/issues/12) [#6](https://github.com/voidint/gbb/issues/6)
- 变量表达式首字母大写。[#11](https://github.com/voidint/gbb/issues/11)
Expand Down
76 changes: 48 additions & 28 deletions tool/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,25 @@ func Build(conf *config.Config, dir string) error {

// buildDir 切换到指定工作目录,调用指定的编译工具进行编译。
func buildDir(conf *config.Config, dir string) (err error) {
wd, err := os.Getwd()
if err != nil {
if err = chdir(dir, conf.Debug); err != nil {
return err
}
if wd != dir {
if conf.Debug {
fmt.Printf("==> cd %s\n", dir)
}
if err = os.Chdir(dir); err != nil {
return err
}
}

cmdArgs := strings.Fields(conf.Tool) // go install ==> []string{"go", "install"}

var buf bytes.Buffer
for i := range conf.Variables {
varName := strings.TrimSpace(conf.Variables[i].Variable)
varExpr := strings.TrimSpace(conf.Variables[i].Value)

if conf.Debug {
fmt.Printf("==> eval(%q)\n", varExpr)
}
val, err := variable.Eval(varExpr, conf.Debug)
mainPkg, err := isMainPkg(dir)
if err != nil {
return err
}
if mainPkg {
flags, err := ldflags(conf)
if err != nil {
return err
}
if conf.Debug {
fmt.Println(val)
}
buf.WriteString(fmt.Sprintf(`-X "%s.%s=%s"`, conf.Importpath, varName, val))
if i < len(conf.Variables)-1 {
buf.WriteByte(' ')
if flags != "" {
cmdArgs = append(cmdArgs, "-ldflags", flags)
}
}
if buf.Len() > 0 {
cmdArgs = append(cmdArgs, "-ldflags", buf.String())
}

if conf.Debug {
fmt.Print("==> ", cmdArgs[0])
Expand All @@ -92,3 +73,42 @@ func buildDir(conf *config.Config, dir string) (err error) {
cmd.Stderr = os.Stderr
return cmd.Run()
}

func chdir(dir string, debug bool) (err error) {
wd, err := os.Getwd()
if err != nil {
return err
}
if wd == dir {
return nil
}

if debug {
fmt.Printf("==> cd %s\n", dir)
}
return os.Chdir(dir)
}

func ldflags(conf *config.Config) (flags string, err error) {
var buf bytes.Buffer
for i := range conf.Variables {
varName := strings.TrimSpace(conf.Variables[i].Variable)
varExpr := strings.TrimSpace(conf.Variables[i].Value)

if conf.Debug {
fmt.Printf("==> eval(%q)\n", varExpr)
}
val, err := variable.Eval(varExpr, conf.Debug)
if err != nil {
return "", err
}
if conf.Debug {
fmt.Println(val)
}
buf.WriteString(fmt.Sprintf(`-X "%s.%s=%s"`, conf.Importpath, varName, val))
if i < len(conf.Variables)-1 {
buf.WriteByte(' ')
}
}
return buf.String(), nil
}
50 changes: 36 additions & 14 deletions tool/golang.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"os"
"path/filepath"
"runtime"
Expand All @@ -27,7 +26,7 @@ func NewGoBuilder(conf *config.Config) *GoBuilder {

// Build 切换到指定工作目录后调用编译工具编译。
func (b *GoBuilder) Build(rootDir string) error {
paths, err := walkMainDir(rootDir)
paths, err := walkPkgs(rootDir)
if err != nil {
return err
}
Expand All @@ -40,7 +39,7 @@ func (b *GoBuilder) Build(rootDir string) error {
}

// 查找root及其子孙目录下所有的main包路径
func walkMainDir(rootDir string) (paths []string, err error) {
func walkMainPkgs(rootDir string) (paths []string, err error) {
return paths, filepath.Walk(rootDir, func(path string, info os.FileInfo, e error) error {
if e != nil {
return e
Expand Down Expand Up @@ -92,7 +91,7 @@ func hasMain(srcfile string) (bool, error) {
return false, nil
}

func walkPkgDir(rootDir string) (paths []string, err error) {
func walkPkgs(rootDir string) (paths []string, err error) {
return paths, filepath.Walk(rootDir, func(path string, info os.FileInfo, e error) error {
if e != nil {
return e
Expand Down Expand Up @@ -120,22 +119,45 @@ func walkPkgDir(rootDir string) (paths []string, err error) {

// isGoPkg 判断路径是否是golang的包
func isGoPkg(path string) (yes bool, err error) {
path = strings.TrimSpace(path)
// path = strings.TrimSpace(path)
// if path == "" {
// return false, nil
// }
// infos, err := ioutil.ReadDir(path)
// if err != nil {
// return false, err
// }

// for i := range infos {
// if infos[i].IsDir() {
// continue
// }
// if ext := filepath.Ext(infos[i].Name()); ext == ".go" { // TODO 排除go test目录
// return true, nil
// }
// }
// return false, nil

if path == "" {
return false, nil
}
infos, err := ioutil.ReadDir(path)
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, path, nil, 0)
if err != nil {
return false, err
}
return len(pkgs) > 0, nil
}

for i := range infos {
if infos[i].IsDir() {
continue
}
if ext := filepath.Ext(infos[i].Name()); ext == ".go" { // TODO 排除go test目录
return true, nil
}
func isMainPkg(path string) (yes bool, err error) {
if path == "" {
return false, nil
}
return false, nil
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, path, nil, 0)
if err != nil {
return false, err
}
_, yes = pkgs["main"]
return yes, nil
}
70 changes: 64 additions & 6 deletions tool/golang_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,31 @@ func TestHasMain(t *testing.T) {
})
}

func TestWalkMainDir(t *testing.T) {
func TestWalkMainPkgs(t *testing.T) {
Convey("遍历根目录及其子目录查找包含main函数的源代码文件路径", t, func() {
dir, err := os.Getwd()
So(err, ShouldBeNil)
So(strings.HasSuffix(dir, filepath.Join("src", "github.com", "voidint", "gbb", "tool")), ShouldBeTrue)
workspace := strings.TrimRight(dir, fmt.Sprintf("%ctool", os.PathSeparator))
paths, err := walkMainDir(workspace)
paths, err := walkMainPkgs(workspace)
So(err, ShouldBeNil)
So(paths, ShouldNotBeEmpty)
So(len(paths), ShouldEqual, 1)
So(paths[0], ShouldEqual, workspace)
})
}

func TestWalkPkgDir(t *testing.T) {
func TestWalkPkgs(t *testing.T) {
Convey("查找指定目录及其子目录下所有满足golang包的目录路径", t, func() {
wd, err := os.Getwd()
So(err, ShouldBeNil)
paths, err := walkPkgDir(wd)
paths, err := walkPkgs(wd)
So(err, ShouldBeNil)
So(paths, ShouldNotBeEmpty)
So(len(paths), ShouldEqual, 1)
So(paths[0], ShouldEqual, wd)

paths, err = walkPkgDir(strings.TrimRight(wd, "tool"))
paths, err = walkPkgs(strings.TrimRight(wd, "tool"))
So(err, ShouldBeNil)
So(paths, ShouldNotBeEmpty)
So(len(paths), ShouldEqual, 7)
Expand All @@ -75,7 +75,7 @@ func TestWalkPkgDir(t *testing.T) {
})
defer monkey.Unpatch(isGoPkg)

paths, err := walkPkgDir(wd)
paths, err := walkPkgs(wd)
So(err, ShouldNotBeNil)
So(err, ShouldEqual, ErrIsGoPkg)
So(paths, ShouldBeEmpty)
Expand Down Expand Up @@ -130,3 +130,61 @@ func TestIsGoPkg(t *testing.T) {
})
})
}

func TestIsMainPkg(t *testing.T) {
Convey("检查指定路径是否是main包", t, func() {
wd, err := os.Getwd()
So(err, ShouldBeNil)
So(wd, ShouldNotBeBlank)

Convey("合法路径", func() {
Convey("非main包且不包含子包", func() {
yes, err := isMainPkg(wd)
So(err, ShouldBeNil)
So(yes, ShouldBeFalse)
})
Convey("非main包且包含子包", func() {
path := filepath.Join(
strings.TrimRight(wd, "tool"),
"vendor", "github.com", "smartystreets", "assertions",
)
yes, err := isMainPkg(path)
So(err, ShouldBeNil)
So(yes, ShouldBeFalse)
})

Convey("main包", func() {
yes, err := isMainPkg(strings.TrimRight(wd, "tool"))
So(err, ShouldBeNil)
So(yes, ShouldBeTrue)
})
})

Convey("非法路径", func() {
Convey("路径为空", func() {
yes, err := isMainPkg("")
So(err, ShouldBeNil)
So(yes, ShouldBeFalse)
})
Convey("路径非目录", func() {
yes, err := isMainPkg(filepath.Join(wd, "golang_test.go"))
So(err, ShouldNotBeNil)
So(yes, ShouldBeFalse)
})
Convey("路径不存在", func() {
yes, err := isMainPkg(filepath.Join(wd, "not_exist_dir"))
So(err, ShouldNotBeNil)
So(yes, ShouldBeFalse)
})
Convey("路径下不包含go源文件(非包路径)", func() {
path := filepath.Join(
strings.TrimRight(wd, "tool"),
"vendor", "github.com",
)
yes, err := isMainPkg(path)
So(err, ShouldBeNil)
So(yes, ShouldBeFalse)
})
})
})
}

0 comments on commit d603586

Please sign in to comment.