diff --git a/README.md b/README.md index c0e661d5d..8d4cc68a6 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Kratos是[bilibili](https://www.bilibili.com)开源的一套Go微服务框架, * [log](doc/wiki-cn/logger.md):基于[zap](https://github.com/uber-go/zap)的field方式实现的高性能log库,集成了我们提供的[log-agent敬请期待]()日志收集方案。 * [database](doc/wiki-cn/database.md):集成MySQL&HBase&TiDB的SDK,其中TiDB使用服务发现方案。 * [cache](doc/wiki-cn/cache.md):集成memcache&redis的SDK,注意无redis-cluster实现,推荐使用代理模式[overlord](https://github.com/bilibili/overlord)。 -* [kratos tool](doc/wiki-cn/kratos-tool.md):kratos相关工具量,包括项目快速生成、pb文件代码生成、swagger文档生成等。 +* [kratos工具](doc/wiki-cn/kratos-tool.md):kratos相关工具量,包括项目快速生成、pb文件代码生成、swagger文档生成等。 我们致力于提供完整的微服务研发体验,整合相关框架及工具后,微服务治理相关部分可对整体业务开发周期无感,从而更加聚焦于业务交付。对每位开发者而言,整套Kratos框架也是不错的学习仓库,可以了解和参考到[bilibili](https://www.bilibili.com)在微服务方面的技术积累和经验。 @@ -26,10 +26,11 @@ Kratos是[bilibili](https://www.bilibili.com)开源的一套Go微服务框架, ```shell go get -u github.com/bilibili/kratos/tool/kratos -kratos init +cd $GOPATH/src +kratos new kratos-demo ``` -`kratos init`会快速生成基于kratos库的脚手架代码,如生成[kratos-demo](https://github.com/bilibili/kratos-demo) +`kratos new kratos-demo`会快速生成基于kratos库的脚手架代码,如生成[kratos-demo](https://github.com/bilibili/kratos-demo) ```shell cd kratos-demo/cmd @@ -39,9 +40,10 @@ go build 打开浏览器访问:[http://localhost:8000/kratos-demo/start](http://localhost:8000/kratos-demo/start),你会看到输出了`Golang 大法好 !!!` -[快速开始](doc/wiki-cn/quickstart.md) +[快速开始](doc/wiki-cn/quickstart.md) +[kratos工具](doc/wiki-cn/kratos-tool.md) -# Document +# 文档目录 [简体中文](doc/wiki-cn/summary.md) diff --git a/doc/img/kratosinit.gif b/doc/img/kratosinit.gif deleted file mode 100644 index ab9b71774..000000000 Binary files a/doc/img/kratosinit.gif and /dev/null differ diff --git a/doc/wiki-cn/blademaster-quickstart.md b/doc/wiki-cn/blademaster-quickstart.md index eca87f42d..e3f12a8a5 100644 --- a/doc/wiki-cn/blademaster-quickstart.md +++ b/doc/wiki-cn/blademaster-quickstart.md @@ -1,6 +1,6 @@ # 准备工作 -推荐使用[kratos tool](kratos-tool.md)快速生成项目,如我们生成一个叫`kratos-demo`的项目。 +推荐使用[kratos工具](kratos-tool.md)快速生成项目,如我们生成一个叫`kratos-demo`的项目。 生成目录结构如下: ``` diff --git a/doc/wiki-cn/kratos-tool.md b/doc/wiki-cn/kratos-tool.md index e69de29bb..cb3562801 100644 --- a/doc/wiki-cn/kratos-tool.md +++ b/doc/wiki-cn/kratos-tool.md @@ -0,0 +1,112 @@ +# 介绍 + +kratos包含了一批好用的工具集,比如项目一键生成、基于proto生成http&grpc代码,生成缓存回源代码,生成memcache执行代码,生成swagger文档等。 + +# 获取工具 + +执行以下命令,即可快速安装好`kratos`工具 +```shell +go get -u github.com/bilibili/kratos/tool/kratos +``` + +那么接下来让我们快速开始熟悉工具的用法~ + +# kratos本体 + +`kratos`是所有工具集的本体,就像`go`一样,拥有执行各种子工具的能力,如`go build`和`go tool`。先让我们看看`-h`的输出: + +``` +NAME: + kratos - kratos tool + +USAGE: + kratos [global options] command [command options] [arguments...] + +VERSION: + 0.0.1 + +COMMANDS: + new, n create new project + build, b kratos build + run, r kratos run + tool, t kratos tool + version, v kratos version + self-upgrade kratos self-upgrade + help, h Shows a list of commands or help for one command + +GLOBAL OPTIONS: + --help, -h show help + --version, -v print the version +``` + +可以看到`kratos`有如:`new` `build` `run` `tool`等在内的COMMANDS,那么接下来一一演示如何使用。 + +# kratos new + +`kratos new`是快速创建一个项目的命令,执行如下: + +```shell +kratos new kratos-demo +``` + +即可快速在当前目录生成一个叫`kratos-demo`的项目。此外还支持指定owner和path,如下: + +```shell +kratos new kratos-demo -o YourName -d YourPath +``` + +注意,`kratos new`默认是不会生成`grpc`示例代码的,如需生成请加`--grpc`,如下: + +```shell +kratos new kratos-demo -o YourName -d YourPath --grpc +``` + +特别注意,如果不是macos系统,生成的示例项目`api`目录下的`proto`文件并不会自动生成对应的`.pb.go`文件,需要参考以下说明进行生成。 + +[protoc说明](protoc.md) + +# kratos build&run + +`kratos build`和`kratos run`是`go build`和`go run`的封装,并无特别用途。 + +# kratos tool + +`kratos tool`是基于proto生成http&grpc代码,生成缓存回源代码,生成memcache执行代码,生成swagger文档等工具集,先看下`kratos tool`的执行效果: + +``` +kratos(已安装): Kratos工具集本体 Author(kratos) [2019/04/02] +kprotoc(已安装): 快速方便生成pb.go的protoc封装,不支持Windows,Linux请先安装protoc工具 Author(kratos) [2019/04/02] + +安装工具: kratos tool install demo +执行工具: kratos tool demo +安装全部工具: kratos tool install all + +详细文档: https://github.com/bilibili/kratos/blob/master/doc/wiki-cn/kratos-tool.md +``` + +***小小说明:如未安装工具,第一次运行也可自动安装,不需要特别执行install*** + +目前已经集成的工具有: +* `kprotoc`用于快速生成`pb.go`文件,但目前不支持windows,Linux也需要先自己安装`protoc`工具。 +* TODOs... + +### kratos tool kprotoc + +该命令运行没其他参数,直接`kratos tool kprotoc`运行即可。但使用前需特别说明: + +* 该工具不支持Windows用户,请安装`protoc`和`gogo protobuf`工具 +* 该工具在Linux下运行,需提前安装好`protoc`工具 + +该工具实际是一段`shell`脚本,其中自动将`protoc`命令进行了拼接,识别了需要`include`的目录和当前目录下的`proto`文件,最终会拼接为如下命令进行执行: + +```shell +protoc -I/Users/felix/work/go/src:/usr/local/include --gogofast_out=plugins=grpc:/Users/felix/work/go/src /Users/felix/work/go/src/kratos-demo/api/api.proto +``` + +Windows和Linux用户可以参考该命令进行`proto`生成`pb.go`文件,也可以参考[protoc说明](protoc.md)。 + +### TODOs + +------------- + +[文档目录树](summary.md) diff --git a/doc/wiki-cn/protoc.md b/doc/wiki-cn/protoc.md new file mode 100644 index 000000000..9aa7d7d75 --- /dev/null +++ b/doc/wiki-cn/protoc.md @@ -0,0 +1,15 @@ +# protoc + +`protobuf`是Google官方出品的一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。 + +使用`protobuf`,需要先书写`.proto`文件,然后编译该文件。编译`proto`文件则需要使用到官方的`protoc`工具,安装文档请参看:[google官方protoc工具](https://github.com/protocolbuffers/protobuf#protocol-compiler-installation)。 + +注意:`protoc`是用于编辑`proto`文件的工具,它并不具备生成对应语言代码的能力,所以正常都是`protoc`配合对应语言的代码生成工具来使用,如Go语言的[gogo protobuf](https://github.com/gogo/protobuf),请先点击按文档说明安装。 + +安装好对应工具后,我们可以进入`api`目录,执行如下命令: + +```shell +protoc -I/Users/felix/work/go/src:/usr/local/include --gogofast_out=plugins=grpc:/Users/felix/work/go/src /Users/felix/work/go/src/kratos-demo/api/api.proto +``` + +请注意替换`/Users/felix/work/go/src`目录为你本地开发环境对应GOPATH目录,其中`--gogofast_out`意味着告诉`protoc`工具需要使用`gogo protobuf`的工具生成代码。 diff --git a/doc/wiki-cn/quickstart.md b/doc/wiki-cn/quickstart.md index 0abcb7686..5a627019c 100644 --- a/doc/wiki-cn/quickstart.md +++ b/doc/wiki-cn/quickstart.md @@ -1,18 +1,20 @@ # 快速开始 -快速使用kratos项目,可以使用`kratos tool`,如下: +快速使用kratos项目,可以使用`kratos`工具,如下: ```shell go get -u github.com/bilibili/kratos/tool/kratos -kratos init +cd $GOPATH/src +kratos new kratos-demo ``` + 根据提示可以快速创建项目,如[kratos-demo](https://github.com/bilibili/kratos-demo)就是通过工具创建生成。目录结构如下: ``` ├── CHANGELOG.md # CHANGELOG ├── CONTRIBUTORS.md # CONTRIBUTORS ├── README.md # README -├── api # api目录为对外保留的proto文件,及生成的pb.go文件 +├── api # api目录为对外保留的proto文件及生成的pb.go文件,注:需要"--grpc"参数 │   ├── api.proto │   ├── api.pb.go # 通过go generate生成的pb.go文件 │   └── generate.go @@ -51,9 +53,7 @@ go build 打开浏览器访问:[http://localhost:8000/kratos-demo/start](http://localhost:8000/kratos-demo/start),你会看到输出了`Golang 大法好 !!!` -# 动图说明 - -![kratos init](/doc/img/kratosinit.gif) +[kratos工具](kratos-tool.md) ------------- diff --git a/doc/wiki-cn/summary.md b/doc/wiki-cn/summary.md index 67abf002f..ee1ba5bb9 100644 --- a/doc/wiki-cn/summary.md +++ b/doc/wiki-cn/summary.md @@ -24,4 +24,4 @@ * [cache](cache.md) * [memcache](cache-mc.md) * [redis](cache-redis.md) -* [kratos tool](kratos-tool.md) +* [kratos工具](kratos-tool.md) diff --git a/doc/wiki-cn/warden-quickstart.md b/doc/wiki-cn/warden-quickstart.md index 359a2f87c..2711dedd3 100644 --- a/doc/wiki-cn/warden-quickstart.md +++ b/doc/wiki-cn/warden-quickstart.md @@ -1,23 +1,29 @@ # 准备工作 -推荐使用[kratos tool](kratos-tool.md)快速生成项目,如我们生成一个叫`kratos-demo`的项目。 - -[快速开始](quickstart.md) +推荐使用[kratos工具](kratos-tool.md)快速生成带`--grpc`的项目,如我们生成一个叫`kratos-demo`的项目。 # pb文件 创建项目成功后,进入`api`目录下可以看到`api.proto`和`api.pb.go`和`generate.go`文件,其中: + * `api.proto`是gRPC server的描述文件 * `api.pb.go`是基于`api.proto`生成的代码文件 -* `generate.go`是用于`kratos tool`执行`go generate`进行代码生成的临时文件 +* `generate.go`是用于`kratos tool kprotoc`执行`go generate`进行代码生成的临时文件 接下来可以将以上三个文件全部删除或者保留`generate.go`,之后编写自己的proto文件,确认proto无误后,进行代码生成: + * 可直接执行`kratos tool kprotoc`,该命令会调用protoc工具生成`.pb.go`文件 * 如`generate.go`没删除,也可以执行`go generate`命令,将调用`kratos tool kprotoc`工具进行代码生成 +[kprotoc说明请看](kratos-tool.md) + +### 如没看kprotoc文档,请看下面这段话 + +`kratos tool kprotoc`用于快速生成`pb.go`文件,但目前不支持windows,Linux也需要先自己安装`protoc`工具,具体请看[protoc说明](protoc.md)。 + # 注册server -进入`internal/server/grpc`目录,打开`server.go`文件,可以看到以下代码,只需要替换以下注释内容就可以启动一个gRPC服务。 +进入`internal/server/grpc`目录打开`server.go`文件,可以看到以下代码,只需要替换以下注释内容就可以启动一个gRPC服务。 ```go package grpc @@ -68,7 +74,7 @@ func (s *Service) SayHello(ctx context.Context, req *pb.HelloReq) (reply *empty. * 第一个返回值必须是proto内定义的`message`对应生成的结构体,第二个参数必须是`error` * 在http框架bm中,如果共用proto文件生成bm代码,那么也可以直接使用该service方法 -建议service严格按照此格式声明方法,使其能够在bm和warden内共用 +建议service严格按照此格式声明方法使其能够在bm和warden内共用。 # client调用 diff --git a/tool/kratos/build.go b/tool/kratos/build.go index 0265db814..8ab59d3a0 100644 --- a/tool/kratos/build.go +++ b/tool/kratos/build.go @@ -1,18 +1,47 @@ package main import ( + "fmt" + "io/ioutil" "os" "os/exec" + "path" + "path/filepath" "github.com/urfave/cli" ) func buildAction(c *cli.Context) error { + base, err := os.Getwd() + if err != nil { + panic(err) + } args := append([]string{"build"}, c.Args()...) cmd := exec.Command("go", args...) + cmd.Dir = buildDir(base, "cmd", 5) cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + fmt.Printf("directory: %s\n", cmd.Dir) + fmt.Printf("kratos: %s\n", Version) if err := cmd.Run(); err != nil { panic(err) } + fmt.Println("build success.") return nil } + +func buildDir(base string, cmd string, n int) string { + dirs, err := ioutil.ReadDir(base) + if err != nil { + panic(err) + } + for _, d := range dirs { + if d.IsDir() && d.Name() == cmd { + return path.Join(base, cmd) + } + } + if n <= 1 { + return base + } + return buildDir(filepath.Dir(base), cmd, n-1) +} diff --git a/tool/kratos/doc.go b/tool/kratos/doc.go deleted file mode 100644 index ad9d84020..000000000 --- a/tool/kratos/doc.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -kratos 是Kratos的工具链,提供新项目创建,代码生成等功能 - -kartos build 本目录之下局部编译,根目录全量编译 -NAME: - kratos build - -USAGE: - kratos build [arguments...] - -EXAMPLE: - cd app && kratos build ./service/.. admin interface/.. tool/cache/... - kratos build - -kartos init 新建新项目 -USAGE: - kratos init [command options] [arguments...] - -OPTIONS: - -n value 项目名 - -o value 维护人 - --grpc 是否是GRPC - -EXAMPLE: - kratos init -n demo -o kratos -*/ -package main diff --git a/tool/kratos/init.go b/tool/kratos/init.go deleted file mode 100644 index 84a5d6c82..000000000 --- a/tool/kratos/init.go +++ /dev/null @@ -1,155 +0,0 @@ -package main - -import ( - "fmt" - "go/build" - "os" - "path/filepath" - "strings" - - "github.com/urfave/cli" - "gopkg.in/AlecAivazis/survey.v1" -) - -const ( - _textModeFastInit = "一键初始化项目" - _textModeInteraction = "自定义项目参数" - _textYes = "是" - _textNo = "否" -) - -func runInit(ctx *cli.Context) (err error) { - if ctx.NumFlags() == 0 { - if err = interact(); err != nil { - return - } - } - if !validate() { - return nil - } - if err = create(); err != nil { - fmt.Println("项目初始化失败: ", err.Error()) - return nil - } - fmt.Printf("项目[%s]初始化成功!\n", p.Path) - return nil -} - -func initPwd() (ok bool) { - pwd, err := os.Getwd() - if err != nil { - return - } - ps := strings.Split(pwd, string(os.PathSeparator)) - plen := len(ps) - if plen < 1 { - // 至少要有一个目录层级:项目名 - return - } - name := ps[plen-1] - if name == "" { - return - } - p.Name = name - p.Path = pwd - return true -} - -func goPath() (gp string) { - gopaths := strings.Split(os.Getenv("GOPATH"), ":") - if len(gopaths) == 1 { - return gopaths[0] - } - pwd, err := os.Getwd() - if err != nil { - return - } - abspwd, err := filepath.Abs(pwd) - if err != nil { - return - } - for _, gopath := range gopaths { - absgp, err := filepath.Abs(gopath) - if err != nil { - return - } - if strings.HasPrefix(abspwd, absgp) { - return absgp - } - } - return build.Default.GOPATH -} - -func interact() (err error) { - qs1 := &survey.Select{ - Message: "你想怎么玩?", - Options: []string{_textModeFastInit, _textModeInteraction}, - } - var ans1 string - if err = survey.AskOne(qs1, &ans1, nil); err != nil { - return - } - switch ans1 { - case _textModeFastInit: - if ok := initPwd(); !ok { - fmt.Println("快速初始化失败!") - } - return - case _textModeInteraction: - // go on - default: - return - } - qs := []*survey.Question{ - { - Name: "name", - Prompt: &survey.Input{ - Message: "请输入项目名称:", - }, - Validate: survey.Required, - }, - { - Name: "owner", - Prompt: &survey.Input{ - Message: "请输入项目负责人:", - }, - }, - { - Name: "useGRPC", - Prompt: &survey.Select{ - Message: "是否使用 gRPC ?", - Options: []string{_textYes, _textNo}, - Default: _textNo, - }, - }, - { - Name: "here", - Prompt: &survey.Select{ - Message: "是否当前目录?默认为GOPATH下", - Options: []string{_textYes, _textNo}, - Default: _textYes, - }, - }, - } - ans := struct { - Name string - Owner string - UseGRPC string - Here string - }{} - if err = survey.Ask(qs, &ans); err != nil { - return - } - p.Name = ans.Name - p.Owner = ans.Owner - if ans.UseGRPC == _textYes { - p.WithGRPC = true - } - if ans.UseGRPC == _textYes { - p.WithGRPC = true - } - if ans.Here == _textYes { - p.Here = true - } - return -} diff --git a/tool/kratos/main.go b/tool/kratos/main.go index 256af1a26..0ebe3453d 100644 --- a/tool/kratos/main.go +++ b/tool/kratos/main.go @@ -10,40 +10,47 @@ import ( func main() { app := cli.NewApp() app.Name = "kratos" - app.Usage = "kratos tool" + app.Usage = "kratos工具集" app.Version = Version app.Commands = []cli.Command{ { - Name: "build", - Aliases: []string{"b"}, - Usage: "kratos build", - Action: buildAction, - }, - { - Name: "init", - Aliases: []string{"i"}, + Name: "new", + Aliases: []string{"n"}, Usage: "create new project", Flags: []cli.Flag{ - cli.StringFlag{ - Name: "n", - Value: "", - Usage: "project name for create project", - Destination: &p.Name, - }, cli.StringFlag{ Name: "o", Value: "", Usage: "project owner for create project", Destination: &p.Owner, }, + cli.StringFlag{ + Name: "d", + Value: "", + Usage: "project directory for create project", + Destination: &p.Path, + }, cli.BoolFlag{ Name: "grpc", Usage: "whether to use grpc for create project", Destination: &p.WithGRPC, }, }, - Action: runInit, + Action: runNew, + }, + { + Name: "build", + Aliases: []string{"b"}, + Usage: "kratos build", + Action: buildAction, }, + { + Name: "run", + Aliases: []string{"r"}, + Usage: "kratos run", + Action: runAction, + }, + { Name: "tool", Aliases: []string{"t"}, diff --git a/tool/kratos/new.go b/tool/kratos/new.go new file mode 100644 index 000000000..49d5fb47b --- /dev/null +++ b/tool/kratos/new.go @@ -0,0 +1,33 @@ +package main + +import ( + "errors" + "fmt" + "os" + "path" + + "github.com/urfave/cli" +) + +func runNew(ctx *cli.Context) error { + if len(ctx.Args()) == 0 { + return errors.New("required project name") + } + p.Name = ctx.Args()[0] + if p.Path != "" { + p.Path = path.Join(p.Path, p.Name) + } else { + pwd, _ := os.Getwd() + p.Path = path.Join(pwd, p.Name) + } + // creata a project + if err := create(); err != nil { + return err + } + fmt.Printf("Project: %s\n", p.Name) + fmt.Printf("Owner: %s\n", p.Owner) + fmt.Printf("WithGRPC: %t\n", p.WithGRPC) + fmt.Printf("Directory: %s\n\n", p.Path) + fmt.Println("The application has been created.") + return nil +} diff --git a/tool/kratos/project.go b/tool/kratos/project.go index cffbdd18e..0de61dc40 100644 --- a/tool/kratos/project.go +++ b/tool/kratos/project.go @@ -6,7 +6,7 @@ import ( "io/ioutil" "os" "os/exec" - "path" + "runtime" "strings" "text/template" ) @@ -84,22 +84,6 @@ var ( } ) -func validate() (ok bool) { - if p.Name == "" { - fmt.Println("[-n] Invalid project name.") - return - } - if p.Path == "" { - if p.Here { - pwd, _ := os.Getwd() - p.Path = path.Join(pwd, p.Name) - } else { - p.Path = path.Join(goPath(), "src", p.Name) - } - } - return true -} - func create() (err error) { if p.WithGRPC { files[_tplTypeGRPCServer] = "/internal/server/grpc/server.go" @@ -131,6 +115,10 @@ func create() (err error) { if err = genpb(); err != nil { return } + if runtime.GOOS != "darwin" { + fmt.Println("您的操作系统不是macos,kprotoc工具无法正常运行,请参看kratos tool文档!") + fmt.Println("地址:", toolDoc) + } } return } diff --git a/tool/kratos/run.go b/tool/kratos/run.go new file mode 100644 index 000000000..99e551cb5 --- /dev/null +++ b/tool/kratos/run.go @@ -0,0 +1,28 @@ +package main + +import ( + "os" + "os/exec" + "path" + "path/filepath" + + "github.com/urfave/cli" +) + +func runAction(c *cli.Context) error { + base, err := os.Getwd() + if err != nil { + panic(err) + } + dir := buildDir(base, "cmd", 5) + conf := path.Join(filepath.Dir(dir), "configs") + args := append([]string{"run", "main.go", "-conf", conf}, c.Args()...) + cmd := exec.Command("go", args...) + cmd.Dir = dir + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + panic(err) + } + return nil +} diff --git a/tool/kratos/template.go b/tool/kratos/template.go index c293a8301..679bbd64a 100644 --- a/tool/kratos/template.go +++ b/tool/kratos/template.go @@ -433,7 +433,7 @@ replace ( cloud.google.com/go => github.com/googleapis/google-cloud-go v0.26.0 golang.org/x/crypto => github.com/golang/crypto v0.0.0-20190123085648-057139ce5d2b golang.org/x/lint => github.com/golang/lint v0.0.0-20181026193005-c67002cb31c3 - golang.org/x/net => github.com/golang/net v0.0.0-20190311183353-d8887717615a + golang.org/x/net => github.com/golang/net v0.0.0-20190420063019-afa5a82059c6 golang.org/x/oauth2 => github.com/golang/oauth2 v0.0.0-20180821212333-d2e6202438be golang.org/x/sync => github.com/golang/sync v0.0.0-20181108010431-42b317875d0f golang.org/x/sys => github.com/golang/sys v0.0.0-20180905080454-ebe1bf3edb33 diff --git a/tool/kratos/tool.go b/tool/kratos/tool.go index 8eed53b33..6f84e25f9 100644 --- a/tool/kratos/tool.go +++ b/tool/kratos/tool.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "go/build" "os" "os/exec" "path" @@ -15,16 +16,21 @@ import ( "github.com/urfave/cli" ) +const ( + toolDoc = "https://github.com/bilibili/kratos/blob/master/doc/wiki-cn/kratos-tool.md" +) + func toolAction(c *cli.Context) (err error) { if c.NArg() == 0 { sort.Slice(toolIndexs, func(i, j int) bool { return toolIndexs[i].BuildTime.After(toolIndexs[j].BuildTime) }) for _, t := range toolIndexs { updateTime := t.BuildTime.Format("2006/01/02") - fmt.Printf("%s%s: %s %s (%s) [%s]\n", color.HiMagentaString(t.Name), getNotice(t), color.HiCyanString(t.Summary), t.URL, t.Author, updateTime) + fmt.Printf("%s%s: %s Author(%s) [%s]\n", color.HiMagentaString(t.Name), getNotice(t), color.HiCyanString(t.Summary), t.Author, updateTime) } - fmt.Println("\n执行 install 安装程序 如: kratos tool install demo") - fmt.Println("执行 工具名称 运行程序 如: kratos tool demo") - fmt.Println("\n安装全部工具: kratos tool install all") + fmt.Println("\n安装工具: kratos tool install demo") + fmt.Println("执行工具: kratos tool demo") + fmt.Println("安装全部工具: kratos tool install all") + fmt.Println("\n详细文档:", toolDoc) return } if c.Args().First() == "install" { @@ -129,7 +135,6 @@ type Tool struct { Summary string `json:"summary"` Platform []string `json:"platform"` Author string `json:"author"` - URL string `json:"url"` } func (t Tool) supportOS() bool { @@ -143,7 +148,7 @@ func (t Tool) supportOS() bool { func (t Tool) install() { if t.Install == "" { - fmt.Fprintf(os.Stderr, color.RedString("%s: 自动安装失败 详情请查看文档 %s\n", t.Name, t.URL)) + fmt.Fprintf(os.Stderr, color.RedString("%s: 自动安装失败详情请查看文档:%s\n", t.Name, toolDoc)) return } cmds := strings.Split(t.Install, " ") @@ -174,3 +179,28 @@ func (t Tool) installed() bool { _, err := os.Stat(t.toolPath()) return err == nil } + +func goPath() (gp string) { + gopaths := strings.Split(os.Getenv("GOPATH"), ":") + if len(gopaths) == 1 { + return gopaths[0] + } + pwd, err := os.Getwd() + if err != nil { + return + } + abspwd, err := filepath.Abs(pwd) + if err != nil { + return + } + for _, gopath := range gopaths { + absgp, err := filepath.Abs(gopath) + if err != nil { + return + } + if strings.HasPrefix(abspwd, absgp) { + return absgp + } + } + return build.Default.GOPATH +} diff --git a/tool/kratos/tool_index.go b/tool/kratos/tool_index.go index a19b9140e..b88e5f5b5 100644 --- a/tool/kratos/tool_index.go +++ b/tool/kratos/tool_index.go @@ -10,15 +10,13 @@ var toolIndexs = []*Tool{ Summary: "Kratos工具集本体", Platform: []string{"darwin", "linux", "windows"}, Author: "kratos", - URL: "wiki", }, &Tool{ Name: "kprotoc", BuildTime: time.Date(2019, 4, 2, 0, 0, 0, 0, time.Local), Install: "bash -c ${GOPATH}/src/github.com/bilibili/kratos/tool/kprotoc/install_kprotoc.sh", - Summary: "快速方便生成pb.go的protoc封装", + Summary: "快速方便生成pb.go的protoc封装,不支持windows,Linux请先安装protoc工具", Platform: []string{"darwin", "linux"}, - Author: "kratos", - URL: "wiki", + Author: "https://github.com/tomwei7", }, }