From adb4a1e6c0c18278e3db22ad27d14ee73e1290f8 Mon Sep 17 00:00:00 2001 From: John Guo Date: Tue, 25 Jan 2022 10:21:59 +0800 Subject: [PATCH 1/4] README update --- README.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.MD b/README.MD index bea4043e0..837075277 100644 --- a/README.MD +++ b/README.MD @@ -27,6 +27,7 @@ - much, much more...ready to explore? # Installation +Enter your repo. directory and execute following command: ## primary module ```bash @@ -35,7 +36,7 @@ go get -u -v github.com/gogf/gf/v2 ## cli tool ```bash -go install -g github.com/gogf/gf/cmd/gf/v2 +go install github.com/gogf/gf/cmd/gf/v2 ``` # Limitation From 01b9fa8ac9e35dfa50dfea2fbf8f6a08c3452d4f Mon Sep 17 00:00:00 2001 From: John Guo Date: Tue, 25 Jan 2022 20:43:57 +0800 Subject: [PATCH 2/4] improve package gcfg --- errors/gerror/gerror.go | 26 +++++++----- errors/gerror/gerror_error.go | 3 ++ os/gcfg/gcfg.go | 6 ++- os/gcfg/gcfg_adapter_file_path.go | 2 +- os/gcfg/gcfg_z_example_test.go | 66 +++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 os/gcfg/gcfg_z_example_test.go diff --git a/errors/gerror/gerror.go b/errors/gerror/gerror.go index ac11e323d..282dcb40a 100644 --- a/errors/gerror/gerror.go +++ b/errors/gerror/gerror.go @@ -241,22 +241,30 @@ func WrapCodeSkipf(code gcode.Code, skip int, err error, format string, args ... } // Code returns the error code of current error. -// It returns CodeNil if it has no error code or it does not implements interface Code. +// It returns CodeNil if it has no error code neither it does not implement interface Code. func Code(err error) gcode.Code { - if err != nil { - if e, ok := err.(iCode); ok { - return e.Code() - } + if err == nil { + return gcode.CodeNil + } + if e, ok := err.(iCode); ok { + return e.Code() + } + if e, ok := err.(iNext); ok { + return Code(e.Next()) } return gcode.CodeNil } // Cause returns the root cause error of `err`. func Cause(err error) error { - if err != nil { - if e, ok := err.(iCause); ok { - return e.Cause() - } + if err == nil { + return nil + } + if e, ok := err.(iCause); ok { + return e.Cause() + } + if e, ok := err.(iNext); ok { + return Cause(e.Next()) } return err } diff --git a/errors/gerror/gerror_error.go b/errors/gerror/gerror_error.go index c69f01836..e3491b7bf 100644 --- a/errors/gerror/gerror_error.go +++ b/errors/gerror/gerror_error.go @@ -65,6 +65,9 @@ func (err *Error) Code() gcode.Code { if err == nil { return gcode.CodeNil } + if err.code == gcode.CodeNil { + return Code(err.Next()) + } return err.code } diff --git a/os/gcfg/gcfg.go b/os/gcfg/gcfg.go index 0e080afab..5342f56e3 100644 --- a/os/gcfg/gcfg.go +++ b/os/gcfg/gcfg.go @@ -13,6 +13,8 @@ import ( "github.com/gogf/gf/v2/container/gmap" "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/internal/command" "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/internal/utils" @@ -140,7 +142,7 @@ func (c *Config) Get(ctx context.Context, pattern string, def ...interface{}) (* // Fetching Rules: Environment arguments are in uppercase format, eg: GF_PACKAGE_VARIABLE. func (c *Config) GetWithEnv(ctx context.Context, pattern string, def ...interface{}) (*gvar.Var, error) { value, err := c.Get(ctx, pattern) - if err != nil { + if err != nil && gerror.Code(err) != gcode.CodeNotFound { return nil, err } if value == nil { @@ -162,7 +164,7 @@ func (c *Config) GetWithEnv(ctx context.Context, pattern string, def ...interfac // Fetching Rules: Command line arguments are in lowercase format, eg: gf.package.variable. func (c *Config) GetWithCmd(ctx context.Context, pattern string, def ...interface{}) (*gvar.Var, error) { value, err := c.Get(ctx, pattern) - if err != nil { + if err != nil && gerror.Code(err) != gcode.CodeNotFound { return nil, err } if value == nil { diff --git a/os/gcfg/gcfg_adapter_file_path.go b/os/gcfg/gcfg_adapter_file_path.go index fa65ecca5..b23c682fc 100644 --- a/os/gcfg/gcfg_adapter_file_path.go +++ b/os/gcfg/gcfg_adapter_file_path.go @@ -219,7 +219,7 @@ func (c *AdapterFile) GetFilePath(fileName ...string) (path string, err error) { } else { buffer.WriteString(fmt.Sprintf(`cannot find config file "%s" with no path configured`, usedFileName)) } - err = gerror.New(buffer.String()) + err = gerror.NewCode(gcode.CodeNotFound, buffer.String()) } return } diff --git a/os/gcfg/gcfg_z_example_test.go b/os/gcfg/gcfg_z_example_test.go new file mode 100644 index 000000000..a64a2e4ca --- /dev/null +++ b/os/gcfg/gcfg_z_example_test.go @@ -0,0 +1,66 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gcfg_test + +import ( + "fmt" + "os" + + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gcmd" + "github.com/gogf/gf/v2/os/gctx" + "github.com/gogf/gf/v2/os/genv" +) + +func ExampleConfig_GetWithEnv() { + var ( + key = `ENV_TEST` + ctx = gctx.New() + ) + v, err := g.Cfg().GetWithEnv(ctx, key) + if err != nil { + panic(err) + } + fmt.Printf("env:%s\n", v) + if err = genv.Set(key, "gf"); err != nil { + panic(err) + } + v, err = g.Cfg().GetWithEnv(ctx, key) + if err != nil { + panic(err) + } + fmt.Printf("env:%s", v) + + // Output: + // env: + // env:gf +} + +func ExampleConfig_GetWithCmd() { + var ( + key = `cmd.test` + ctx = gctx.New() + ) + v, err := g.Cfg().GetWithCmd(ctx, key) + if err != nil { + panic(err) + } + fmt.Printf("cmd:%s\n", v) + // Re-Initialize custom command arguments. + os.Args = append(os.Args, fmt.Sprintf(`--%s=yes`, key)) + gcmd.Init(os.Args...) + // Retrieve the configuration and command option again. + v, err = g.Cfg().GetWithCmd(ctx, key) + if err != nil { + panic(err) + } + fmt.Printf("cmd:%s", v) + + // Output: + // cmd: + // cmd:yes +} From 7ac9c46f12047062e39386039061ff14a5a9d187 Mon Sep 17 00:00:00 2001 From: John Guo Date: Tue, 25 Jan 2022 23:01:35 +0800 Subject: [PATCH 3/4] mark underlying PostForm function deprecated for gclient.Client --- net/gclient/gclient_request.go | 23 +++++++++++++++++++++++ net/gclient/gclient_z_unit_test.go | 3 +++ 2 files changed, 26 insertions(+) diff --git a/net/gclient/gclient_request.go b/net/gclient/gclient_request.go index 144002baf..50915db34 100644 --- a/net/gclient/gclient_request.go +++ b/net/gclient/gclient_request.go @@ -13,6 +13,7 @@ import ( "io/ioutil" "mime/multipart" "net/http" + "net/url" "os" "strings" "time" @@ -83,6 +84,28 @@ func (c *Client) Trace(ctx context.Context, url string, data ...interface{}) (*R return c.DoRequest(ctx, httpMethodTrace, url, data...) } +// PostForm issues a POST to the specified URL, +// with data's keys and values URL-encoded as the request body. +// +// The Content-Type header is set to application/x-www-form-urlencoded. +// To set other headers, use NewRequest and Client.Do. +// +// When err is nil, resp always contains a non-nil resp.Body. +// Caller should close resp.Body when done reading from it. +// +// See the Client.Do method documentation for details on how redirects +// are handled. +// +// To make a request with a specified context.Context, use NewRequestWithContext +// and Client.Do. +// Deprecated, use Post instead. +func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) { + return nil, gerror.NewCode( + gcode.CodeNotSupported, + `PostForm is not supported, please use Post instead`, + ) +} + // DoRequest sends request with given HTTP method and data and returns the response object. // Note that the response object MUST be closed if it'll never be used. // diff --git a/net/gclient/gclient_z_unit_test.go b/net/gclient/gclient_z_unit_test.go index 02b704e87..af6d137a9 100644 --- a/net/gclient/gclient_z_unit_test.go +++ b/net/gclient/gclient_z_unit_test.go @@ -54,6 +54,9 @@ func Test_Client_Basic(t *testing.T) { _, err := g.Client().Post(ctx, "") t.AssertNE(err, nil) + + _, err = g.Client().PostForm("", nil) + t.AssertNE(err, nil) }) } From 809496860518b7957a1e32674dc490a118405e46 Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 26 Jan 2022 17:05:30 +0800 Subject: [PATCH 4/4] README update --- cmd/gf/README.MD | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/cmd/gf/README.MD b/cmd/gf/README.MD index d40ec2668..f3e564b1c 100644 --- a/cmd/gf/README.MD +++ b/cmd/gf/README.MD @@ -2,7 +2,10 @@ `gf` is a powerful CLI tool for building [GoFrame](https://goframe.org) application with convenience. -# Install + +## 1. Install + +### 1). Manually Install > You might need setting the goproxy to make through building. > Please make sure your Golang version > v1.15. @@ -16,8 +19,30 @@ ``` gf -v ``` +### 2). PreBuilt Binary -## Commands +You can also install `gf` tool using pre-built binaries: https://github.com/gogf/gf/releases + +After downloads, please use `gf_xxx_xxx install` command to install gf binary to system binary path. + +1. `Mac` + ```shell + wget -O gf https://github.com/gogf/gf/releases/download/v2.0.0-rc2/gf_darwin_amd64 && chmod +x gf && ./gf install + ``` + > If you're using `zsh`, you might need rename your alias by command `alias gf=gf` to resolve the conflicts between `gf` and `git fetch`. + +2. `Linux` + ```shell + wget -O gf https://github.com/gogf/gf/releases/download/v2.0.0-rc2/gf_linux_amd64 && chmod +x gf && ./gf install + ``` + +3. `Windows` + + Manually download, execute it and then follow the instruction. + +4. Database `sqlite` and `oracle` are not support in `gf gen` command in default as it needs `cgo` and `gcc`, you can manually make some changes to the source codes and do the building. + +## 2. Commands ```html $ gf USAGE @@ -45,11 +70,11 @@ ADDITIONAL Use "gf COMMAND -h" for details about a command. ``` -# FAQ +## 3. FAQ -1. Command `gf run` returns `pipe: too many open files` +### 1). Command `gf run` returns `pipe: too many open files` - Please use `ulimit -n 65535` to enlarge your system configuration for max open files for current terminal shell session, and then `gf run`. +Please use `ulimit -n 65535` to enlarge your system configuration for max open files for current terminal shell session, and then `gf run`.