diff options
Diffstat (limited to 'plumbing')
-rw-r--r-- | plumbing/protocol/packp/report_status.go | 29 | ||||
-rw-r--r-- | plumbing/protocol/packp/report_status_test.go | 19 | ||||
-rw-r--r-- | plumbing/transport/internal/common/common.go | 4 | ||||
-rw-r--r-- | plumbing/transport/test/send_pack.go | 53 |
4 files changed, 80 insertions, 25 deletions
diff --git a/plumbing/protocol/packp/report_status.go b/plumbing/protocol/packp/report_status.go index ead4bb6..29c1a4c 100644 --- a/plumbing/protocol/packp/report_status.go +++ b/plumbing/protocol/packp/report_status.go @@ -26,9 +26,19 @@ func NewReportStatus() *ReportStatus { return &ReportStatus{} } -// Ok returns true if the report status reported no error. -func (s *ReportStatus) Ok() bool { - return s.UnpackStatus == ok +// Error returns the first error if any. +func (s *ReportStatus) Error() error { + if s.UnpackStatus != ok { + return fmt.Errorf("unpack error: %s", s.UnpackStatus) + } + + for _, s := range s.CommandStatuses { + if err := s.Error(); err != nil { + return err + } + } + + return nil } // Encode writes the report status to a writer. @@ -135,14 +145,19 @@ type CommandStatus struct { Status string } -// Ok returns true if the command status reported no error. -func (s *CommandStatus) Ok() bool { - return s.Status == ok +// Error returns the error, if any. +func (s *CommandStatus) Error() error { + if s.Status == ok { + return nil + } + + return fmt.Errorf("command error on %s: %s", + s.ReferenceName.String(), s.Status) } func (s *CommandStatus) encode(w io.Writer) error { e := pktline.NewEncoder(w) - if s.Ok() { + if s.Error() == nil { return e.Encodef("ok %s\n", s.ReferenceName.String()) } diff --git a/plumbing/protocol/packp/report_status_test.go b/plumbing/protocol/packp/report_status_test.go index 168d25b..1c3fa81 100644 --- a/plumbing/protocol/packp/report_status_test.go +++ b/plumbing/protocol/packp/report_status_test.go @@ -13,22 +13,25 @@ type ReportStatusSuite struct{} var _ = Suite(&ReportStatusSuite{}) -func (s *ReportStatusSuite) TestOk(c *C) { +func (s *ReportStatusSuite) TestError(c *C) { rs := NewReportStatus() rs.UnpackStatus = "ok" - c.Assert(rs.Ok(), Equals, true) + c.Assert(rs.Error(), IsNil) rs.UnpackStatus = "OK" - c.Assert(rs.Ok(), Equals, false) + c.Assert(rs.Error(), ErrorMatches, "unpack error: OK") rs.UnpackStatus = "" - c.Assert(rs.Ok(), Equals, false) + c.Assert(rs.Error(), ErrorMatches, "unpack error: ") + + cs := &CommandStatus{ReferenceName: plumbing.ReferenceName("ref")} + rs.UnpackStatus = "ok" + rs.CommandStatuses = append(rs.CommandStatuses, cs) - cs := &CommandStatus{} cs.Status = "ok" - c.Assert(cs.Ok(), Equals, true) + c.Assert(rs.Error(), IsNil) cs.Status = "OK" - c.Assert(cs.Ok(), Equals, false) + c.Assert(rs.Error(), ErrorMatches, "command error on ref: OK") cs.Status = "" - c.Assert(cs.Ok(), Equals, false) + c.Assert(rs.Error(), ErrorMatches, "command error on ref: ") } func (s *ReportStatusSuite) testEncodeDecodeOk(c *C, rs *ReportStatus, lines ...string) { diff --git a/plumbing/transport/internal/common/common.go b/plumbing/transport/internal/common/common.go index f6d1249..17c473e 100644 --- a/plumbing/transport/internal/common/common.go +++ b/plumbing/transport/internal/common/common.go @@ -281,8 +281,8 @@ func (s *session) SendPack(req *packp.ReferenceUpdateRequest) (*packp.ReportStat return nil, err } - if !report.Ok() { - return report, fmt.Errorf("report status: %s", report.UnpackStatus) + if err := report.Error(); err != nil { + return report, err } return report, s.Command.Wait() diff --git a/plumbing/transport/test/send_pack.go b/plumbing/transport/test/send_pack.go index 8cb549d..f880588 100644 --- a/plumbing/transport/test/send_pack.go +++ b/plumbing/transport/test/send_pack.go @@ -131,7 +131,7 @@ func (s *SendPackSuite) TestFullSendPackOnNonEmpty(c *C) { fixture := fixtures.Basic().ByTag("packfile").One() req := packp.NewReferenceUpdateRequest() req.Commands = []*packp.Command{ - {"refs/heads/master", plumbing.ZeroHash, fixture.Head}, + {"refs/heads/master", fixture.Head, fixture.Head}, } s.sendPack(c, endpoint, req, fixture, full) s.checkRemoteHead(c, endpoint, fixture.Head) @@ -143,7 +143,7 @@ func (s *SendPackSuite) TestSendPackOnNonEmpty(c *C) { fixture := fixtures.Basic().ByTag("packfile").One() req := packp.NewReferenceUpdateRequest() req.Commands = []*packp.Command{ - {"refs/heads/master", plumbing.ZeroHash, fixture.Head}, + {"refs/heads/master", fixture.Head, fixture.Head}, } s.sendPack(c, endpoint, req, fixture, full) s.checkRemoteHead(c, endpoint, fixture.Head) @@ -155,7 +155,7 @@ func (s *SendPackSuite) TestSendPackOnNonEmptyWithReportStatus(c *C) { fixture := fixtures.Basic().ByTag("packfile").One() req := packp.NewReferenceUpdateRequest() req.Commands = []*packp.Command{ - {"refs/heads/master", plumbing.ZeroHash, fixture.Head}, + {"refs/heads/master", fixture.Head, fixture.Head}, } req.Capabilities.Set(capability.ReportStatus) @@ -163,10 +163,30 @@ func (s *SendPackSuite) TestSendPackOnNonEmptyWithReportStatus(c *C) { s.checkRemoteHead(c, endpoint, fixture.Head) } -func (s *SendPackSuite) sendPack(c *C, ep transport.Endpoint, - req *packp.ReferenceUpdateRequest, fixture *fixtures.Fixture, - callAdvertisedReferences bool) { +func (s *SendPackSuite) TestSendPackOnNonEmptyWithReportStatusWithError(c *C) { + endpoint := s.Endpoint + full := false + fixture := fixtures.Basic().ByTag("packfile").One() + req := packp.NewReferenceUpdateRequest() + req.Commands = []*packp.Command{ + {"refs/heads/master", plumbing.ZeroHash, fixture.Head}, + } + req.Capabilities.Set(capability.ReportStatus) + + report, err := s.sendPackNoCheck(c, endpoint, req, fixture, full) + //XXX: Recent git versions return "failed to update ref", while older + // (>=1.9) return "failed to lock". + c.Assert(err, ErrorMatches, ".*(failed to update ref|failed to lock).*") + c.Assert(report.UnpackStatus, Equals, "ok") + c.Assert(len(report.CommandStatuses), Equals, 1) + c.Assert(report.CommandStatuses[0].ReferenceName, Equals, plumbing.ReferenceName("refs/heads/master")) + c.Assert(report.CommandStatuses[0].Status, Matches, "(failed to update ref|failed to lock)") + s.checkRemoteHead(c, endpoint, fixture.Head) +} +func (s *SendPackSuite) sendPackNoCheck(c *C, ep transport.Endpoint, + req *packp.ReferenceUpdateRequest, fixture *fixtures.Fixture, + callAdvertisedReferences bool) (*packp.ReportStatus, error) { url := "" if fixture != nil { url = fixture.URL @@ -193,11 +213,28 @@ func (s *SendPackSuite) sendPack(c *C, ep transport.Endpoint, req.Packfile = s.emptyPackfile() } - report, err := r.SendPack(req) + return r.SendPack(req) +} + +func (s *SendPackSuite) sendPack(c *C, ep transport.Endpoint, + req *packp.ReferenceUpdateRequest, fixture *fixtures.Fixture, + callAdvertisedReferences bool) { + + url := "" + if fixture != nil { + url = fixture.URL + } + + comment := Commentf( + "failed with ep=%s fixture=%s callAdvertisedReferences=%s", + ep.String(), url, callAdvertisedReferences, + ) + report, err := s.sendPackNoCheck(c, ep, req, fixture, callAdvertisedReferences) + c.Assert(err, IsNil, comment) if req.Capabilities.Supports(capability.ReportStatus) { c.Assert(report, NotNil, comment) - c.Assert(report.Ok(), Equals, true, comment) + c.Assert(report.Error(), IsNil, comment) } else { c.Assert(report, IsNil, comment) } |