diff --git a/cmd/gf/internal/cmd/cmd_z_unit_gen_pb_test.go b/cmd/gf/internal/cmd/cmd_z_unit_gen_pb_test.go index f1ec5be5cbc..0f9e0913733 100644 --- a/cmd/gf/internal/cmd/cmd_z_unit_gen_pb_test.go +++ b/cmd/gf/internal/cmd/cmd_z_unit_gen_pb_test.go @@ -48,3 +48,42 @@ func TestGenPbIssue3882(t *testing.T) { t.Assert(gstr.Contains(genContent, exceptText), true) }) } + +// This issue only occurs when executing multiple times +// and the subsequent OutputApi is the parent directory of the previous execution +func TestGenPbIssue3953(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + var ( + outputPath = gfile.Temp(guid.S()) + outputApiPath = filepath.Join(outputPath, "api") + outputCtrlPath = filepath.Join(outputPath, "controller") + + protobufFolder = gtest.DataPath("issue", "3953") + in = genpb.CGenPbInput{ + Path: protobufFolder, + OutputApi: outputApiPath, + OutputCtrl: outputCtrlPath, + } + err error + ) + err = gfile.Mkdir(outputApiPath) + t.AssertNil(err) + err = gfile.Mkdir(outputCtrlPath) + t.AssertNil(err) + defer gfile.Remove(outputPath) + + _, err = genpb.CGenPb{}.Pb(ctx, in) + // do twice,and set outputApi to outputPath + in.OutputApi = outputPath + _, err = genpb.CGenPb{}.Pb(ctx, in) + t.AssertNil(err) + + var ( + genContent = gfile.GetContents(filepath.Join(outputApiPath, "issue3953.pb.go")) + // The old version would have appeared `v:"required" v:"required"` + // but the new version of the code will appear `v:"required"` only once + notExceptText = `v:"required" v:"required"` + ) + t.Assert(gstr.Contains(genContent, notExceptText), false) + }) +} diff --git a/cmd/gf/internal/cmd/genpb/genpb_tag.go b/cmd/gf/internal/cmd/genpb/genpb_tag.go index f8cfad7e5b8..ac74e28ebce 100644 --- a/cmd/gf/internal/cmd/genpb/genpb_tag.go +++ b/cmd/gf/internal/cmd/genpb/genpb_tag.go @@ -71,6 +71,10 @@ func (c CGenPb) doTagReplacement(ctx context.Context, content string) (string, e if !lineTagMap.IsEmpty() { tagContent := c.listMapToStructTag(lineTagMap) lineTagMap.Clear() + // If already have it, don't add it anymore + if gstr.Contains(gstr.StrTill(line, "` //"), tagContent) { + continue + } line, _ = gregex.ReplaceString("`(.+)`", fmt.Sprintf("`$1 %s`", tagContent), line) } lines[index] = line diff --git a/cmd/gf/internal/cmd/testdata/issue/3953/issue3953.proto b/cmd/gf/internal/cmd/testdata/issue/3953/issue3953.proto new file mode 100644 index 00000000000..8bc86fba1f7 --- /dev/null +++ b/cmd/gf/internal/cmd/testdata/issue/3953/issue3953.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package account; + +option go_package = "account/v1"; + +service Account { + rpc getUserByIds (Req) returns (Resp) { + } +} + +message Req { + repeated int64 ids = 1; // v: required +} +message Resp { + repeated string data = 1; +}