@@ -79,9 +79,11 @@ type Hashed interface {
7979 Digest () digest.Digest
8080}
8181
82- type IncludedPath struct {
83- Path string
84- Record * CacheRecord
82+ type includedPath struct {
83+ path string
84+ record * CacheRecord
85+ matchedIncludePattern bool
86+ matchedExcludePattern bool
8587}
8688
8789type cacheManager struct {
@@ -404,30 +406,30 @@ func (cc *cacheContext) Checksum(ctx context.Context, mountable cache.Mountable,
404406
405407 if opts .FollowLinks {
406408 for i , w := range includedPaths {
407- if w .Record .Type == CacheRecordTypeSymlink {
408- dgst , err := cc .checksumFollow (ctx , m , w .Path , opts .FollowLinks )
409+ if w .record .Type == CacheRecordTypeSymlink {
410+ dgst , err := cc .checksumFollow (ctx , m , w .path , opts .FollowLinks )
409411 if err != nil {
410412 return "" , err
411413 }
412- includedPaths [i ].Record = & CacheRecord {Digest : dgst }
414+ includedPaths [i ].record = & CacheRecord {Digest : dgst }
413415 }
414416 }
415417 }
416418 if len (includedPaths ) == 0 {
417419 return digest .FromBytes ([]byte {}), nil
418420 }
419421
420- if len (includedPaths ) == 1 && path .Base (p ) == path .Base (includedPaths [0 ].Path ) {
421- return includedPaths [0 ].Record .Digest , nil
422+ if len (includedPaths ) == 1 && path .Base (p ) == path .Base (includedPaths [0 ].path ) {
423+ return includedPaths [0 ].record .Digest , nil
422424 }
423425
424426 digester := digest .Canonical .Digester ()
425427 for i , w := range includedPaths {
426428 if i != 0 {
427429 digester .Hash ().Write ([]byte {0 })
428430 }
429- digester .Hash ().Write ([]byte (path .Base (w .Path )))
430- digester .Hash ().Write ([]byte (w .Record .Digest ))
431+ digester .Hash ().Write ([]byte (path .Base (w .path )))
432+ digester .Hash ().Write ([]byte (w .record .Digest ))
431433 }
432434 return digester .Digest (), nil
433435}
@@ -456,7 +458,7 @@ func (cc *cacheContext) checksumFollow(ctx context.Context, m *mount, p string,
456458 }
457459}
458460
459- func (cc * cacheContext ) includedPaths (ctx context.Context , m * mount , p string , opts ChecksumOpts ) ([]* IncludedPath , error ) {
461+ func (cc * cacheContext ) includedPaths (ctx context.Context , m * mount , p string , opts ChecksumOpts ) ([]* includedPath , error ) {
460462 cc .mu .Lock ()
461463 defer cc .mu .Unlock ()
462464
@@ -501,7 +503,7 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
501503 }
502504 }
503505
504- includedPaths := make ([]* IncludedPath , 0 , 2 )
506+ includedPaths := make ([]* includedPath , 0 , 2 )
505507
506508 txn := cc .tree .Txn ()
507509 root = txn .Root ()
@@ -524,7 +526,7 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
524526 }
525527
526528 var (
527- parentDirHeaders []* IncludedPath
529+ parentDirHeaders []* includedPath
528530 lastMatchedDir string
529531 )
530532
@@ -533,11 +535,15 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
533535
534536 for len (parentDirHeaders ) != 0 {
535537 lastParentDir := parentDirHeaders [len (parentDirHeaders )- 1 ]
536- if strings .HasPrefix (fn , lastParentDir .Path + "/" ) {
538+ if strings .HasPrefix (fn , lastParentDir .path + "/" ) {
537539 break
538540 }
539541 parentDirHeaders = parentDirHeaders [:len (parentDirHeaders )- 1 ]
540542 }
543+ var parentDir * includedPath
544+ if len (parentDirHeaders ) != 0 {
545+ parentDir = parentDirHeaders [len (parentDirHeaders )- 1 ]
546+ }
541547
542548 dirHeader := false
543549 if len (k ) > 0 && k [len (k )- 1 ] == byte (0 ) {
@@ -550,6 +556,7 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
550556 }
551557 }
552558
559+ maybeIncludedPath := & includedPath {path : fn }
553560 var shouldInclude bool
554561 if opts .Wildcard {
555562 if p != "" && (lastMatchedDir == "" || ! strings .HasPrefix (fn , lastMatchedDir + "/" )) {
@@ -564,7 +571,13 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
564571 lastMatchedDir = fn
565572 }
566573
567- shouldInclude , err = shouldIncludePath (strings .TrimSuffix (strings .TrimPrefix (fn + "/" , lastMatchedDir + "/" ), "/" ), includePatternMatcher , excludePatternMatcher )
574+ shouldInclude , err = shouldIncludePath (
575+ strings .TrimSuffix (strings .TrimPrefix (fn + "/" , lastMatchedDir + "/" ), "/" ),
576+ includePatternMatcher ,
577+ excludePatternMatcher ,
578+ maybeIncludedPath ,
579+ parentDir ,
580+ )
568581 if err != nil {
569582 return nil , err
570583 }
@@ -574,7 +587,13 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
574587 continue
575588 }
576589
577- shouldInclude , err = shouldIncludePath (strings .TrimSuffix (strings .TrimPrefix (fn + "/" , p + "/" ), "/" ), includePatternMatcher , excludePatternMatcher )
590+ shouldInclude , err = shouldIncludePath (
591+ strings .TrimSuffix (strings .TrimPrefix (fn + "/" , p + "/" ), "/" ),
592+ includePatternMatcher ,
593+ excludePatternMatcher ,
594+ maybeIncludedPath ,
595+ parentDir ,
596+ )
578597 if err != nil {
579598 return nil , err
580599 }
@@ -599,17 +618,18 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
599618 // dir.
600619 shouldInclude = false
601620 }
621+ maybeIncludedPath .record = cr
602622
603623 if ! shouldInclude {
604624 if cr .Type == CacheRecordTypeDirHeader {
605625 // We keep track of non-included parent dir headers in case an
606626 // include pattern matches a file inside one of these dirs.
607- parentDirHeaders = append (parentDirHeaders , & IncludedPath { Path : fn , Record : cr } )
627+ parentDirHeaders = append (parentDirHeaders , maybeIncludedPath )
608628 }
609629 } else {
610630 includedPaths = append (includedPaths , parentDirHeaders ... )
611631 parentDirHeaders = nil
612- includedPaths = append (includedPaths , & IncludedPath { Path : fn , Record : cr } )
632+ includedPaths = append (includedPaths , maybeIncludedPath )
613633 }
614634 k , _ , kOk = iter .Next ()
615635 }
@@ -624,22 +644,38 @@ func shouldIncludePath(
624644 candidate string ,
625645 includePatternMatcher * fileutils.PatternMatcher ,
626646 excludePatternMatcher * fileutils.PatternMatcher ,
647+ maybeIncludedPath * includedPath ,
648+ parentDir * includedPath ,
627649) (bool , error ) {
650+ var (
651+ m bool
652+ err error
653+ )
628654 if includePatternMatcher != nil {
629- m , err := includePatternMatcher .Matches (candidate )
655+ if parentDir != nil {
656+ m , err = includePatternMatcher .MatchesUsingParentResult (candidate , parentDir .matchedIncludePattern )
657+ } else {
658+ m , err = includePatternMatcher .MatchesOrParentMatches (candidate )
659+ }
630660 if err != nil {
631661 return false , errors .Wrap (err , "failed to match includepatterns" )
632662 }
663+ maybeIncludedPath .matchedIncludePattern = m
633664 if ! m {
634665 return false , nil
635666 }
636667 }
637668
638669 if excludePatternMatcher != nil {
639- m , err := excludePatternMatcher .Matches (candidate )
670+ if parentDir != nil {
671+ m , err = excludePatternMatcher .MatchesUsingParentResult (candidate , parentDir .matchedExcludePattern )
672+ } else {
673+ m , err = excludePatternMatcher .MatchesOrParentMatches (candidate )
674+ }
640675 if err != nil {
641676 return false , errors .Wrap (err , "failed to match excludepatterns" )
642677 }
678+ maybeIncludedPath .matchedExcludePattern = m
643679 if m {
644680 return false , nil
645681 }
0 commit comments