diff --git a/README.md b/README.md index e7994a743..195ec775a 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ go build 打开浏览器访问:[http://localhost:8000/kratos-demo/start](http://localhost:8000/kratos-demo/start),你会看到输出了`Golang 大法好 !!!` +[快速开始](doc/wiki-cn/quickstart.md) + # Document [简体中文](doc/wiki-cn/summary.md) diff --git a/doc/img/kratosinit.gif b/doc/img/kratosinit.gif new file mode 100644 index 000000000..ab9b71774 Binary files /dev/null and b/doc/img/kratosinit.gif differ diff --git a/doc/wiki-cn/blademaster-mid.md b/doc/wiki-cn/blademaster-mid.md index 5356ffff0..28f36fd0c 100644 --- a/doc/wiki-cn/blademaster-mid.md +++ b/doc/wiki-cn/blademaster-mid.md @@ -102,3 +102,8 @@ func Example() { e.Start() } ``` + + +------------- + +[文档目录树](summary.md) diff --git a/doc/wiki-cn/blademaster-mod.md b/doc/wiki-cn/blademaster-mod.md index 1bb68d68d..1aac31c66 100644 --- a/doc/wiki-cn/blademaster-mod.md +++ b/doc/wiki-cn/blademaster-mod.md @@ -77,3 +77,8 @@ func (c *Context) Protobuf(data proto.Message, err error) 将 Router 模块中预先注册的中间件与其他 Handler 合并,放入 Context 的 handlers 字段,并将 index 置 0,然后通过 Next() 方法一个个执行下去。 部分中间件可能想要在过程中中断整个流程,此时可以使用 Abort() 方法提前结束处理。 有些中间件还想在所有 Handler 执行完后再执行部分逻辑,此时可以在自身 Handler 中显式调用 Next() 方法,并将这些逻辑放在调用了 Next() 方法之后。 + + +------------- + +[文档目录树](summary.md) diff --git a/doc/wiki-cn/blademaster-quickstart.md b/doc/wiki-cn/blademaster-quickstart.md index 633c236ce..0fec788b2 100644 --- a/doc/wiki-cn/blademaster-quickstart.md +++ b/doc/wiki-cn/blademaster-quickstart.md @@ -62,3 +62,8 @@ func howToStart(c *bm.Context) // handler方法默认传入bm的Context对象 # 扩展阅读 [bm模块说明](blademaster-mod.md) [bm中间件](blademaster-mid.md) [bm基于pb生成](blademaster-pb.md) + + +------------- + +[文档目录树](summary.md) diff --git a/doc/wiki-cn/blademaster.md b/doc/wiki-cn/blademaster.md index 1d2a54d57..94e97ff96 100644 --- a/doc/wiki-cn/blademaster.md +++ b/doc/wiki-cn/blademaster.md @@ -31,3 +31,8 @@ blademaster 由几个非常精简的内部模块组成。其中 Router 用于根 blademaster 处理请求的模式非常简单,大部分的逻辑都被封装在了各种 Handler 中。一般而言,业务逻辑作为最后一个 Handler。正常情况下,每个 Handler 按照顺序一个一个串形地执行下去。 但是 Handler 中可以也中断整个处理流程,直接输出 Response。这种模式常被用于校验登陆的中间件中;一旦发现请求不合法,直接响应拒绝。 请求处理的流程中也可以使用 Render 来辅助渲染 Response,比如对于不同的请求需要响应不同的数据格式(JSON、XML),此时可以使用不同的 Render 来简化逻辑。 + + +------------- + +[文档目录树](summary.md) diff --git a/doc/wiki-cn/quickstart.md b/doc/wiki-cn/quickstart.md index e69de29bb..0abcb7686 100644 --- a/doc/wiki-cn/quickstart.md +++ b/doc/wiki-cn/quickstart.md @@ -0,0 +1,60 @@ +# 快速开始 + +快速使用kratos项目,可以使用`kratos tool`,如下: + +```shell +go get -u github.com/bilibili/kratos/tool/kratos +kratos init +``` +根据提示可以快速创建项目,如[kratos-demo](https://github.com/bilibili/kratos-demo)就是通过工具创建生成。目录结构如下: + +``` +├── CHANGELOG.md # CHANGELOG +├── CONTRIBUTORS.md # CONTRIBUTORS +├── README.md # README +├── api # api目录为对外保留的proto文件,及生成的pb.go文件 +│   ├── api.proto +│   ├── api.pb.go # 通过go generate生成的pb.go文件 +│   └── generate.go +├── cmd # cmd目录为main所在 +│   └── main.go # main.go +├── configs # configs为配置文件目录 +│   ├── application.toml # 应用的自定义配置文件,可能是一些业务开关如:useABtest = true +│   ├── grpc.toml # grpc相关配置 +│   ├── http.toml # http相关配置 +│   ├── log.toml # log相关配置 +│   ├── memcache.toml # memcache相关配置 +│   ├── mysql.toml # mysql相关配置 +│   └── redis.toml # redis相关配置 +├── go.mod # go.mod +└── internal # internal为项目内部包,包括以下目录: + ├── dao # dao层,用于数据库、cache、MQ、依赖某业务grpc|http等资源访问 + │   └── dao.go + ├── model # model层,用于声明业务结构体 + │   └── model.go + ├── server # server层,用于初始化grpc和http server + │   └── http # http层,用于初始化http server和声明handler + │   └── http.go + │   └── grpc # grpc层,用于初始化grpc server和定义method + │   └── grpc.go + └── service # service层,用于业务逻辑处理,且为方便http和grpc共用方法,建议入参和出参保持grpc风格,且使用pb文件生成代码 + └── service.go +``` + +生成后可直接运行如下: + +```shell +cd kratos-demo/cmd +go build +./cmd -conf ../configs +``` + +打开浏览器访问:[http://localhost:8000/kratos-demo/start](http://localhost:8000/kratos-demo/start),你会看到输出了`Golang 大法好 !!!` + +# 动图说明 + +![kratos init](/doc/img/kratosinit.gif) + +------------- + +[文档目录树](summary.md) diff --git a/tool/kprotoc/install_kprotoc.sh b/tool/kprotoc/install_kprotoc.sh new file mode 100755 index 000000000..80282888e --- /dev/null +++ b/tool/kprotoc/install_kprotoc.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e +if [[ -z $GOPATH ]]; then + GOPATH=${HOME}/go +fi +BIN_PATH=$( cut -d ':' -f 1 <<< "$GOPATH" )/bin +if [[ ! -z $GOBIN ]]; then + BIN_PATH=$GOBIN +fi +if [[ ! -z $INSTALL_PATH ]]; then + BIN_PATH=$INSTALL_PATH +fi +if [[ -f $BIN_PATH/kprotoc ]]; then + echo "kprotoc alreay install, remove $BIN_PATH/kprotoc first to reinstall." + exit 1; +fi + +ln -s $GOPATH/src/github.com/bilibili/kratos/tool/kprotoc/kprotoc.sh $BIN_PATH/kprotoc +echo "install kprotoc to $BIN_PATH/kprotoc done!" diff --git a/tool/kprotoc/kprotoc.sh b/tool/kprotoc/kprotoc.sh new file mode 100755 index 000000000..fac1fd530 --- /dev/null +++ b/tool/kprotoc/kprotoc.sh @@ -0,0 +1,118 @@ +#!/bin/bash +DEFAULT_PROTOC_GEN="gogofast" +DEFAULT_PROTOC="protoc" +KRATOS_DIR_NAME="github.com/bilibili/kratos" +USR_INCLUDE_DIR="/usr/local/include" +GOPATH=$GOPATH +if [[ -z $GOPATH ]]; then + GOPATH=${HOME}/go +fi + +function _install_protoc() { + osname=$(uname -s) + echo "install protoc ..." + case $osname in + "Darwin" ) + brew install protobuf + ;; + *) + echo "unknown operating system, need install protobuf manual see: https://developers.google.com/protocol-buffers" + exit 1 + ;; + esac +} + +function _install_protoc_gen() { + local protoc_gen=$1 + case $protoc_gen in + "gofast" ) + echo "install gofast from github.com/gogo/protobuf/protoc-gen-gofast" + go get github.com/gogo/protobuf/protoc-gen-gofast + ;; + "gogofast" ) + echo "install gogofast from github.com/gogo/protobuf/protoc-gen-gogofast" + go get github.com/gogo/protobuf/protoc-gen-gogofast + ;; + "gogo" ) + echo "install gogo from github.com/gogo/protobuf/protoc-gen-gogo" + go get github.com/gogo/protobuf/protoc-gen-gogo + ;; + "go" ) + echo "install protoc-gen-go from github.com/golang/protobuf" + go get github.com/golang/protobuf/{proto,protoc-gen-go} + ;; + *) + echo "can't install protoc-gen-${protoc_gen} automatic !" + exit 1; + ;; + esac +} + +function _find_kratos_dir() { + local kratos_dir_name=$1 + local current_dir="$GOPATH/src/$kratos_dir_name" + if [[ ! -d $current_dir ]]; then + go get -u $kratos_dir_name + fi + echo $current_dir +} + +function _esc_string() { + echo $(echo "$1" | sed 's_/_\\/_g') +} + +function _run_protoc() { + local proto_dir=$1 + local proto_files=$(find $proto_dir -maxdepth 1 -name "*.proto") + if [[ -z $proto_files ]]; then + return + fi + local protoc_cmd="$PROTOC -I$PROTO_PATH --${PROTOC_GEN}_out=plugins=grpc:${GOPATH}/src ${proto_files}" + echo $protoc_cmd + $protoc_cmd +} + +if [[ -z $PROTOC ]]; then + PROTOC=${DEFAULT_PROTOC} + which $PROTOC + if [[ "$?" -ne "0" ]]; then + _install_protoc + fi +fi +if [[ -z $PROTOC_GEN ]]; then + PROTOC_GEN=${DEFAULT_PROTOC_GEN} + which protoc-gen-$PROTOC_GEN + if [[ "$?" -ne "0" ]]; then + _install_protoc_gen $PROTOC_GEN + fi +fi + +KRATOS_DIR=$(_find_kratos_dir $KRATOS_DIR_NAME) +if [[ "$?" != "0" ]]; then + echo "can't find kratos directoy" + exit 1 +fi + +KRATOS_PARENT=$(dirname $KRATOS_DIR) + +if [[ -z $PROTO_PATH ]]; then + PROTO_PATH=$GOPATH/src:$KRATOS_PARENT:$USR_INCLUDE_DIR +else + PROTO_PATH=$GOPATH/src:$PROTO_PATH:$KRATOS_PARENT:$USR_INCLUDE_DIR +fi + +if [[ ! -z $1 ]]; then + cd $1 +fi +TARGET_DIR=$(pwd) + +# switch to $GOPATH/src +cd $GOPATH/src +echo "switch workdir to $GOPATH/src" + +DIRS=$(find $TARGET_DIR -type d) + +for dir in $DIRS; do + echo "run protoc in $dir" + _run_protoc $dir +done diff --git a/tool/kratos/template.go b/tool/kratos/template.go index 95ef99c14..d03942e3c 100644 --- a/tool/kratos/template.go +++ b/tool/kratos/template.go @@ -409,7 +409,7 @@ message HelloReq { _tplAPIGenerate = `package api // 生成 gRPC 代码 -//go:generate TODO:待完善工具protoc.sh +//go:generate kratos tool kprotoc ` _tplModel = `package model diff --git a/tool/kratos/tool.go b/tool/kratos/tool.go index 5f4681a16..8eed53b33 100644 --- a/tool/kratos/tool.go +++ b/tool/kratos/tool.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "path" "path/filepath" "runtime" "sort" @@ -114,7 +115,7 @@ func runTool(name, dir, cmd string, args []string) (err error) { } if err = toolCmd.Run(); err != nil { if e, ok := err.(*exec.ExitError); !ok || !e.Exited() { - fmt.Fprintf(os.Stderr, "install %s: %v\n", name, err) + fmt.Fprintf(os.Stderr, "运行 %s 出错: %v\n", name, err) } } return @@ -147,7 +148,7 @@ func (t Tool) install() { } cmds := strings.Split(t.Install, " ") if len(cmds) > 0 { - if err := runTool(t.Name, t.toolPath(), cmds[0], cmds[1:]); err == nil { + if err := runTool(t.Name, path.Dir(t.toolPath()), cmds[0], cmds[1:]); err == nil { color.Green("%s: 安装成功!", t.Name) } } diff --git a/tool/kratos/tool_index.go b/tool/kratos/tool_index.go index 7de142492..a19b9140e 100644 --- a/tool/kratos/tool_index.go +++ b/tool/kratos/tool_index.go @@ -12,4 +12,13 @@ var toolIndexs = []*Tool{ 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封装", + Platform: []string{"darwin", "linux"}, + Author: "kratos", + URL: "wiki", + }, }