Skip to content

Commit

Permalink
forge: Add MarshalChangeID/UnmarshalChangeID (#521)
Browse files Browse the repository at this point in the history
Add a means for forges to serialize and deserialize just their ChangeIDs
without any other change metadata.

This will be used by #508.
  • Loading branch information
abhinav authored Dec 20, 2024
1 parent b1932d1 commit 28d0458
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 6 deletions.
6 changes: 6 additions & 0 deletions internal/forge/forge.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ type Forge interface {
// it's possible to define change templates in the repository.
ChangeTemplatePaths() []string

// MarshalChangeID serializes the given change ID into a valid JSON blob.
MarshalChangeID(ChangeID) (json.RawMessage, error)

// UnmarshalChangeID deserializes the given JSON blob into a change ID.
UnmarshalChangeID(json.RawMessage) (ChangeID, error)

// MarshalChangeMetadata serializes the given change metadata
// into a valid JSON blob.
MarshalChangeMetadata(ChangeMetadata) (json.RawMessage, error)
Expand Down
78 changes: 78 additions & 0 deletions internal/forge/forgetest/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions internal/forge/github/change_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ func (*Forge) UnmarshalChangeMetadata(data json.RawMessage) (forge.ChangeMetadat
return &md, nil
}

// MarshalChangeID serializes a PR into JSON.
func (*Forge) MarshalChangeID(cid forge.ChangeID) (json.RawMessage, error) {
return json.Marshal(mustPR(cid))
}

// UnmarshalChangeID deserializes a PR from JSON.
func (*Forge) UnmarshalChangeID(data json.RawMessage) (forge.ChangeID, error) {
var pr PR
if err := json.Unmarshal(data, &pr); err != nil {
return nil, fmt.Errorf("unmarshal PR: %w", err)
}
return &pr, nil
}

// PR uniquely identifies a PR in a GitHub repository.
// It's a valid forge.ChangeID.
type PR struct {
Expand Down
32 changes: 29 additions & 3 deletions internal/forge/github/change_meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ func TestPRString(t *testing.T) {
}).String())
}

func TestPRMarshal(t *testing.T) {
tests := []struct {
name string
give PR
want string
}{
{
name: "NumberOnly",
give: PR{Number: 42},
want: `{"number": 42}`,
},
{
name: "NumberAndGQLID",
give: PR{Number: 42, GQLID: "foo"},
want: `{"number": 42, "gqlID": "foo"}`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := new(Forge).MarshalChangeID(&tt.give)
require.NoError(t, err)
assert.JSONEq(t, tt.want, string(got))
})
}
}

func TestPRUnmarshal(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -57,16 +84,15 @@ func TestPRUnmarshal(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var pr PR
err := json.Unmarshal([]byte(tt.give), &pr)
pr, err := new(Forge).UnmarshalChangeID(json.RawMessage(tt.give))
if tt.wantErr != "" {
require.Error(t, err)
assert.ErrorContains(t, err, tt.wantErr)
return
}

require.NoError(t, err)
assert.Equal(t, tt.want, pr)
assert.Equal(t, &tt.want, pr)
})
}
}
Expand Down
14 changes: 14 additions & 0 deletions internal/forge/gitlab/change_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ func (*Forge) UnmarshalChangeMetadata(data json.RawMessage) (forge.ChangeMetadat
return &md, nil
}

// MarshalChangeID serializes a MR into JSON.
func (*Forge) MarshalChangeID(id forge.ChangeID) (json.RawMessage, error) {
return json.Marshal(mustMR(id))
}

// UnmarshalChangeID deserializes a MR from JSON.
func (*Forge) UnmarshalChangeID(data json.RawMessage) (forge.ChangeID, error) {
var id MR
if err := json.Unmarshal(data, &id); err != nil {
return nil, fmt.Errorf("unmarshal MR ID: %w", err)
}
return &id, nil
}

// MR uniquely identifies a Merge Request in GitLab.
// It's a valid forge.ChangeID.
type MR struct {
Expand Down
27 changes: 24 additions & 3 deletions internal/forge/gitlab/change_meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@ func TestMRString(t *testing.T) {
}).String())
}

func TestMRMarshal(t *testing.T) {
tests := []struct {
name string
give MR
want string
}{
{
name: "NumberOnly",
give: MR{Number: 42},
want: `{"number": 42}`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := new(Forge).MarshalChangeID(&tt.give)
require.NoError(t, err)
assert.JSONEq(t, tt.want, string(got))
})
}
}

func TestMRUnmarshal(t *testing.T) {
tests := []struct {
name string
Expand All @@ -70,16 +92,15 @@ func TestMRUnmarshal(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var pr MR
err := json.Unmarshal([]byte(tt.give), &pr)
pr, err := new(Forge).UnmarshalChangeID(json.RawMessage(tt.give))
if tt.wantErr != "" {
require.Error(t, err)
assert.ErrorContains(t, err, tt.wantErr)
return
}

require.NoError(t, err)
assert.Equal(t, tt.want, pr)
assert.Equal(t, &tt.want, pr)
})
}
}
Expand Down
14 changes: 14 additions & 0 deletions internal/forge/shamhub/change_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,17 @@ func (f *Forge) UnmarshalChangeMetadata(data json.RawMessage) (forge.ChangeMetad
}
return &md, nil
}

// MarshalChangeID marshals the given change ID to JSON.
func (f *Forge) MarshalChangeID(id forge.ChangeID) (json.RawMessage, error) {
return json.Marshal(id.(ChangeID))
}

// UnmarshalChangeID unmarshals the given JSON data to change ID.
func (f *Forge) UnmarshalChangeID(data json.RawMessage) (forge.ChangeID, error) {
var id ChangeID
if err := json.Unmarshal(data, &id); err != nil {
return nil, fmt.Errorf("unmarshal change ID: %w", err)
}
return id, nil
}

0 comments on commit 28d0458

Please sign in to comment.