@@ -304,22 +304,55 @@ function Base.show(io::IO, filehash::FileHash)
304304end
305305
306306# Estimates the size of the bundle directory
307- function _max_appbundle_dir_size (dir; maxsize= 100 * 1024 * 1024 )
307+ function _max_appbundle_dir_size (dir:: AbstractString ; maxsize= 100 * 1024 * 1024 )
308308 sz = 0
309+ _walk_appbundle_files (dir) do filepath
310+ if sz > maxsize
311+ return _WalkFilesReturnEarly ()
312+ end
313+ sz += filesize (filepath)
314+ end
315+ return sz, sz <= maxsize
316+ end
317+
318+ function _walk_appbundle_files (f:: Base.Callable , dir:: AbstractString )
319+ # Note: even if if `path_filterer` says that directory `foo/bar`
320+ # should not be included, it will still likely return `true` for
321+ # any files in there, like `foo/bar/baz`. So we need to make sure
322+ # we stop recursing into subdirectories.
309323 pred = _PackageBundler. path_filterer (dir)
310- for (root, _, files) in walkdir (dir)
311- for file in files
312- file = joinpath (root, file)
313- if ! pred (file)
314- @debug " ignoring $file in dir size measurement"
315- continue
316- end
324+ _walkfiles (dir; descend= pred) do filepath
325+ if ! pred (filepath)
326+ @debug " ignoring file in _walk_appbundle_files: $(file) "
327+ return nothing
328+ end
329+ return f (filepath)
330+ end
331+ end
332+
333+ struct _WalkFilesReturnEarly end
317334
318- sz > maxsize && return sz, false
319- sz += filesize (file)
335+ # Calls `f` on any non-directory in `root`.
336+ # `descend` gets called on any directory, and if it returns false,
337+ function _walkfiles (f:: Base.Callable , root:: AbstractString ; descend:: Base.Callable )
338+ if ! isdir (root)
339+ error (" Not a directory: $(root) " )
340+ end
341+ directories = String[root]
342+ while ! isempty (directories)
343+ dir = popfirst! (directories)
344+ for subpath in readdir (dir; join= true )
345+ if isdir (subpath)
346+ if descend (subpath):: Bool
347+ push! (directories, subpath)
348+ end
349+ else
350+ if f (subpath) === _WalkFilesReturnEarly ()
351+ break
352+ end
353+ end
320354 end
321355 end
322- return sz, sz < maxsize
323356end
324357
325358function _json_get (d:: Dict , key, :: Type{T} ; var:: AbstractString , parse= false ) where {T}
0 commit comments