├── README.md ├── cleanup.swift └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # SwiftPM Cleanup 2 | 3 | A simple tool to clean up your SwiftPM project's environment. 4 | It will remove: 5 | - `.build` 6 | - `.swiftpm` 7 | - `Package.resolved` 8 | - `/your/home/directory/.swiftpm` 9 | - `/your/home/directory/Library/Caches/org.swift.swiftpm` 10 | 11 | Optionally, by passing the `--clean-derived-data` flag, it will also remove: 12 | - `/your_home_directory/Library/Developer/Xcode/DerivedData/your_project` 13 | 14 | If you want to specify a project other than the one in the current directory, use the --path option: 15 | 16 | - `--path /path/to/your_project` 17 | 18 | ## Usage 19 | 20 | - Clone the script file into your project's directory 21 | - Run it with 22 | ```bash 23 | swift cleanup.swift [--path /path/to/your_project] [--clean-derived-data] 24 | ``` 25 | 26 | > [!WARNING]\ 27 | > Make sure to: 28 | > - Run it as normal user and not as root, as that will switch your home directory to `/var/root` 29 | > - Close any IDE or editor that might be using the project's files, as that will result in permission issues 30 | -------------------------------------------------------------------------------- /cleanup.swift: -------------------------------------------------------------------------------- 1 | #!/usr/bin/swift 2 | 3 | // This is a script to clean up a SwiftPM environment. 4 | 5 | import Foundation 6 | 7 | let fileManager = FileManager.default 8 | let homeDirectory = NSHomeDirectory() 9 | 10 | let derivedDataPath = "\(homeDirectory)/Library/Developer/Xcode/DerivedData" 11 | 12 | func pathsToClean(for path: String) -> [String] { 13 | [ 14 | "\(path)/.build", 15 | "\(path)/Package.resolved", 16 | "\(path)/.swiftpm", 17 | "\(homeDirectory)/.swiftpm", 18 | "\(homeDirectory)/Library/Caches/org.swift.swiftpm", 19 | ] 20 | } 21 | 22 | func delete(path: String) { 23 | do { 24 | if fileManager.fileExists(atPath: path) { 25 | try fileManager.removeItem(atPath: path) 26 | print("✅ Deleted: \(path)") 27 | } else { 28 | print("❕ Path not found, skipped: \(path)") 29 | } 30 | } catch { 31 | print("❌ Error deleting path \(path): \(error)") 32 | } 33 | } 34 | 35 | func deleteDerivedData(for project: String) { 36 | do { 37 | let derivedDataContents = try fileManager.contentsOfDirectory(atPath: derivedDataPath) 38 | let projectFolder = derivedDataContents.first { $0.contains(project) } 39 | if let projectFolder = projectFolder { 40 | let fullPath = "\(derivedDataPath)/\(projectFolder)" 41 | delete(path: fullPath) 42 | } else { 43 | print("❕ No DerivedData found for project \(project).") 44 | } 45 | } catch { 46 | print("❌ Failed to access DerivedData directory: \(error)") 47 | } 48 | } 49 | 50 | let arguments = CommandLine.arguments 51 | let shouldDeleteDerivedData = arguments.contains("--clean-derived-data") 52 | 53 | let projectPath: String 54 | if 55 | let pathIndex = arguments.firstIndex(of: "--path"), 56 | arguments.count > pathIndex + 1 57 | { 58 | projectPath = arguments[pathIndex + 1] 59 | } else { 60 | projectPath = fileManager.currentDirectoryPath 61 | } 62 | 63 | let projectName = URL(fileURLWithPath: projectPath).lastPathComponent 64 | 65 | for path in pathsToClean(for: projectPath) { 66 | delete(path: path) 67 | } 68 | 69 | if shouldDeleteDerivedData { 70 | deleteDerivedData(for: projectName) 71 | } else { 72 | print("Skipping DerivedData. Use '--clean-derived-data' flag to clean it.") 73 | } 74 | 75 | print("🧹 Cleanup completed.") 76 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | 92 | .vscode 93 | --------------------------------------------------------------------------------