@@ -23,9 +23,6 @@ const (
23
23
DefaultPrimaryRemoteName = "origin"
24
24
)
25
25
26
- // TODO: need a way to detect multiple repos, for now PathChecker is only meant
27
- // to be used for the manifest dir iteself, and assume there is no nested repos
28
-
29
26
func NewPathChecker (path string , digest digest.SHA256 ) types.PathChecker {
30
27
return & PathChecker {
31
28
path : path ,
@@ -47,16 +44,35 @@ type (
47
44
}
48
45
49
46
GitSummary struct {
50
- ObjectHash * string `json:"objectHash,omitempty"`
51
- Remotes map [string ][]string `json:"remotes,omitempty"`
52
- 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"`
53
67
}
54
68
55
69
GitReference struct {
56
- Name string `json:"name,omitempty"`
57
- Hash string `json:"hash,omitempty"`
58
- Type string `json:"type,omitempty"`
59
- 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"`
60
76
}
61
77
)
62
78
@@ -142,19 +158,101 @@ func (c *PathChecker) MakeSummary() (types.PathCheckSummary, error) {
142
158
Git : & git ,
143
159
}
144
160
145
- // TODO: determine position of local branch against remote
146
- // TODO: introduce notion of primary remote branch to determine the possition of the working branch
147
- // TODO: determine if a tag is used
148
- // TODO: also check if local tag in sync wirth remote tag
149
- // TODO: provide info on singed tags/commits
161
+ head , err := c .cache .repo .Head ()
162
+ if err != nil {
163
+ return nil , err
164
+ }
165
+
166
+ ref := GitReference {
167
+ Name : head .Name ().String (),
168
+ Hash : head .Hash ().String (),
169
+ Type : head .Type ().String (),
170
+ Target : head .Target ().String (),
171
+ }
150
172
173
+ obj := & GitObject {}
151
174
if summary .Unmodified {
152
- git .ObjectHash = new (string )
153
- * git .ObjectHash = c .cache .obj .ID ().String ()
175
+ obj .TreeHash = c .cache .obj .ID ().String ()
154
176
} else if c .IsBlob () {
155
177
// there is currently no easy way to obtain a hash for a subtree
156
- git .ObjectHash = new (string )
157
- * 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
158
256
}
159
257
160
258
remotes , err := c .cache .repo .Remotes ()
@@ -189,17 +287,8 @@ func (c *PathChecker) MakeSummary() (types.PathCheckSummary, error) {
189
287
git .Remotes [remoteConfig .Name ] = remoteConfig .URLs
190
288
}
191
289
192
- head , err := c .cache .repo .Head ()
193
- if err != nil {
194
- return nil , err
195
- }
196
-
197
- git .Reference = GitReference {
198
- Name : head .Name ().String (),
199
- Hash : head .Hash ().String (),
200
- Type : head .Type ().String (),
201
- Target : head .Target ().String (),
202
- }
290
+ git .Reference = ref
291
+ git .Object = * obj
203
292
204
293
return summary , nil
205
294
}
@@ -288,6 +377,10 @@ func (c *PathChecker) Check() (bool, bool, error) {
288
377
}
289
378
unmodified , _ , err := isBlobUnmodified (worktree , & f .Blob , filepath .Join (repoPath , f .Name ))
290
379
if err != nil {
380
+ if f .Mode == filemode .Symlink {
381
+ // TODO: should at least log a warning for broken symlink
382
+ return nil
383
+ }
291
384
return err
292
385
}
293
386
if ! unmodified {
@@ -419,6 +512,9 @@ func findByPath(repo *gogit.Repository, path string) (object.Object, error) {
419
512
if err != nil {
420
513
return nil , err
421
514
}
515
+ if path == "." {
516
+ return tree , nil
517
+ }
422
518
treeEntry , err := tree .FindEntry (path )
423
519
switch err {
424
520
case nil :
@@ -438,12 +534,12 @@ func findByPath(repo *gogit.Repository, path string) (object.Object, error) {
438
534
}
439
535
440
536
func detectRepo (path string ) (* gogit.Repository , bool ) {
537
+ if repo , err := gogit .PlainOpen (path ); err == nil {
538
+ return repo , true
539
+ }
441
540
dir := filepath .Dir (path )
442
541
if dir == path { // reached root
443
542
return nil , false
444
543
}
445
- if repo , err := gogit .PlainOpen (dir ); err == nil {
446
- return repo , true
447
- }
448
544
return detectRepo (dir )
449
545
}
0 commit comments