2021-11-21 13:09:45 +08:00
|
|
|
// 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 gcmd
|
|
|
|
|
|
|
|
|
|
import (
|
2022-06-17 17:41:10 +08:00
|
|
|
"bytes"
|
2021-11-21 13:09:45 +08:00
|
|
|
"context"
|
|
|
|
|
"fmt"
|
2021-11-21 22:38:47 +08:00
|
|
|
"os"
|
2021-11-21 13:09:45 +08:00
|
|
|
|
2022-11-01 20:12:21 +08:00
|
|
|
"go.opentelemetry.io/otel"
|
|
|
|
|
"go.opentelemetry.io/otel/propagation"
|
|
|
|
|
"go.opentelemetry.io/otel/trace"
|
|
|
|
|
|
2022-06-17 15:16:35 +08:00
|
|
|
"github.com/gogf/gf/v2"
|
2022-01-01 19:57:43 +08:00
|
|
|
"github.com/gogf/gf/v2/errors/gcode"
|
|
|
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
2022-06-17 15:16:35 +08:00
|
|
|
"github.com/gogf/gf/v2/net/gtrace"
|
2021-12-07 19:08:52 +08:00
|
|
|
"github.com/gogf/gf/v2/os/gcfg"
|
2022-06-17 15:16:35 +08:00
|
|
|
"github.com/gogf/gf/v2/os/genv"
|
2022-06-17 17:41:10 +08:00
|
|
|
"github.com/gogf/gf/v2/os/glog"
|
2021-11-21 13:09:45 +08:00
|
|
|
"github.com/gogf/gf/v2/text/gstr"
|
2021-12-07 19:08:52 +08:00
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
|
|
|
"github.com/gogf/gf/v2/util/gutil"
|
2021-11-21 13:09:45 +08:00
|
|
|
)
|
|
|
|
|
|
2024-01-30 20:14:13 +08:00
|
|
|
// Run calls custom function in os.Args that bound to this command.
|
2022-01-01 20:20:49 +08:00
|
|
|
// It exits this process with exit code 1 if any error occurs.
|
|
|
|
|
func (c *Command) Run(ctx context.Context) {
|
|
|
|
|
_ = c.RunWithValue(ctx)
|
2021-11-23 20:26:55 +08:00
|
|
|
}
|
|
|
|
|
|
2024-01-30 20:14:13 +08:00
|
|
|
// RunWithValue calls custom function in os.Args that bound to this command with value output.
|
2022-01-01 20:20:49 +08:00
|
|
|
// It exits this process with exit code 1 if any error occurs.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.
**Type alias migration to `any`:**
* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)
**Generated code and templates:**
* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
**Container and utility updates:**
* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)
These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
|
|
|
func (c *Command) RunWithValue(ctx context.Context) (value any) {
|
2022-01-01 20:20:49 +08:00
|
|
|
value, err := c.RunWithValueError(ctx)
|
|
|
|
|
if err != nil {
|
2022-01-12 19:39:38 +08:00
|
|
|
var (
|
|
|
|
|
code = gerror.Code(err)
|
|
|
|
|
detail = code.Detail()
|
2022-06-17 17:41:10 +08:00
|
|
|
buffer = bytes.NewBuffer(nil)
|
2022-01-12 19:39:38 +08:00
|
|
|
)
|
|
|
|
|
if code.Code() == gcode.CodeNotFound.Code() {
|
2025-08-29 10:32:30 +08:00
|
|
|
fmt.Fprintf(buffer, "ERROR: %s\n", gstr.Trim(err.Error()))
|
2022-01-12 19:39:38 +08:00
|
|
|
if lastCmd, ok := detail.(*Command); ok {
|
2022-06-17 17:41:10 +08:00
|
|
|
lastCmd.PrintTo(buffer)
|
2022-01-12 19:39:38 +08:00
|
|
|
} else {
|
2022-06-17 17:41:10 +08:00
|
|
|
c.PrintTo(buffer)
|
2022-01-12 19:39:38 +08:00
|
|
|
}
|
2022-01-01 20:20:49 +08:00
|
|
|
} else {
|
2025-08-29 10:32:30 +08:00
|
|
|
fmt.Fprintf(buffer, "%+v\n", err)
|
2022-01-01 20:20:49 +08:00
|
|
|
}
|
2022-06-17 17:41:10 +08:00
|
|
|
if gtrace.GetTraceID(ctx) == "" {
|
|
|
|
|
fmt.Println(buffer.String())
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
2022-06-17 17:42:49 +08:00
|
|
|
glog.Stack(false).Fatal(ctx, buffer.String())
|
2022-01-01 20:20:49 +08:00
|
|
|
}
|
|
|
|
|
return value
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-30 20:14:13 +08:00
|
|
|
// RunWithError calls custom function in os.Args that bound to this command with error output.
|
2022-01-01 20:20:49 +08:00
|
|
|
func (c *Command) RunWithError(ctx context.Context) (err error) {
|
|
|
|
|
_, err = c.RunWithValueError(ctx)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-30 20:14:13 +08:00
|
|
|
// RunWithValueError calls custom function in os.Args that bound to this command with value and error output.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.
**Type alias migration to `any`:**
* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)
**Generated code and templates:**
* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
**Container and utility updates:**
* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)
These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
|
|
|
func (c *Command) RunWithValueError(ctx context.Context) (value any, err error) {
|
2024-01-30 20:14:13 +08:00
|
|
|
return c.RunWithSpecificArgs(ctx, os.Args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RunWithSpecificArgs calls custom function in specific args that bound to this command with value and error output.
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.
**Type alias migration to `any`:**
* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)
**Generated code and templates:**
* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
**Container and utility updates:**
* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)
These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
|
|
|
func (c *Command) RunWithSpecificArgs(ctx context.Context, args []string) (value any, err error) {
|
2024-01-30 20:14:13 +08:00
|
|
|
if len(args) == 0 {
|
|
|
|
|
return nil, gerror.NewCode(gcode.CodeInvalidParameter, "args can not be empty!")
|
|
|
|
|
}
|
|
|
|
|
parser, err := ParseArgs(args, nil)
|
2021-11-21 13:09:45 +08:00
|
|
|
if err != nil {
|
2021-11-23 20:26:55 +08:00
|
|
|
return nil, err
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
2024-01-30 20:14:13 +08:00
|
|
|
parsedArgs := parser.GetArgAll()
|
2021-11-21 13:09:45 +08:00
|
|
|
|
|
|
|
|
// Exclude the root binary name.
|
2024-01-30 20:14:13 +08:00
|
|
|
parsedArgs = parsedArgs[1:]
|
2021-11-21 13:09:45 +08:00
|
|
|
|
2024-10-10 09:17:34 +08:00
|
|
|
// If no args or no sub command, it runs standalone.
|
|
|
|
|
if len(parsedArgs) == 0 || len(c.commands) == 0 {
|
|
|
|
|
return c.doRun(ctx, args, parser)
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-21 13:09:45 +08:00
|
|
|
// Find the matched command and run it.
|
2024-09-28 18:02:34 +08:00
|
|
|
// It here `fromArgIndex` set to 1 to calculate the argument index in to `newCtx`.
|
|
|
|
|
lastCmd, foundCmd, newCtx := c.searchCommand(ctx, parsedArgs, 1)
|
2022-01-12 19:39:38 +08:00
|
|
|
if foundCmd != nil {
|
2024-01-30 20:14:13 +08:00
|
|
|
return foundCmd.doRun(newCtx, args, parser)
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Print error and help command if no command found.
|
2022-01-01 19:57:43 +08:00
|
|
|
err = gerror.NewCodef(
|
2022-01-12 19:39:38 +08:00
|
|
|
gcode.WithCode(gcode.CodeNotFound, lastCmd),
|
|
|
|
|
`command "%s" not found for command "%s", command line: %s`,
|
2024-01-30 20:14:13 +08:00
|
|
|
gstr.Join(parsedArgs, " "),
|
2022-01-12 19:39:38 +08:00
|
|
|
c.Name,
|
2024-01-30 20:14:13 +08:00
|
|
|
gstr.Join(args, " "),
|
2021-11-21 22:38:47 +08:00
|
|
|
)
|
2022-01-01 19:57:43 +08:00
|
|
|
return
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
|
|
|
|
|
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.
**Type alias migration to `any`:**
* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)
**Generated code and templates:**
* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
**Container and utility updates:**
* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)
These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
|
|
|
func (c *Command) doRun(ctx context.Context, args []string, parser *Parser) (value any, err error) {
|
2022-01-12 19:39:38 +08:00
|
|
|
defer func() {
|
|
|
|
|
if exception := recover(); exception != nil {
|
|
|
|
|
if v, ok := exception.(error); ok && gerror.HasStack(v) {
|
|
|
|
|
err = v
|
|
|
|
|
} else {
|
2023-08-14 09:53:13 +08:00
|
|
|
err = gerror.NewCodef(gcode.CodeInternalPanic, "exception recovered: %+v", exception)
|
2022-01-12 19:39:38 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}()
|
2021-12-07 22:19:28 +08:00
|
|
|
|
2022-01-12 19:39:38 +08:00
|
|
|
ctx = context.WithValue(ctx, CtxKeyCommand, c)
|
2021-11-21 13:09:45 +08:00
|
|
|
// Check built-in help command.
|
2022-01-19 21:07:48 +08:00
|
|
|
if parser.GetOpt(helpOptionName) != nil || parser.GetOpt(helpOptionNameShort) != nil {
|
2021-11-21 13:09:45 +08:00
|
|
|
if c.HelpFunc != nil {
|
2021-11-23 20:26:55 +08:00
|
|
|
return nil, c.HelpFunc(ctx, parser)
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
2021-11-23 20:26:55 +08:00
|
|
|
return nil, c.defaultHelpFunc(ctx, parser)
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
2024-10-10 09:17:34 +08:00
|
|
|
|
2022-06-17 15:16:35 +08:00
|
|
|
// OpenTelemetry for command.
|
|
|
|
|
var (
|
|
|
|
|
span trace.Span
|
|
|
|
|
tr = otel.GetTracerProvider().Tracer(
|
|
|
|
|
tracingInstrumentName,
|
|
|
|
|
trace.WithInstrumentationVersion(gf.VERSION),
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
ctx, span = tr.Start(
|
|
|
|
|
otel.GetTextMapPropagator().Extract(
|
|
|
|
|
ctx,
|
|
|
|
|
propagation.MapCarrier(genv.Map()),
|
|
|
|
|
),
|
|
|
|
|
gstr.Join(os.Args, " "),
|
|
|
|
|
trace.WithSpanKind(trace.SpanKindServer),
|
|
|
|
|
)
|
|
|
|
|
defer span.End()
|
|
|
|
|
span.SetAttributes(gtrace.CommonLabels()...)
|
2024-01-30 20:14:13 +08:00
|
|
|
// Reparse the original arguments for current command configuration.
|
|
|
|
|
parser, err = c.reParse(ctx, args, parser)
|
2021-11-21 13:09:45 +08:00
|
|
|
if err != nil {
|
2021-11-23 20:26:55 +08:00
|
|
|
return nil, err
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
|
|
|
|
// Registered command function calling.
|
2021-11-23 20:26:55 +08:00
|
|
|
if c.Func != nil {
|
|
|
|
|
return nil, c.Func(ctx, parser)
|
|
|
|
|
}
|
|
|
|
|
if c.FuncWithValue != nil {
|
|
|
|
|
return c.FuncWithValue(ctx, parser)
|
|
|
|
|
}
|
2021-11-24 16:17:50 +08:00
|
|
|
// If no function defined in current command, it then prints help.
|
|
|
|
|
if c.HelpFunc != nil {
|
|
|
|
|
return nil, c.HelpFunc(ctx, parser)
|
|
|
|
|
}
|
|
|
|
|
return nil, c.defaultHelpFunc(ctx, parser)
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
|
|
|
|
|
2024-01-30 20:14:13 +08:00
|
|
|
// reParse parses the original arguments using option configuration of current command.
|
|
|
|
|
func (c *Command) reParse(ctx context.Context, args []string, parser *Parser) (*Parser, error) {
|
2021-12-09 23:49:39 +08:00
|
|
|
if len(c.Arguments) == 0 {
|
2021-12-02 20:27:26 +08:00
|
|
|
return parser, nil
|
|
|
|
|
}
|
2021-11-21 13:09:45 +08:00
|
|
|
var (
|
|
|
|
|
optionKey string
|
|
|
|
|
supportedOptions = make(map[string]bool)
|
|
|
|
|
)
|
2021-12-09 23:49:39 +08:00
|
|
|
for _, arg := range c.Arguments {
|
|
|
|
|
if arg.IsArg {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if arg.Short != "" {
|
2023-11-22 21:05:39 +08:00
|
|
|
optionKey = fmt.Sprintf(`%s,%s`, arg.Name, arg.Short)
|
|
|
|
|
} else {
|
|
|
|
|
optionKey = arg.Name
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
2021-12-09 23:49:39 +08:00
|
|
|
supportedOptions[optionKey] = !arg.Orphan
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
2024-01-30 20:14:13 +08:00
|
|
|
parser, err := ParseArgs(args, supportedOptions, ParserOption{
|
2022-05-13 15:24:10 +08:00
|
|
|
CaseSensitive: c.CaseSensitive,
|
|
|
|
|
Strict: c.Strict,
|
|
|
|
|
})
|
2021-12-07 19:08:52 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
// Retrieve option values from config component if it has "config" tag.
|
|
|
|
|
if c.Config != "" && gcfg.Instance().Available(ctx) {
|
|
|
|
|
value, err := gcfg.Instance().Get(ctx, c.Config)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
configMap := value.Map()
|
2022-11-01 20:12:21 +08:00
|
|
|
for optionName := range parser.supportedOptions {
|
2021-12-07 19:08:52 +08:00
|
|
|
// The command line has the high priority.
|
2022-01-19 21:07:48 +08:00
|
|
|
if parser.GetOpt(optionName) != nil {
|
2021-12-07 19:08:52 +08:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
// Merge the config value into parser.
|
|
|
|
|
foundKey, foundValue := gutil.MapPossibleItemByKey(configMap, optionName)
|
|
|
|
|
if foundKey != "" {
|
|
|
|
|
parser.parsedOptions[optionName] = gconv.String(foundValue)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return parser, nil
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
|
|
|
|
|
2021-11-21 22:38:47 +08:00
|
|
|
// searchCommand recursively searches the command according given arguments.
|
2024-04-01 19:07:08 +08:00
|
|
|
func (c *Command) searchCommand(
|
|
|
|
|
ctx context.Context, args []string, fromArgIndex int,
|
|
|
|
|
) (lastCmd, foundCmd *Command, newCtx context.Context) {
|
2021-11-21 13:09:45 +08:00
|
|
|
if len(args) == 0 {
|
2022-01-12 19:39:38 +08:00
|
|
|
return c, nil, ctx
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
|
|
|
|
for _, cmd := range c.commands {
|
2021-12-02 23:50:29 +08:00
|
|
|
// Recursively searching the command.
|
2024-04-01 19:07:08 +08:00
|
|
|
// String comparison case-sensitive.
|
2021-11-21 13:09:45 +08:00
|
|
|
if cmd.Name == args[0] {
|
|
|
|
|
leftArgs := args[1:]
|
2021-12-09 23:49:39 +08:00
|
|
|
// If this command needs argument,
|
2024-04-01 19:07:08 +08:00
|
|
|
// it then gives all its left arguments to it using arg index marks.
|
|
|
|
|
//
|
|
|
|
|
// Note that the args here (using default args parsing) could be different with the args
|
|
|
|
|
// that are parsed in command.
|
|
|
|
|
if cmd.hasArgumentFromIndex() || len(leftArgs) == 0 {
|
|
|
|
|
ctx = context.WithValue(ctx, CtxKeyArgumentsIndex, fromArgIndex+1)
|
2022-01-12 19:39:38 +08:00
|
|
|
return c, cmd, ctx
|
2021-12-09 23:49:39 +08:00
|
|
|
}
|
2024-04-01 19:07:08 +08:00
|
|
|
return cmd.searchCommand(ctx, leftArgs, fromArgIndex+1)
|
2021-12-09 23:49:39 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-01-12 19:39:38 +08:00
|
|
|
return c, nil, ctx
|
2021-12-09 23:49:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Command) hasArgumentFromIndex() bool {
|
|
|
|
|
for _, arg := range c.Arguments {
|
|
|
|
|
if arg.IsArg {
|
|
|
|
|
return true
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
|
|
|
|
}
|
2021-12-09 23:49:39 +08:00
|
|
|
return false
|
2021-11-21 13:09:45 +08:00
|
|
|
}
|
2021-12-11 01:11:40 +08:00
|
|
|
|
|
|
|
|
func (c *Command) hasArgumentFromOption() bool {
|
|
|
|
|
for _, arg := range c.Arguments {
|
|
|
|
|
if !arg.IsArg {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|