@@ -624,8 +624,10 @@ func WriteDeltaTar(w io.Writer, baseDir string, relPaths []string) error {
624624 return tw .Close ()
625625}
626626
627- // ImmutableWorkspaceParents lists directory names whose immediate children are
628- // immutable workspace directories (e.g. transforms/<hash>/, groovy-dsl/<hash>/).
627+ // ImmutableWorkspaceParents maps directory names to the depth at which their
628+ // immutable workspace hash directories live. Depth 1 means the hash dirs are
629+ // direct children (e.g. transforms/<hash>/). Depth 2 means the hash dirs are
630+ // one level deeper (e.g. kotlin-dsl/scripts/<hash>/).
629631//
630632// Each workspace is an atomic unit: Gradle creates all files together via an
631633// atomic directory rename, and expects all files to be present when reading.
@@ -639,10 +641,18 @@ func WriteDeltaTar(w io.Writer, baseDir string, relPaths []string) error {
639641//
640642// The fix: when ANY file in a workspace is newer than the marker, include ALL
641643// files from that workspace in the delta.
642- var ImmutableWorkspaceParents = map [string ]bool {
643- "transforms" : true ,
644- "groovy-dsl" : true ,
645- "kotlin-dsl" : true ,
644+ //
645+ // Workspace directory structure (relative to caches/<version>/):
646+ // - transforms/<hash>/ depth 1 - artifact transforms
647+ // - groovy-dsl/<hash>/ depth 1 - compiled Groovy build scripts
648+ // - kotlin-dsl/scripts/<hash>/ depth 2 - compiled Kotlin build scripts
649+ // - kotlin-dsl/accessors/<hash>/ depth 2 - generated type-safe accessors
650+ // - dependencies-accessors/<hash>/ depth 1 - version catalog accessors
651+ var ImmutableWorkspaceParents = map [string ]int {
652+ "transforms" : 1 ,
653+ "groovy-dsl" : 1 ,
654+ "kotlin-dsl" : 2 ,
655+ "dependencies-accessors" : 1 ,
646656}
647657
648658// CollectNewFiles walks realCaches in parallel and returns paths of regular files
@@ -681,9 +691,12 @@ func CollectNewFiles(realCaches string, since time.Time, gradleHome string) ([]s
681691 }
682692
683693 // walkWorkspaceParent handles directories like transforms/ whose children
684- // are atomic workspace directories. For each child, if any file is newer
685- // than since, all files are included.
686- walkWorkspaceParent := func (dir , rel string ) {
694+ // are atomic workspace directories. depth indicates how many directory levels
695+ // below dir the actual hash workspace directories live. When depth > 1
696+ // (e.g. kotlin-dsl/scripts/<hash>/), it recurses into intermediate directories
697+ // before treating children as atomic workspaces.
698+ var walkWorkspaceParent func (dir , rel string , depth int )
699+ walkWorkspaceParent = func (dir , rel string , depth int ) {
687700 defer wg .Done ()
688701
689702 entries , err := os .ReadDir (dir )
@@ -705,6 +718,14 @@ func CollectNewFiles(realCaches string, since time.Time, gradleHome string) ([]s
705718 childDir := filepath .Join (dir , entry .Name ())
706719 childRel := rel + "/" + entry .Name ()
707720
721+ if depth > 1 {
722+ // Not yet at the hash workspace level — recurse one level deeper.
723+ sem <- struct {}{}
724+ wg .Add (1 )
725+ go walkWorkspaceParent (childDir , childRel , depth - 1 )
726+ continue
727+ }
728+
708729 hasNew := false
709730 _ = filepath .WalkDir (childDir , func (_ string , d os.DirEntry , err error ) error {
710731 if err != nil || d .IsDir () {
@@ -755,10 +776,10 @@ func CollectNewFiles(realCaches string, since time.Time, gradleHome string) ([]s
755776 if IsExcludedCache (name ) || IsDeltaExcluded (name ) {
756777 continue
757778 }
758- if ImmutableWorkspaceParents [name ] {
779+ if depth , ok := ImmutableWorkspaceParents [name ]; ok {
759780 sem <- struct {}{}
760781 wg .Add (1 )
761- go walkWorkspaceParent (filepath .Join (dir , name ), childRel )
782+ go walkWorkspaceParent (filepath .Join (dir , name ), childRel , depth )
762783 } else {
763784 sem <- struct {}{}
764785 wg .Add (1 )
0 commit comments