Skip to content

Commit 336502b

Browse files
Add tags and signatures to Git predicate
1 parent 0171fa3 commit 336502b

File tree

2 files changed

+121
-28
lines changed

2 files changed

+121
-28
lines changed

attest/manifest/manifest.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"cmp"
55

66
"github.com/errordeveloper/tape/attest/types"
7+
attestTypes "github.com/errordeveloper/tape/attest/types"
78
)
89

910
const (
10-
ManifestDirPredicateType = "docker.com/tape/ManifestDir/v0.1"
11+
ManifestDirPredicateType = "docker.com/tape/ManifestDir/v0.2"
1112
)
1213

1314
var (

attest/vcs/git/git.go

Lines changed: 119 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,35 @@ type (
4444
}
4545

4646
GitSummary struct {
47-
ObjectHash *string `json:"objectHash,omitempty"`
48-
Remotes map[string][]string `json:"remotes,omitempty"`
49-
Reference GitReference `json:"reference,omitempty"`
47+
Object GitObject `json:"object,omitempty"`
48+
Remotes map[string][]string `json:"remotes,omitempty"`
49+
Reference GitReference `json:"reference,omitempty"`
50+
}
51+
52+
GitObject struct {
53+
TreeHash string `json:"treeHash,omitempty"`
54+
CommitHash string `json:"commitHash,omitempty"`
55+
}
56+
57+
Signature struct {
58+
PGP []byte `json:"pgp"`
59+
Validated bool `json:"validated"`
60+
}
61+
62+
GitTag struct {
63+
Name string `json:"name"`
64+
Hash string `json:"hash,omitempty"`
65+
Target string `json:"target,omitempty"`
66+
Signature *Signature `json:"signature,omitempty"`
5067
}
5168

5269
GitReference struct {
53-
Name string `json:"name,omitempty"`
54-
Hash string `json:"hash,omitempty"`
55-
Type string `json:"type,omitempty"`
56-
Target string `json:"target,omitempty"`
70+
Name string `json:"name,omitempty"`
71+
Hash string `json:"hash,omitempty"`
72+
Type string `json:"type,omitempty"`
73+
Target string `json:"target,omitempty"`
74+
Tags []GitTag `json:"tags,omitempty"`
75+
Signature *Signature `json:"signature,omitempty"`
5776
}
5877
)
5978

@@ -139,19 +158,101 @@ func (c *PathChecker) MakeSummary() (types.PathCheckSummary, error) {
139158
Git: &git,
140159
}
141160

142-
// TODO: determine position of local branch against remote
143-
// TODO: introduce notion of primary remote branch to determine the possition of the working branch
144-
// TODO: determine if a tag is used
145-
// TODO: also check if local tag in sync wirth remote tag
146-
// TODO: provide info on singed tags/commits
161+
head, err := c.cache.repo.Head()
162+
if err != nil {
163+
return nil, err
164+
}
147165

166+
ref := GitReference{
167+
Name: head.Name().String(),
168+
Hash: head.Hash().String(),
169+
Type: head.Type().String(),
170+
Target: head.Target().String(),
171+
}
172+
173+
obj := &GitObject{}
148174
if summary.Unmodified {
149-
git.ObjectHash = new(string)
150-
*git.ObjectHash = c.cache.obj.ID().String()
175+
obj.TreeHash = c.cache.obj.ID().String()
151176
} else if c.IsBlob() {
152177
// there is currently no easy way to obtain a hash for a subtree
153-
git.ObjectHash = new(string)
154-
*git.ObjectHash = c.cache.blobHash
178+
obj.TreeHash = c.cache.blobHash
179+
}
180+
181+
headCommit, err := c.cache.repo.CommitObject(head.Hash())
182+
if err != nil {
183+
return nil, err
184+
}
185+
if headCommit.PGPSignature != "" {
186+
ref.Signature = &Signature{
187+
PGP: []byte(headCommit.PGPSignature),
188+
Validated: false,
189+
}
190+
}
191+
192+
if summary.Unmodified {
193+
commitIter := object.NewCommitPathIterFromIter(
194+
func(path string) bool {
195+
switch {
196+
case c.IsTree():
197+
return strings.HasPrefix(c.cache.repoPath, path)
198+
case c.IsBlob():
199+
return c.cache.repoPath == path
200+
default:
201+
return false
202+
}
203+
},
204+
object.NewCommitIterCTime(headCommit, nil, nil),
205+
true,
206+
)
207+
defer commitIter.Close()
208+
// only need first commit, avoid looping over all commits with ForEach
209+
commit, err := commitIter.Next()
210+
if err == nil {
211+
obj.CommitHash = commit.Hash.String()
212+
} else if err != io.EOF {
213+
return nil, err
214+
}
215+
}
216+
217+
tags, err := c.cache.repo.Tags()
218+
if err != nil {
219+
return nil, err
220+
}
221+
222+
if err := tags.ForEach(func(t *plumbing.Reference) error {
223+
target, err := c.cache.repo.ResolveRevision(plumbing.Revision(t.Name()))
224+
if err != nil {
225+
return err
226+
}
227+
if *target != head.Hash() {
228+
// doesn't point to HEAD
229+
return nil
230+
}
231+
232+
tag := GitTag{
233+
Name: t.Name().Short(),
234+
Hash: t.Hash().String(),
235+
Target: target.String(),
236+
}
237+
238+
if tag.Target != tag.Hash {
239+
// annotated tags have own object hash, while has of a leightweight tag is the same as target
240+
tagObject, err := c.cache.repo.TagObject(t.Hash())
241+
if err != nil {
242+
return err
243+
}
244+
if tagObject.PGPSignature != "" {
245+
tag.Signature = &Signature{
246+
PGP: []byte(tagObject.PGPSignature),
247+
Validated: false,
248+
}
249+
}
250+
}
251+
252+
ref.Tags = append(ref.Tags, tag)
253+
return nil
254+
}); err != nil {
255+
return nil, err
155256
}
156257

157258
remotes, err := c.cache.repo.Remotes()
@@ -186,17 +287,8 @@ func (c *PathChecker) MakeSummary() (types.PathCheckSummary, error) {
186287
git.Remotes[remoteConfig.Name] = remoteConfig.URLs
187288
}
188289

189-
head, err := c.cache.repo.Head()
190-
if err != nil {
191-
return nil, err
192-
}
193-
194-
git.Reference = GitReference{
195-
Name: head.Name().String(),
196-
Hash: head.Hash().String(),
197-
Type: head.Type().String(),
198-
Target: head.Target().String(),
199-
}
290+
git.Reference = ref
291+
git.Object = *obj
200292

201293
return summary, nil
202294
}

0 commit comments

Comments
 (0)