feat(android): port iOS rsync optimisations to Android build pipeline#31
feat(android): port iOS rsync optimisations to Android build pipeline#31benjam-es wants to merge 4 commits intoNativePHP:mainfrom
Conversation
Replace RecursiveIteratorIterator with rsync -a --copy-links in copyLaravelAppIntoIosApp() to eliminate unnecessary file copying and prevent OOM crashes with symlinked local packages. The old approach collected all files into a PHP array before copying, consuming 60+ MB on standard projects and exceeding the 128 MB memory limit when Composer path repositories introduced nested vendor dirs. It also copied ~19,000 files (notably node_modules) that removeUnnecessaryFiles() immediately deleted. - Add getExcludedPaths() as single source of truth for rsync excludes - Add loadVendorExportIgnorePatterns() to respect .gitattributes - Add glob support in removeUnnecessaryFiles for wildcard dir patterns - Exclude non-runtime files (*.md, LICENSE*, docs, CI configs) - Fix vendor nested dir pattern (vendor/*/*/vendor vs vendor/*/vendor) - Wrap copy step in components->task() for progress feedback
|
This ports the same optimisations introduced in the iOS build in #30 — shared The Android pipeline is a bit more involved since it needs to work across macOS, Linux, and Windows (robocopy vs rsync, different nativephp/ exclude logic per platform), so this might need more testing on those platforms to make sure nothing slips through. The core exclude list is identical to iOS, but the platform-conditional branches are worth a closer look. |
5ce4ddc to
ad955fd
Compare
Move hardcoded exclusion lists, copy logic, and cleanup logic out of BuildIosAppCommand into BundleExclusions (data) and BundleFileManager (behaviour). This makes the lists testable, maintainable, and reusable across platforms.
- Add shared getExcludedPaths() with comprehensive exclude list matching iOS - Add loadVendorExportIgnorePatterns() for .gitattributes export-ignore support - Fix vendor glob pattern from vendor/*/vendor to vendor/*/*/vendor - Replace platform-specific match block with unified getExcludedPaths() call - Stream ZIP iterator directly instead of materialising via iterator_to_array() - Remove redundant addDirectoryToZip() excludes now handled by rsync
…ileManager Remove getExcludedPaths(), loadVendorExportIgnorePatterns(), and platformOptimizedCopy() that duplicated the extracted BundleExclusions and BundleFileManager classes. Android bundle prep now uses the same copy/cleanup pipeline as iOS.
Manual profiling: kitchen-sink-mobile-vueTested on real device build ( Build step timing
What the 15.8 MB reduction is made ofBreakdown of the 1,794 files (34 MB pre-compression) now excluded from the bundle:
Profiling script results (3-run average)
|
Safety of removed filesAll excluded content is non-runtime:
The cleanup step ( |
ad955fd to
105385a
Compare
Problem
The Android build pipeline in
PreparesBuild.phpandPlatformFileOperations.phphas the same issues that were fixed for iOS in #30:Minimal exclude rules — Only 4–6 hardcoded excludes (
.git,node_modules,nativephp/*,vendor/nativephp/mobile/resources), so rsync copies thousands of non-runtime files (tests, docs, dotfiles, YAML configs, LICENSE files) into the temp directory.Wrong vendor glob —
vendor/*/vendoronly matches one level deep, missing the actual Composer layoutvendor/namespace/package/vendor. The separatevendor/nativephp/mobile/vendorline was a workaround for this bug.No
.gitattributessupport — Vendor packages that declareexport-ignorepatterns are fully copied, including their test suites and CI configs.Memory spike in ZIP step —
addDirectoryToZip()callsiterator_to_array()to materialise every file into a PHP array before iterating, consuming ~20 MB unnecessarily.Redundant hardcoded excludes —
addDirectoryToZip()maintains its own list of 14 hardcoded excludes that partially overlap with rsync's excludes, making the filtering logic harder to maintain.Solution
Port the iOS optimisations from #30 to the Android build:
getExcludedPaths()— shared method with comprehensive exclude list (dotfiles, tests, docs, vendor non-runtime files, project-level build artifacts), with platform-awarenativephp/handlingloadVendorExportIgnorePatterns()— reads.gitattributesexport-ignorefrom vendor packagesprepareLaravelBundle()— replaces thematch (PHP_OS_FAMILY)block withgetExcludedPaths()+loadVendorExportIgnorePatterns()platformOptimizedCopy()— fixesvendor/*/vendor→vendor/*/*/vendor, removes hardcoded appends (now provided by caller)addDirectoryToZip()— streams iterator directly instead of materialising array; removes excludes now guaranteed absent after rsync (keeps safety-net excludes for files created between rsync and zip)Benchmarks
Profiled on kitchen-sink-mobile-vue (Android build flow):
Rsync copy
ZIP creation
Total
Key takeaways:
iterator_to_arrayis the big winaddDirectoryToZip()hardcoded excludes cleanup was safeTest plan
composer installstep still runs correctly in temp directorygetExcludedPaths()