@@ -6,9 +6,12 @@ import (
66 "fmt"
77 "os"
88 "os/user"
9+ "sort"
910 "strings"
1011 "time"
1112
13+ "github.com/dustin/go-humanize"
14+
1215 xa "github.com/bitrise-io/bitrise-build-cache-cli/internal/analytics"
1316 "github.com/bitrise-io/bitrise-build-cache-cli/internal/build_cache/kv"
1417 "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
@@ -43,6 +46,8 @@ var restoreXcodeDerivedDataFilesCmd = &cobra.Command{
4346 logger .Infof ("(i) Checking parameters" )
4447 projectRoot , _ := cmd .Flags ().GetString ("project-root" )
4548 cacheKey , _ := cmd .Flags ().GetString ("key" )
49+ forceOverwrite , _ := cmd .Flags ().GetBool ("force-overwrite-files" )
50+ maxLoggedErrors , _ := cmd .Flags ().GetInt ("max-logged-errors" )
4651
4752 tracker := xcode .NewDefaultStepTracker ("restore-xcode-build-cache" , os .Getenv , logger )
4853 defer tracker .Wait ()
@@ -54,7 +59,8 @@ var restoreXcodeDerivedDataFilesCmd = &cobra.Command{
5459 return fmt .Errorf ("read auth config from environments: %w" , err )
5560 }
5661
57- op , cmdError := restoreXcodeDerivedDataFilesCmdFn (cmd .Context (), authConfig , CacheMetadataPath , projectRoot , cacheKey , logger , tracker , startT , os .Getenv , isDebugLogMode )
62+ op , cmdError := restoreXcodeDerivedDataFilesCmdFn (cmd .Context (), authConfig , CacheMetadataPath , projectRoot ,
63+ cacheKey , logger , tracker , startT , os .Getenv , isDebugLogMode , forceOverwrite , maxLoggedErrors )
5864 if op != nil {
5965 if cmdError != nil {
6066 errStr := cmdError .Error ()
@@ -85,10 +91,12 @@ func init() {
8591 if err := restoreXcodeDerivedDataFilesCmd .MarkFlagRequired ("project-root" ); err != nil {
8692 panic (err )
8793 }
94+ restoreXcodeDerivedDataFilesCmd .Flags ().Bool ("force-overwrite-files" , false , "If set, the command will try to overwrite existing files during restoring the cache even if the permissions do not allow it" )
95+ restoreXcodeDerivedDataFilesCmd .Flags ().Int ("max-logged-errors" , 100 , "The maximum number of errors logged to the console during restoring the cache." )
8896}
8997
9098func restoreXcodeDerivedDataFilesCmdFn (ctx context.Context , authConfig common.CacheAuthConfig , cacheMetadataPath , projectRoot , providedCacheKey string , logger log.Logger ,
91- tracker xcode.StepAnalyticsTracker , startT time.Time , envProvider func (string ) string , isDebugLogMode bool ) (* xa.CacheOperation , error ) {
99+ tracker xcode.StepAnalyticsTracker , startT time.Time , envProvider func (string ) string , isDebugLogMode , forceOverwrite bool , maxLoggedDownloadErrors int ) (* xa.CacheOperation , error ) {
92100 kvClient , err := createKVClient (ctx , authConfig , envProvider , logger )
93101 if err != nil {
94102 return nil , fmt .Errorf ("create kv client: %w" , err )
@@ -110,7 +118,7 @@ func restoreXcodeDerivedDataFilesCmdFn(ctx context.Context, authConfig common.Ca
110118 return op , fmt .Errorf ("load metadata: %w" , err )
111119 }
112120
113- logCacheMetadata (metadata , logger )
121+ logCacheMetadata (metadata , logger , isDebugLogMode )
114122
115123 logger .TInfof ("Restoring metadata of input files" )
116124 var filesUpdated int
@@ -127,7 +135,7 @@ func restoreXcodeDerivedDataFilesCmdFn(ctx context.Context, authConfig common.Ca
127135 tracker .LogMetadataLoaded (metadataRestoredT .Sub (startT ), string (cacheKeyType ), len (metadata .ProjectFiles .Files )+ len (metadata .ProjectFiles .Directories ), filesUpdated , metadataSize )
128136
129137 logger .TInfof ("Downloading DerivedData files" )
130- stats , err := xcode .DownloadCacheFilesFromBuildCache (ctx , metadata .DerivedData , kvClient , logger , isDebugLogMode )
138+ stats , err := xcode .DownloadCacheFilesFromBuildCache (ctx , metadata .DerivedData , kvClient , logger , isDebugLogMode , forceOverwrite , maxLoggedDownloadErrors )
131139 ddDownloadedT := time .Now ()
132140 tracker .LogDerivedDataDownloaded (ddDownloadedT .Sub (metadataRestoredT ), stats )
133141 fillCacheOperationWithDownloadStats (op , stats )
@@ -146,7 +154,7 @@ func restoreXcodeDerivedDataFilesCmdFn(ctx context.Context, authConfig common.Ca
146154
147155 if len (metadata .XcodeCacheDir .Files ) > 0 {
148156 logger .TInfof ("Downloading Xcode cache files" )
149- if _ , err := xcode .DownloadCacheFilesFromBuildCache (ctx , metadata .XcodeCacheDir , kvClient , logger , isDebugLogMode ); err != nil {
157+ if _ , err := xcode .DownloadCacheFilesFromBuildCache (ctx , metadata .XcodeCacheDir , kvClient , logger , isDebugLogMode , forceOverwrite , maxLoggedDownloadErrors ); err != nil {
150158 return op , fmt .Errorf ("download Xcode cache files: %w" , err )
151159 }
152160
@@ -211,7 +219,7 @@ func downloadMetadata(ctx context.Context, cacheMetadataPath, providedCacheKey s
211219 return cacheKeyType , cacheKey , nil
212220}
213221
214- func logCacheMetadata (md * xcode.Metadata , logger log.Logger ) {
222+ func logCacheMetadata (md * xcode.Metadata , logger log.Logger , isDebugLogMode bool ) {
215223 logger .Infof ("Cache metadata:" )
216224 logger .Infof (" Cache key: %s" , md .CacheKey )
217225 createdAt := ""
@@ -228,6 +236,24 @@ func logCacheMetadata(md *xcode.Metadata, logger log.Logger) {
228236 logger .Infof (" Xcode cache files: %d" , len (md .XcodeCacheDir .Files ))
229237 logger .Infof (" Build Cache CLI version: %s" , md .BuildCacheCLIVersion )
230238 logger .Infof (" Metadata version: %d" , md .MetadataVersion )
239+
240+ if isDebugLogMode {
241+ sortedDDFiles := make ([]* xcode.FileInfo , len (md .DerivedData .Files ))
242+ copy (sortedDDFiles , md .DerivedData .Files )
243+
244+ sort .Slice (sortedDDFiles , func (i , j int ) bool {
245+ return sortedDDFiles [i ].Size > sortedDDFiles [j ].Size
246+ })
247+
248+ if len (sortedDDFiles ) > 10 {
249+ sortedDDFiles = sortedDDFiles [:10 ]
250+ }
251+
252+ logger .Debugf (" Largest files:" )
253+ for i , file := range sortedDDFiles {
254+ logger .Debugf (" %d. %s (%s)" , i + 1 , file .Path , humanize .Bytes (uint64 (file .Size )))
255+ }
256+ }
231257}
232258
233259func logCurrentUserInfo (logger log.Logger ) {
0 commit comments