parent
d8b83c5809
commit
436db51d86
Before Width: | Height: | Size: 2.1 MiB |
@ -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) |
@ -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`的工具生成代码。 |
@ -1,18 +1,47 @@ |
|||||||
package main |
package main |
||||||
|
|
||||||
import ( |
import ( |
||||||
|
"fmt" |
||||||
|
"io/ioutil" |
||||||
"os" |
"os" |
||||||
"os/exec" |
"os/exec" |
||||||
|
"path" |
||||||
|
"path/filepath" |
||||||
|
|
||||||
"github.com/urfave/cli" |
"github.com/urfave/cli" |
||||||
) |
) |
||||||
|
|
||||||
func buildAction(c *cli.Context) error { |
func buildAction(c *cli.Context) error { |
||||||
|
base, err := os.Getwd() |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
args := append([]string{"build"}, c.Args()...) |
args := append([]string{"build"}, c.Args()...) |
||||||
cmd := exec.Command("go", args...) |
cmd := exec.Command("go", args...) |
||||||
|
cmd.Dir = buildDir(base, "cmd", 5) |
||||||
cmd.Stdout = os.Stdout |
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 { |
if err := cmd.Run(); err != nil { |
||||||
panic(err) |
panic(err) |
||||||
} |
} |
||||||
|
fmt.Println("build success.") |
||||||
return nil |
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) |
||||||
|
} |
||||||
|
@ -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 |
|
@ -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 |
|
||||||
} |
|
@ -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 |
||||||
|
} |
@ -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 |
||||||
|
} |
Loading…
Reference in new issue