From 3a4b9149b94b9b43243fd0b1580625514f7670ee Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 8 Mar 2026 01:36:31 +0800 Subject: protocol/v0v1/server/receivepack: Fix report-status --- protocol/v0v1/server/receivepack/report_status.go | 183 +++++++++++++++++++++ .../v0v1/server/receivepack/report_status_test.go | 34 +++- protocol/v0v1/server/receivepack/session.go | 86 ---------- 3 files changed, 210 insertions(+), 93 deletions(-) create mode 100644 protocol/v0v1/server/receivepack/report_status.go diff --git a/protocol/v0v1/server/receivepack/report_status.go b/protocol/v0v1/server/receivepack/report_status.go new file mode 100644 index 00000000..75298f85 --- /dev/null +++ b/protocol/v0v1/server/receivepack/report_status.go @@ -0,0 +1,183 @@ +package receivepack + +import ( + "fmt" + + "codeberg.org/lindenii/furgit/format/pktline" +) + +// WriteReportStatus writes one classic report-status response. +func (session *Session) WriteReportStatus(result ReportStatusResult) error { + unpackResult := "ok" + if result.UnpackError != "" { + unpackResult = result.UnpackError + } + + if !session.negotiated.SideBand64K { + err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult)) + if err != nil { + return err + } + + for _, command := range result.Commands { + line := fmt.Sprintf("ok %s\n", command.Name) + if command.Error != "" { + line = fmt.Sprintf("ng %s %s\n", command.Name, command.Error) + } + + err = session.base.WriteData([]byte(line)) + if err != nil { + return err + } + } + + return session.base.WriteFlush() + } + + buf, err := pktline.AppendData(nil, fmt.Appendf(nil, "unpack %s\n", unpackResult)) + if err != nil { + return err + } + + for _, command := range result.Commands { + line := fmt.Sprintf("ok %s\n", command.Name) + if command.Error != "" { + line = fmt.Sprintf("ng %s %s\n", command.Name, command.Error) + } + + buf, err = pktline.AppendData(buf, []byte(line)) + if err != nil { + return err + } + } + + buf = pktline.AppendFlushPkt(buf) + + w := session.base.PrimaryDataWriter() + _, err = w.Write(buf) + if err != nil { + return err + } + + return session.base.WriteFlush() +} + +// WriteReportStatusV2 writes one report-status-v2 response. +func (session *Session) WriteReportStatusV2(result ReportStatusResult) error { + unpackResult := "ok" + if result.UnpackError != "" { + unpackResult = result.UnpackError + } + + if !session.negotiated.SideBand64K { + err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult)) + if err != nil { + return err + } + + for _, command := range result.Commands { + if command.Error != "" { + err = session.base.WriteData(fmt.Appendf(nil, "ng %s %s\n", command.Name, command.Error)) + if err != nil { + return err + } + + continue + } + + err = session.base.WriteData(fmt.Appendf(nil, "ok %s\n", command.Name)) + if err != nil { + return err + } + + if command.RefName != "" { + err = session.base.WriteData(fmt.Appendf(nil, "option refname %s\n", command.RefName)) + if err != nil { + return err + } + } + + if command.OldID != nil { + err = session.base.WriteData(fmt.Appendf(nil, "option old-oid %s\n", *command.OldID)) + if err != nil { + return err + } + } + + if command.NewID != nil { + err = session.base.WriteData(fmt.Appendf(nil, "option new-oid %s\n", *command.NewID)) + if err != nil { + return err + } + } + + if command.ForcedUpdate { + err = session.base.WriteData([]byte("option forced-update\n")) + if err != nil { + return err + } + } + } + + return session.base.WriteFlush() + } + + buf, err := pktline.AppendData(nil, fmt.Appendf(nil, "unpack %s\n", unpackResult)) + if err != nil { + return err + } + + for _, command := range result.Commands { + if command.Error != "" { + buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "ng %s %s\n", command.Name, command.Error)) + if err != nil { + return err + } + + continue + } + + buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "ok %s\n", command.Name)) + if err != nil { + return err + } + + if command.RefName != "" { + buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "option refname %s\n", command.RefName)) + if err != nil { + return err + } + } + + if command.OldID != nil { + buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "option old-oid %s\n", *command.OldID)) + if err != nil { + return err + } + } + + if command.NewID != nil { + buf, err = pktline.AppendData(buf, fmt.Appendf(nil, "option new-oid %s\n", *command.NewID)) + if err != nil { + return err + } + } + + if command.ForcedUpdate { + buf, err = pktline.AppendData(buf, []byte("option forced-update\n")) + if err != nil { + return err + } + } + } + + buf = pktline.AppendFlushPkt(buf) + + w := session.base.PrimaryDataWriter() + _, err = w.Write(buf) + if err != nil { + return err + } + + return session.base.WriteFlush() +} diff --git a/protocol/v0v1/server/receivepack/report_status_test.go b/protocol/v0v1/server/receivepack/report_status_test.go index fa76a85b..605ab1d0 100644 --- a/protocol/v0v1/server/receivepack/report_status_test.go +++ b/protocol/v0v1/server/receivepack/report_status_test.go @@ -101,26 +101,46 @@ func TestWriteReportStatusUsesSideBand64KWhenNegotiated(t *testing.T) { t.Fatalf("ReadFrame(unpack): %v", err) } - if frame.Type != sideband64k.FrameData || string(frame.Payload) != "unpack ok\n" { + if frame.Type != sideband64k.FrameData { t.Fatalf("first frame = %#v", frame) } - frame, err = dec.ReadFrame() + statusDec := pktline.NewDecoder(strings.NewReader(string(frame.Payload)), pktline.ReadOptions{}) + + statusFrame, err := statusDec.ReadFrame() + if err != nil { + t.Fatalf("ReadFrame(unpack status): %v", err) + } + + if statusFrame.Type != pktline.PacketData || string(statusFrame.Payload) != "unpack ok\n" { + t.Fatalf("first status frame = %#v", statusFrame) + } + + statusFrame, err = statusDec.ReadFrame() + if err != nil { + t.Fatalf("ReadFrame(ok status): %v", err) + } + + if statusFrame.Type != pktline.PacketData || string(statusFrame.Payload) != "ok refs/heads/main\n" { + t.Fatalf("second status frame = %#v", statusFrame) + } + + statusFrame, err = statusDec.ReadFrame() if err != nil { - t.Fatalf("ReadFrame(ok): %v", err) + t.Fatalf("ReadFrame(status flush): %v", err) } - if frame.Type != sideband64k.FrameData || string(frame.Payload) != "ok refs/heads/main\n" { - t.Fatalf("second frame = %#v", frame) + if statusFrame.Type != pktline.PacketFlush { + t.Fatalf("status flush frame.Type = %v, want FrameFlush", statusFrame.Type) } frame, err = dec.ReadFrame() if err != nil { - t.Fatalf("ReadFrame(flush): %v", err) + t.Fatalf("ReadFrame(outer flush): %v", err) } if frame.Type != sideband64k.FrameFlush { - t.Fatalf("flush frame.Type = %v, want FrameFlush", frame.Type) + t.Fatalf("outer flush frame.Type = %v, want FrameFlush", frame.Type) } }) } diff --git a/protocol/v0v1/server/receivepack/session.go b/protocol/v0v1/server/receivepack/session.go index 8682c8e5..b8c4a7dd 100644 --- a/protocol/v0v1/server/receivepack/session.go +++ b/protocol/v0v1/server/receivepack/session.go @@ -159,92 +159,6 @@ afterPushOptions: return req, nil } -// WriteReportStatus writes one classic report-status response. -func (session *Session) WriteReportStatus(result ReportStatusResult) error { - unpackResult := "ok" - if result.UnpackError != "" { - unpackResult = result.UnpackError - } - - err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult)) - if err != nil { - return err - } - - for _, command := range result.Commands { - line := fmt.Sprintf("ok %s\n", command.Name) - if command.Error != "" { - line = fmt.Sprintf("ng %s %s\n", command.Name, command.Error) - } - - err = session.base.WriteData([]byte(line)) - if err != nil { - return err - } - } - - return session.base.WriteFlush() -} - -// WriteReportStatusV2 writes one report-status-v2 response. -func (session *Session) WriteReportStatusV2(result ReportStatusResult) error { - unpackResult := "ok" - if result.UnpackError != "" { - unpackResult = result.UnpackError - } - - err := session.base.WriteData(fmt.Appendf(nil, "unpack %s\n", unpackResult)) - if err != nil { - return err - } - - for _, command := range result.Commands { - if command.Error != "" { - err = session.base.WriteData(fmt.Appendf(nil, "ng %s %s\n", command.Name, command.Error)) - if err != nil { - return err - } - - continue - } - - err = session.base.WriteData(fmt.Appendf(nil, "ok %s\n", command.Name)) - if err != nil { - return err - } - - if command.RefName != "" { - err = session.base.WriteData(fmt.Appendf(nil, "option refname %s\n", command.RefName)) - if err != nil { - return err - } - } - - if command.OldID != nil { - err = session.base.WriteData(fmt.Appendf(nil, "option old-oid %s\n", *command.OldID)) - if err != nil { - return err - } - } - - if command.NewID != nil { - err = session.base.WriteData(fmt.Appendf(nil, "option new-oid %s\n", *command.NewID)) - if err != nil { - return err - } - } - - if command.ForcedUpdate { - err = session.base.WriteData([]byte("option forced-update\n")) - if err != nil { - return err - } - } - } - - return session.base.WriteFlush() -} - // WriteProgress writes one progress packet. func (session *Session) WriteProgress(p []byte) error { return session.base.WriteProgress(p) -- cgit v1.3.1-10-gc9f91