mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
gf cli updates
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,3 +15,5 @@ cbuild
|
||||
**/.DS_Store
|
||||
.vscode/
|
||||
.example/other/
|
||||
main
|
||||
gf
|
||||
5
go.mod
5
go.mod
@ -5,20 +5,17 @@ go 1.14
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/gogf/gf/tool/gf v0.0.0-20210629161552-1e628b9edb8e // indirect
|
||||
github.com/gogf/mysql v1.6.1-0.20210603073548-16164ae25579
|
||||
github.com/gomodule/redigo v2.0.0+incompatible
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/grokify/html-strip-tags-go v0.0.0-20200322061010-ea0c1cf2f119
|
||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
go.opentelemetry.io/otel v1.0.0-RC1
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102
|
||||
golang.org/x/text v0.3.4
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
)
|
||||
|
||||
33
go.sum
33
go.sum
@ -6,26 +6,49 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/gogf/gf v1.13.8-0.20201010060010-09ce105eeeab/go.mod h1:nGAMjE4ohU2bwj4Gk3h25K6rEkPZMDdvsmyifpFcuMQ=
|
||||
github.com/gogf/gf v1.16.1/go.mod h1:5eEgE9fWeRQW8dJE3GLpCy0KkNitXh6POesdJiBE/lw=
|
||||
github.com/gogf/gf/tool/gf v0.0.0-20210629161552-1e628b9edb8e h1:0yamWn3TAI/nFVDI9pwofWDekdMt4qQLwQdMmE59TNA=
|
||||
github.com/gogf/gf/tool/gf v0.0.0-20210629161552-1e628b9edb8e/go.mod h1:bCukUi4KQbIKZ4W5xLPKHe3eYparuvqfqBn8ZiYeCnY=
|
||||
github.com/gogf/mysql v1.6.1-0.20210603073548-16164ae25579 h1:pP/uEy52biKDytlgK/ug8kiYPAiYu6KajKVUHfGrtyw=
|
||||
github.com/gogf/mysql v1.6.1-0.20210603073548-16164ae25579/go.mod h1:52e6mXyNnHAsFrXrSnj5JPRSKsZKpHylVtA3j4AtMz8=
|
||||
github.com/gogf/swagger v1.0.4 h1:MILniFKPh52/26s+z8taSh8thn1tq2RaeWM7rYX1dRw=
|
||||
github.com/gogf/swagger v1.0.4/go.mod h1:4rD12TCoDz60jmgtuFnx7ZBWUM92tXc/qtrIrkBIp5Q=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gqcn/structs v1.1.1/go.mod h1:/aBhTBSsKQ2Ec9pbnYdGphtdWXHFn4KrCL0fXM/Adok=
|
||||
github.com/grokify/html-strip-tags-go v0.0.0-20190921062105-daaa06bf1aaf/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
|
||||
github.com/grokify/html-strip-tags-go v0.0.0-20200322061010-ea0c1cf2f119 h1:h3iGUlU8HyW4baKd6D+h1mwOHnM2kwskSuG6Bv4tSbc=
|
||||
github.com/grokify/html-strip-tags-go v0.0.0-20200322061010-ea0c1cf2f119/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -33,26 +56,36 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
|
||||
go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc=
|
||||
go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I=
|
||||
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
|
||||
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk=
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4=
|
||||
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58=
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
||||
@ -1,17 +1,22 @@
|
||||
# GF-CLI
|
||||
English | [简体中文](README_ZH.MD)
|
||||
# GoFrame CLI Tool
|
||||
|
||||
`gf` is a powerful CLI tool for building [GoFrame](https://goframe.org) application with convenience.
|
||||
Powerful CLI tool for building [GoFrame](https://goframe.org) application with convenience.
|
||||
|
||||
## 1. Install
|
||||
|
||||
> You might need setting the goproxy to make through building.
|
||||
|
||||
1. Latest version
|
||||
> Go version >= v1.16
|
||||
```
|
||||
go install github.com/gogf/gf/tool/gf@latest
|
||||
```
|
||||
> Go version < v1.16
|
||||
```
|
||||
go install github.com/gogf/gf/tool/gf
|
||||
```
|
||||
1. Specified version
|
||||
> Go version >= v1.16
|
||||
```
|
||||
go install github.com/gogf/gf/tool/gf@v1.16.0
|
||||
```
|
||||
@ -35,8 +40,7 @@ COMMAND
|
||||
build cross-building go project for lots of platforms...
|
||||
docker create a docker image for current GF project...
|
||||
swagger swagger feature for current project...
|
||||
update update current gf binary to latest one (might need root/admin permission)
|
||||
install install gf binary to system (might need root/admin permission)
|
||||
update update current gf binary to latest one
|
||||
version show current binary version info
|
||||
|
||||
OPTION
|
||||
|
||||
@ -1,65 +0,0 @@
|
||||
# GF-CLI
|
||||
[English](README.MD) | 简体中文
|
||||
|
||||
`gf`是一款强大的[GoFrame](https://goframe.org)开发工具链,使得我们开发基于`GoFrame`框架的项目更加便捷。
|
||||
|
||||
## 1. 安装
|
||||
|
||||
1. 最新版本
|
||||
```
|
||||
go install github.com/gogf/gf/tool/gf@latest
|
||||
```
|
||||
1. 指定版本
|
||||
```
|
||||
go install github.com/gogf/gf/tool/gf@v1.16.0
|
||||
```
|
||||
> 注意:在`gf gen`命令中,由于`sqlite`和`oracle`数据库需要`cgo`和`gcc`支持,因此预编译的二进制中不提供对这两个数据库的支持,您需要手动修改源码,去掉对应源码文件中指定数据库类型的`import`注释后手动编译支持。
|
||||
|
||||
## 2. 命令
|
||||
```html
|
||||
$ gf
|
||||
USAGE
|
||||
gf COMMAND [ARGUMENT] [OPTION]
|
||||
|
||||
COMMAND
|
||||
env show current Golang environment variables
|
||||
get install or update GF to system in default...
|
||||
gen automatically generate go files for ORM models...
|
||||
mod extra features for go modules...
|
||||
run running go codes with hot-compiled-like feature...
|
||||
init initialize an empty GF project at current working directory...
|
||||
help show more information about a specified command
|
||||
pack packing any file/directory to a resource file, or a go file...
|
||||
build cross-building go project for lots of platforms...
|
||||
docker create a docker image for current GF project...
|
||||
swagger swagger feature for current project...
|
||||
update update current gf binary to latest one (might need root/admin permission)
|
||||
install install gf binary to system (might need root/admin permission)
|
||||
version show current binary version info
|
||||
|
||||
OPTION
|
||||
-y all yes for all command without prompt ask
|
||||
-?,-h show this help or detail for specified command
|
||||
-v,-i show version information
|
||||
|
||||
ADDITIONAL
|
||||
Use 'gf help COMMAND' or 'gf COMMAND -h' for detail about a command, which has '...'
|
||||
in the tail of their comments.
|
||||
```
|
||||
|
||||
## 3. 文档
|
||||
|
||||
完善详尽的中文文档请参考`GoFrame`官网板块:[开发工具](https://itician.org/pages/viewpage.action?pageId=1114260)
|
||||
|
||||
## 4. FAQ
|
||||
|
||||
### 1). `gf run` 命令报错 `pipe: too many open files`
|
||||
|
||||
请执行`ulimit -n 65535`命令扩展您当前终端会话支持的最大文件打开数,随后再执行`gf run`。需要注意的是该命令仅对当前终端会话有效。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,192 +0,0 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/container/gset"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/os/gcmd"
|
||||
"github.com/gogf/gf/os/genv"
|
||||
"github.com/gogf/gf/os/gfile"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
"github.com/gogf/gf/tool/gf/library/allyes"
|
||||
"github.com/gogf/gf/tool/gf/library/mlog"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// installFolderPath contains installFolderPath-related data,
|
||||
// such as path, writable, binaryFilePath, and installed.
|
||||
type installFolderPath struct {
|
||||
path string
|
||||
writable bool
|
||||
binaryFilePath string
|
||||
installed bool
|
||||
}
|
||||
|
||||
// Run does the installation.
|
||||
func Run() {
|
||||
// Ask where to install.
|
||||
paths := getInstallPathsData()
|
||||
if len(paths) <= 0 {
|
||||
mlog.Printf("no path detected, you can manually install gf by copying the binary to path folder.")
|
||||
return
|
||||
}
|
||||
mlog.Printf("I found some installable paths for you(from $PATH): ")
|
||||
mlog.Printf(" %2s | %8s | %9s | %s", "Id", "Writable", "Installed", "Path")
|
||||
|
||||
// Print all paths status and determine the default selectedID value.
|
||||
var (
|
||||
selectedID = -1
|
||||
pathSet = gset.NewStrSet() // Used for repeated items filtering.
|
||||
)
|
||||
for id, aPath := range paths {
|
||||
if !pathSet.AddIfNotExist(aPath.path) {
|
||||
continue
|
||||
}
|
||||
mlog.Printf(" %2d | %8t | %9t | %s", id, aPath.writable, aPath.installed, aPath.path)
|
||||
if selectedID == -1 {
|
||||
// Use the previously installed path as the most priority choice.
|
||||
if aPath.installed {
|
||||
selectedID = id
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there's no previously installed path, use the first writable path.
|
||||
if selectedID == -1 {
|
||||
// Order by choosing priority.
|
||||
commonPaths := garray.NewStrArrayFrom(g.SliceStr{
|
||||
`/usr/local/bin`,
|
||||
`/usr/bin`,
|
||||
`/usr/sbin`,
|
||||
`C:\Windows`,
|
||||
`C:\Windows\system32`,
|
||||
`C:\Go\bin`,
|
||||
`C:\Program Files`,
|
||||
`C:\Program Files (x86)`,
|
||||
})
|
||||
// Check the common installation directories.
|
||||
commonPaths.Iterator(func(k int, v string) bool {
|
||||
for id, aPath := range paths {
|
||||
if strings.EqualFold(aPath.path, v) {
|
||||
selectedID = id
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
if selectedID == -1 {
|
||||
selectedID = 0
|
||||
}
|
||||
}
|
||||
|
||||
if allyes.Check() {
|
||||
// Use the default selectedID.
|
||||
mlog.Printf("please choose one installation destination [default %d]: %d", selectedID, selectedID)
|
||||
} else {
|
||||
// Get input and update selectedID.
|
||||
input := gcmd.Scanf("please choose one installation destination [default %d]: ", selectedID)
|
||||
if input != "" {
|
||||
selectedID = gconv.Int(input)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if out of range.
|
||||
if selectedID >= len(paths) || selectedID < 0 {
|
||||
mlog.Printf("invalid install destination Id: %d", selectedID)
|
||||
return
|
||||
}
|
||||
|
||||
// Get selected destination path.
|
||||
dstPath := paths[selectedID]
|
||||
|
||||
// Install the new binary.
|
||||
err := gfile.CopyFile(gfile.SelfPath(), dstPath.binaryFilePath)
|
||||
if err != nil {
|
||||
mlog.Printf("install gf binary to '%s' failed: %v", dstPath.path, err)
|
||||
mlog.Printf("you can manually install gf by copying the binary to folder: %s", dstPath.path)
|
||||
} else {
|
||||
mlog.Printf("gf binary is successfully installed to: %s", dstPath.path)
|
||||
}
|
||||
|
||||
// Uninstall the old binary.
|
||||
for _, aPath := range paths {
|
||||
// Do not delete myself.
|
||||
if aPath.binaryFilePath != "" &&
|
||||
aPath.binaryFilePath != dstPath.binaryFilePath &&
|
||||
gfile.SelfPath() != aPath.binaryFilePath {
|
||||
gfile.Remove(aPath.binaryFilePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IsInstalled returns whether the binary is installed.
|
||||
func IsInstalled() bool {
|
||||
paths := getInstallPathsData()
|
||||
for _, aPath := range paths {
|
||||
if aPath.installed {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetInstallPathsData returns the installation paths data for the binary.
|
||||
func getInstallPathsData() []installFolderPath {
|
||||
var folderPaths []installFolderPath
|
||||
// Pre generate binaryFileName.
|
||||
binaryFileName := "gf" + gfile.Ext(gfile.SelfPath())
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
folderPaths = checkPathAndAppendToInstallFolderPath(
|
||||
folderPaths, "/usr/local/bin", binaryFileName,
|
||||
)
|
||||
default:
|
||||
// Search and find the writable directory path.
|
||||
envPath := genv.Get("PATH", genv.Get("Path"))
|
||||
if gstr.Contains(envPath, ";") {
|
||||
for _, v := range gstr.SplitAndTrim(envPath, ";") {
|
||||
folderPaths = checkPathAndAppendToInstallFolderPath(
|
||||
folderPaths, v, binaryFileName)
|
||||
}
|
||||
} else if gstr.Contains(envPath, ":") {
|
||||
for _, v := range gstr.SplitAndTrim(envPath, ":") {
|
||||
folderPaths = checkPathAndAppendToInstallFolderPath(
|
||||
folderPaths, v, binaryFileName)
|
||||
}
|
||||
} else if envPath != "" {
|
||||
folderPaths = checkPathAndAppendToInstallFolderPath(
|
||||
folderPaths, envPath, binaryFileName)
|
||||
} else {
|
||||
folderPaths = checkPathAndAppendToInstallFolderPath(
|
||||
folderPaths, "/usr/local/bin", binaryFileName)
|
||||
}
|
||||
}
|
||||
return folderPaths
|
||||
}
|
||||
|
||||
// checkPathAndAppendToInstallFolderPath checks if <path> is writable and already installed.
|
||||
// It adds the <path> to <folderPaths> if it is writable or already installed, or else it ignores the <path>.
|
||||
func checkPathAndAppendToInstallFolderPath(folderPaths []installFolderPath, path string, binaryFileName string) []installFolderPath {
|
||||
var (
|
||||
binaryFilePath = gfile.Join(path, binaryFileName)
|
||||
writable = gfile.IsWritable(path)
|
||||
installed = isInstalled(binaryFilePath)
|
||||
)
|
||||
if !writable && !installed {
|
||||
return folderPaths
|
||||
}
|
||||
return append(
|
||||
folderPaths,
|
||||
installFolderPath{
|
||||
path: path,
|
||||
writable: writable,
|
||||
binaryFilePath: binaryFilePath,
|
||||
installed: installed,
|
||||
})
|
||||
}
|
||||
|
||||
// Check if this gf binary path exists.
|
||||
func isInstalled(path string) bool {
|
||||
return gfile.Exists(path)
|
||||
}
|
||||
@ -1,95 +1,25 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/crypto/gmd5"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/net/ghttp"
|
||||
"github.com/gogf/gf/os/gfile"
|
||||
"github.com/gogf/gf/os/gproc"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
"github.com/gogf/gf/tool/gf/library/mlog"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
cdnUrl = g.Config("url").GetString("cdn.url")
|
||||
homeUrl = g.Config("url").GetString("home.url")
|
||||
)
|
||||
|
||||
func init() {
|
||||
if cdnUrl == "" {
|
||||
mlog.Fatal("CDN configuration cannot be empty")
|
||||
}
|
||||
if homeUrl == "" {
|
||||
mlog.Fatal("Home configuration cannot be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func Run() {
|
||||
mlog.Print("checking...")
|
||||
md5Url := homeUrl + `/cli/binary/md5`
|
||||
latestMd5 := ghttp.GetContent(md5Url, g.Map{
|
||||
"os": runtime.GOOS,
|
||||
"arch": runtime.GOARCH,
|
||||
})
|
||||
if latestMd5 == "" {
|
||||
mlog.Fatal("get the latest binary md5 failed, may be network issue")
|
||||
goBinPath := gproc.SearchBinary("go")
|
||||
if goBinPath == "" {
|
||||
mlog.Fatal(`"go" command not found, install it first to step further`)
|
||||
}
|
||||
localMd5, err := gmd5.EncryptFile(gfile.SelfPath())
|
||||
if err != nil {
|
||||
mlog.Fatal("calculate local binary md5 failed,", err.Error())
|
||||
}
|
||||
if localMd5 != latestMd5 {
|
||||
mlog.Print("downloading...")
|
||||
ext := ""
|
||||
if runtime.GOOS == "windows" {
|
||||
ext = ".exe"
|
||||
}
|
||||
downloadUrl := fmt.Sprintf(
|
||||
`%s/cli/binary/%s_%s/gf%s?%s`,
|
||||
cdnUrl,
|
||||
runtime.GOOS,
|
||||
runtime.GOARCH,
|
||||
ext,
|
||||
latestMd5,
|
||||
)
|
||||
mlog.Debugf("HTTP GET %s", downloadUrl)
|
||||
res, err := ghttp.Get(downloadUrl)
|
||||
if err != nil || res.StatusCode != 200 {
|
||||
mlog.Fatalf(
|
||||
"downloading failed for %s %s, may be network issue:\n%s",
|
||||
runtime.GOOS, runtime.GOARCH, res.ReadAllString(),
|
||||
)
|
||||
}
|
||||
defer res.Close()
|
||||
data := res.ReadAll()
|
||||
mlog.Print("installing...")
|
||||
var (
|
||||
binPath = gfile.SelfPath()
|
||||
binDirPath = gfile.SelfDir()
|
||||
renamePath = binPath + "~"
|
||||
)
|
||||
if runtime.GOOS == "windows" {
|
||||
// Rename myself for windows.
|
||||
if err := gfile.Rename(binPath, renamePath); err != nil {
|
||||
mlog.Fatal("rename binary file failed:", err.Error())
|
||||
}
|
||||
defer gfile.Remove(renamePath)
|
||||
} else {
|
||||
// Remove the binary for other platforms.
|
||||
if gfile.IsWritable(binDirPath) {
|
||||
if err := gfile.Remove(binPath); err != nil {
|
||||
mlog.Fatal("remove binary failed:", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := gfile.PutBytes(binPath, data); err != nil {
|
||||
mlog.Fatal("install binary failed:", err.Error())
|
||||
}
|
||||
if err := gfile.Chmod(binPath, 0777); err != nil {
|
||||
mlog.Fatal("chmod binary failed:", err.Error())
|
||||
}
|
||||
mlog.Print("gf binary is now updated to the latest version")
|
||||
var err error
|
||||
if gstr.CompareVersionGo(runtime.Version(), "go1.16.0") >= 0 {
|
||||
err = gproc.ShellRun(`go install github.com/gogf/gf/tool/gf@latest`)
|
||||
} else {
|
||||
mlog.Print("it's the latest version, no need updates")
|
||||
err = gproc.ShellRun(`go install github.com/gogf/gf/tool/gf`)
|
||||
}
|
||||
if err != nil {
|
||||
mlog.Fatalf(`gf binary installation failed: %+v`, err)
|
||||
}
|
||||
mlog.Print("gf binary is now updated to the latest version")
|
||||
}
|
||||
|
||||
@ -1,26 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "github.com/gogf/gf/tool/gf/boot"
|
||||
|
||||
"github.com/gogf/gf"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
"github.com/gogf/gf/tool/gf/commands/env"
|
||||
"github.com/gogf/gf/tool/gf/commands/mod"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/os/gbuild"
|
||||
"github.com/gogf/gf/os/gcmd"
|
||||
"github.com/gogf/gf/os/gfile"
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
_ "github.com/gogf/gf/tool/gf/boot"
|
||||
"github.com/gogf/gf/tool/gf/commands/build"
|
||||
"github.com/gogf/gf/tool/gf/commands/docker"
|
||||
"github.com/gogf/gf/tool/gf/commands/env"
|
||||
"github.com/gogf/gf/tool/gf/commands/fix"
|
||||
"github.com/gogf/gf/tool/gf/commands/gen"
|
||||
"github.com/gogf/gf/tool/gf/commands/get"
|
||||
"github.com/gogf/gf/tool/gf/commands/initialize"
|
||||
"github.com/gogf/gf/tool/gf/commands/install"
|
||||
"github.com/gogf/gf/tool/gf/commands/mod"
|
||||
"github.com/gogf/gf/tool/gf/commands/pack"
|
||||
"github.com/gogf/gf/tool/gf/commands/run"
|
||||
"github.com/gogf/gf/tool/gf/commands/swagger"
|
||||
@ -52,8 +49,7 @@ COMMAND
|
||||
build cross-building go project for lots of platforms...
|
||||
docker create a docker image for current GF project...
|
||||
swagger swagger feature for current project...
|
||||
update update current gf binary to latest one (might need root/admin permission)
|
||||
install install gf binary to system (might need root/admin permission)
|
||||
update update current gf binary to latest one
|
||||
version show current binary version info
|
||||
|
||||
OPTION
|
||||
@ -111,8 +107,6 @@ func main() {
|
||||
swagger.Run()
|
||||
case "update":
|
||||
update.Run()
|
||||
case "install":
|
||||
install.Run()
|
||||
case "build":
|
||||
build.Run()
|
||||
case "run":
|
||||
@ -128,16 +122,6 @@ func main() {
|
||||
return
|
||||
}
|
||||
}
|
||||
// No argument or option, do installation checks.
|
||||
if !install.IsInstalled() {
|
||||
mlog.Print("hi, it seams it's the first time you installing gf cli.")
|
||||
s := gcmd.Scanf("do you want to install gf binary to your system? [y/n]: ")
|
||||
if strings.EqualFold(s, "y") {
|
||||
install.Run()
|
||||
gcmd.Scan("press <Enter> to exit...")
|
||||
return
|
||||
}
|
||||
}
|
||||
mlog.Print(helpContent)
|
||||
}
|
||||
}
|
||||
@ -183,18 +167,6 @@ func version() {
|
||||
}
|
||||
mlog.Printf(`GoFrame Version: %s`, gfVersion)
|
||||
mlog.Printf(`CLI Installed At: %s`, gfile.SelfPath())
|
||||
if info["gf"] == "" {
|
||||
mlog.Print(`Current is a custom installed version, no installation information.`)
|
||||
return
|
||||
}
|
||||
|
||||
mlog.Print(gstr.Trim(fmt.Sprintf(`
|
||||
CLI Built Detail:
|
||||
Go Version: %s
|
||||
GF Version: %s
|
||||
Git Commit: %s
|
||||
Build Time: %s
|
||||
`, info["go"], info["gf"], info["git"], info["time"])))
|
||||
}
|
||||
|
||||
// getGFVersionOfCurrentProject checks and returns the GoFrame version current project using.
|
||||
@ -210,6 +182,6 @@ func getGFVersionOfCurrentProject() (string, error) {
|
||||
}
|
||||
return "", gerror.New("cannot find goframe requirement in go.mod")
|
||||
} else {
|
||||
return "", gerror.New("cannot find go.mod")
|
||||
return "", gerror.New("cannot find go.mod in current directory")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user