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 |
||||
|
||||
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) |
||||
} |
||||
|
@ -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