Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing command-line argument. #3390

Closed
clh021 opened this issue Mar 15, 2024 · 25 comments
Closed

Missing command-line argument. #3390

clh021 opened this issue Mar 15, 2024 · 25 comments
Labels
bug It is confirmed a bug, but don't worry, we'll handle it. done This issue is done, which may be release in next version.

Comments

@clh021
Copy link

clh021 commented Mar 15, 2024

What version of Go and system type/arch are you using?

Go Version: go1.21.4 linux/amd64

What version of GoFrame are you using?

require github.com/gogf/gf/v2 v2.6.4

Can this bug be re-produced with the latest release?
Yes.

是的,最新发行版仍然可以重现该问题

What did you do?

package main

import (
	"context"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gcmd"
	"github.com/gogf/gf/v2/os/gctx"
)

type Command struct {
	*gcmd.Command
}

var (
	Test = cTest{}
)

type cTest struct {
	g.Meta `name:"index" ad:"test"`
}

type cInput struct {
	g.Meta `name:"index"`
	A      string `short:"a" name:"aa" brief:"aa"`
	B      string `short:"b" name:"bb" brief:"bb"`
}

type cOutput struct{}

func (c cTest) Index(ctx context.Context, in cInput) (out *cOutput, err error) {
	g.Dump(in)
	return
}

func main() {
	var (
		ctx = gctx.GetInitCtx()
	)
	root, err := gcmd.NewFromObject(Test)
	if err != nil {
		panic(err)
	}
	command := &Command{root}
	command.RunWithError(ctx)
}

To facilitate comparison, it is recommended to use the command gf run ./main.go -a "-a aaa -b bbb" for debugging purposes.
为了方便对比,建议使用 gf run ./main.go -a "-a aaa -b bbb" 命令进行调试操作。

What did you expect to see?
Modifying B in cInput to Be or any other content will cause the loss of the parameter value bbb.
Modifying the short options corresponding to A and B in cInput such that A corresponds to b, and B corresponds to a, would result in the parameter value aaa still being associated with A, while the parameter bbb remains with B.

修改 cInput 中的 BBe 或其它内容,将丢失参数值 bbb
修改 cInput 中的 A,B 对应的 short,使其调换 为 A对应b, B对应 a,参数值 aaa仍在 A上,参数 bbb 仍在 B 上。

What did you see instead?
After modifying B in cInput to Be or any other content, the original parameter value bbb that could be received should still be accepted without being affected.
When modifying the short options corresponding to A and B in cInput such that A corresponds to b, and B corresponds to a, the parameter value aaa would now be associated with B, while the parameter bbb is on A.

修改 cInput 中的 BBe 或其它内容后,原来可以接收的参数值 bbb,仍然可以顺利接收,不受影响。
修改 cInput 中的 A,B 对应的 short,使其调换 为 A对应b, B对应 a,参数值 aaaB上,参数 bbbA 上。

@clh021 clh021 added the bug It is confirmed a bug, but don't worry, we'll handle it. label Mar 15, 2024
@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


It seems -a "Here are your customized parameters", you can run gf run -h to check it
1

@wln32
Copy link
Member

wln32 commented Mar 15, 2024

这个bug是在解析完参数给结构体字段赋值的时候导致的

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


This bug is caused when the parameters are parsed and assigned to the structure fields.

@wln32
Copy link
Member

wln32 commented Mar 15, 2024

我复测了几个BUG出来

首先这是我的代码

type Command struct {
	*gcmd.Command
}

var (
	Test = cTest{}
)

type cTest struct {
	g.Meta `name:"index" ad:"test"`
}

type cInput struct {
	g.Meta `name:"index"`
	Name   string `short:"n" name:"age" brief:"我是name字段"`
	Age    string `short:"a" name:"name" brief:"我是age字段"`
}

type cOutput struct{}

func (c cTest) Index(ctx context.Context, in cInput) (out *cOutput, err error) {
	g.Dump(in)
	return
}

func main() {
	root, err := gcmd.NewFromObject(Test)
	if err != nil {
		panic(err)
	}
	command := &Command{root}
	command.Run(gctx.GetInitCtx())
}

下面贴测试结果

q1
q2
q3
q5
q6
q7

@clh021
Copy link
Author

clh021 commented Mar 15, 2024

我刚刚进一步排查,确定了问题出在这一行代码中:
image
image
以下是输出,说明数据在经过这一行代码时,进行了赋值操作,部分数据成功获取,部分数据丢失。
image

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


I just investigated further and determined that the problem lies in this line of code:
image
image
The following is the output, which shows that when the data passes through this line of code, an assignment operation is performed, part of the data is successfully obtained, and part of the data is lost.
image

@wln32
Copy link
Member

wln32 commented Mar 15, 2024

你输入的数据是成功解析了的,问题就是出现在你红线标记哪里,再给字段赋值的时候,由于你tag的值和结构体字段重名了,导致错误解析

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The data you entered was parsed successfully. The problem is that when you assign a value to the field where the red line is marked, the value of your tag has the same name as the structure field, resulting in an incorrect parsing.

@clh021
Copy link
Author

clh021 commented Mar 16, 2024

你输入的数据是成功解析了的,问题就是出现在你红线标记哪里,再给字段赋值的时候,由于你tag的值和结构体字段重名了,导致错误解析

经过又一轮调试,发现:scan 赋值的部分,顺序可能没有严格按照参数名进行匹配。
我上面提的问题有两个,其中一个是 a 和 b 的 short 定义互换,但是结构体中的赋值没有换过来,但是刚刚发现,如果把结构体中的顺序 B 放在 A 前面,得到的值就正确了。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The data you entered was parsed successfully. The problem is that when you assign a value to the field where the red line is marked, the value of your tag has the same name as the structure field, resulting in an incorrect parsing.

After another round of debugging, I found that the order of the scan assignment may not be strictly matched according to the parameter names.
There are two problems I raised above. One of them is that the short definitions of a and b are interchanged, but the assignments in the structure are not exchanged. But I just discovered that if the order B in the structure is placed before A, we get The value is correct.

@wln32
Copy link
Member

wln32 commented Mar 16, 2024

你输入的数据是成功解析了的,问题就是出现在你红线标记哪里,再给字段赋值的时候,由于你tag的值和结构体字段重名了,导致错误解析

经过又一轮调试,发现:scan 赋值的部分,顺序可能没有严格按照参数名进行匹配。 我上面提的问题有两个,其中一个是 a 和 b 的 short 定义互换,但是结构体中的赋值没有换过来,但是刚刚发现,如果把结构体中的顺序 B 放在 A 前面,得到的值就正确了。

我正在试图重新实现这部分

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The data you entered has been parsed successfully. The problem is that it occurs where you marked the red line. When assigning values ​​to the fields, the value of your tag has the same name as the field of the structure, resulting in an incorrect parsing.

After another round of debugging, it was found that the order of the scan assignment may not be strictly matched according to the parameter name. There are two problems I raised above. One of them is that the short definitions of a and b are interchanged, but the assignments in the structure are not exchanged. But I just discovered that if the order B in the structure is placed before A, we get The value is correct.

I'm trying to reimplement this part

@clh021
Copy link
Author

clh021 commented Mar 16, 2024

以下是刚刚进一步精简出来的重现代码

package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

type cInput struct {
	A      string `short:"a" name:"aa" brief:"aa"`
	B      string `short:"b" name:"bb" brief:"bb"`
}

func main() {
	data := map[string]interface{}{
		"a":  "aaa",
		"aa": "bbb",
		"b":  "bbb",
		"bb": "aaa",
	}
	p := cInput{}
	err := gconv.Struct(data, &p)
	if err != nil {
		g.Dump(err)
	} else {
		g.Dump(p)
	}
}

原因可能找到了,(以上代码测试方法一样)
scan 函数本身也没有问题,问题在与 scan 转换时对应的是结构体的名称,而非 short 或 name。
所以应该在 command 和 scan 之间有一个 转换关系。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The following is the reproducible code that has just been further streamlined

package main

import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)

type cInput struct {
A string `short:"a" name:"aa" brief:"aa"`
B string `short:"b" name:"bb" brief:"bb"`
}

func main() {
data := map[string]interface{}{
"a": "aaa",
"aa": "bbb",
"b": "bbb",
"bb": "aaa",
}
p := cInput{}
err := gconv.Struct(data, &p)
if err != nil {
g.Dump(err)
} else {
g.Dump(p)
}
}

The reason may be found, (the above code test method is the same)
There is no problem with the scan function itself. The problem when converting with scan corresponds to the name of the structure, not short or name.
So there should be a conversion relationship between command and scan.

@clh021
Copy link
Author

clh021 commented Mar 16, 2024

你输入的数据是成功解析了的,问题就是出现在你红线标记哪里,再给字段赋值的时候,由于你tag的值和结构体字段重名了,导致错误解析

经过又一轮调试,发现:scan 赋值的部分,顺序可能没有严格按照参数名进行匹配。 我上面提的问题有两个,其中一个是 a 和 b 的 short 定义互换,但是结构体中的赋值没有换过来,但是刚刚发现,如果把结构体中的顺序 B 放在 A 前面,得到的值就正确了。

我正在试图重新实现这部分

您是框架核心开发者吗?我本想尝试提交 PR,但是对 gogf 的内部结构还不够熟悉,很多地方不清楚为什么那样实现,不敢改动。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The data you entered was parsed successfully. The problem is that the red line mark appears. When you assign a value to the field, the value of your tag has the same name as the structure field, resulting in an incorrect parsing.

After another round of debugging, we found that the order of the scan assignment may not be strictly matched according to the parameter names. There are two problems I mentioned above. One of them is that the short definitions of a and b are interchanged, but the assignments in the structure are not exchanged. But I just discovered that if the order B in the structure is placed before A, we get The value is correct.

I'm trying to reimplement this part

Are you a framework core developer? I wanted to try submitting a PR, but I was not familiar enough with the internal structure of gogf. I didn’t know why it was implemented that way in many places, and I didn’t dare to change it.

@wln32
Copy link
Member

wln32 commented Mar 16, 2024

以下是刚刚进一步精简出来的重现代码

package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

type cInput struct {
	A      string `short:"a" name:"aa" brief:"aa"`
	B      string `short:"b" name:"bb" brief:"bb"`
}

func main() {
	data := map[string]interface{}{
		"a":  "aaa",
		"aa": "bbb",
		"b":  "bbb",
		"bb": "aaa",
	}
	p := cInput{}
	err := gconv.Struct(data, &p)
	if err != nil {
		g.Dump(err)
	} else {
		g.Dump(p)
	}
}

原因可能找到了,(以上代码测试方法一样) scan 函数本身也没有问题,问题在与 scan 转换时对应的是结构体的名称,而非 short 或 name。 所以应该在 command 和 scan 之间有一个 转换关系。

具体的实现

你输入的数据是成功解析了的,问题就是出现在你红线标记哪里,再给字段赋值的时候,由于你tag的值和结构体字段重名了,导致错误解析

经过又一轮调试,发现:scan 赋值的部分,顺序可能没有严格按照参数名进行匹配。 我上面提的问题有两个,其中一个是 a 和 b 的 short 定义互换,但是结构体中的赋值没有换过来,但是刚刚发现,如果把结构体中的顺序 B 放在 A 前面,得到的值就正确了。

我正在试图重新实现这部分

您是框架核心开发者吗?我本想尝试提交 PR,但是对 gogf 的内部结构还不够熟悉,很多地方不清楚为什么那样实现,不敢改动。

我跟你一样呢,不是核心开发者,只是无聊学习下而已,我目前已经实现的差不多了已经,测试用例都能跑过

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


The following is the reproduced code that has just been further streamlined

package main

import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)

type cInput struct {
A string `short:"a" name:"aa" brief:"aa"`
B string `short:"b" name:"bb" brief:"bb"`
}

func main() {
data := map[string]interface{}{
"a": "aaa",
"aa": "bbb",
"b": "bbb",
"bb": "aaa",
}
p := cInput{}
err := gconv.Struct(data, &p)
if err != nil {
g.Dump(err)
} else {
g.Dump(p)
}
}

The reason may be found. (The above code test method is the same) There is no problem with the scan function itself. The problem corresponds to the name of the structure when converting with scan, not short or name. So there should be a conversion relationship between command and scan.

specific implementation

The data you entered has been parsed successfully. The problem is that the red line mark appears. When you assign a value to the field, the value of your tag has the same name as the structure field, resulting in an incorrect parsing.

After another round of debugging, we found that the order of the scan assignment may not be strictly matched according to the parameter name. There are two problems I raised above. One of them is that the short definitions of a and b are interchanged, but the assignments in the structure are not exchanged. But I just discovered that if the order B in the structure is placed before A, we get The value is correct.

I'm trying to reimplement this part

Are you a framework core developer? I wanted to try submitting a PR, but I was not familiar enough with the internal structure of gogf. I didn’t know why it was implemented that way in many places, and I didn’t dare to change it.

I'm just like you. I'm not a core developer. I'm just learning out of boredom. I've implemented almost everything so far, and I can run all the test cases.

@clh021
Copy link
Author

clh021 commented Mar 16, 2024

我跟你一样呢,不是核心开发者,只是无聊学习下而已,我目前已经实现的差不多了已经,测试用例都能跑过

测试用例可能需要再针对新的补充一点,把这次的问题发现都包含进去。感谢您帮助我一起发现了这个问题!👍

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


I'm just like you, not a core developer, just learning out of boredom. I've implemented almost everything so far, and I can run all the test cases.

The test cases may need to be supplemented with new ones to include all the problems discovered this time. Thanks for helping me figure this out! 👍

@clh021
Copy link
Author

clh021 commented Mar 26, 2024

我目前是通过为所有参数附上默认值来避开这个问题的。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


I currently get around this problem by attaching default values ​​to all parameters.

@gqcn
Copy link
Member

gqcn commented Mar 26, 2024

我看看呢。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Let me take a look.

gqcn added a commit that referenced this issue Mar 26, 2024
@gqcn
Copy link
Member

gqcn commented Mar 26, 2024

#3429

@gqcn gqcn added the done This issue is done, which may be release in next version. label Mar 26, 2024
@gqcn gqcn closed this as completed Mar 26, 2024
gqcn added a commit that referenced this issue Apr 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug It is confirmed a bug, but don't worry, we'll handle it. done This issue is done, which may be release in next version.
Projects
None yet
Development

No branches or pull requests

4 participants