├── .gitignore ├── Rakefile ├── assets ├── .DS_Store └── output2.png ├── lib ├── xcode_trash_remover │ ├── version.rb │ ├── int_pretty_size.rb │ ├── size_helper.rb │ ├── xcode_dir.rb │ └── core.rb └── xcode_trash_remover.rb ├── Gemfile ├── plist.rb ├── Gemfile.lock ├── bin └── xcclean ├── xcode_trash_remover.gemspec ├── README.md └── LICENSE.txt /.gitignore: -------------------------------------------------------------------------------- 1 | pkg/ 2 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | task default: :spec 3 | -------------------------------------------------------------------------------- /assets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrankKair/xcode-trash-remover/HEAD/assets/.DS_Store -------------------------------------------------------------------------------- /assets/output2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrankKair/xcode-trash-remover/HEAD/assets/output2.png -------------------------------------------------------------------------------- /lib/xcode_trash_remover/version.rb: -------------------------------------------------------------------------------- 1 | module XcodeTrashRemover 2 | VERSION = '2.0.3'.freeze 3 | end 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in xcode_trash_remover.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /lib/xcode_trash_remover/int_pretty_size.rb: -------------------------------------------------------------------------------- 1 | require 'filesize' 2 | 3 | class Integer 4 | def pretty 5 | s = to_s + ' B' 6 | Filesize.from(s).pretty 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/xcode_trash_remover.rb: -------------------------------------------------------------------------------- 1 | require 'xcode_trash_remover/version' 2 | require 'xcode_trash_remover/core' 3 | require 'xcode_trash_remover/int_pretty_size' 4 | require 'xcode_trash_remover/size_helper' 5 | require 'xcode_trash_remover/xcode_dir' 6 | -------------------------------------------------------------------------------- /plist.rb: -------------------------------------------------------------------------------- 1 | require 'nokogiri' 2 | 3 | devp = File.open('device.plist') 4 | doc = Nokogiri::XML(devp) 5 | xml_node = doc.xpath('//string')[2].to_s 6 | device_name = xml_node.gsub('', '').gsub('', '') 7 | puts device_name 8 | 9 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | xcode_trash_remover (2.0.3) 5 | filesize (~> 0.1.1) 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | filesize (0.1.1) 11 | rake (13.0.3) 12 | 13 | PLATFORMS 14 | ruby 15 | 16 | DEPENDENCIES 17 | bundler (~> 1.14) 18 | rake (~> 13.0) 19 | xcode_trash_remover! 20 | 21 | BUNDLED WITH 22 | 1.16.1 23 | -------------------------------------------------------------------------------- /lib/xcode_trash_remover/size_helper.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | module XcodeTrashRemover 4 | module SizeHelper 5 | module_function 6 | 7 | def dir_size(dir_path) 8 | dir_path << '/' unless dir_path.end_with?('/') 9 | total_size = 0 10 | if File.directory?(dir_path) 11 | Dir["#{dir_path}**/*"].each do |f| 12 | total_size += File.size(f) if File.file?(f) && File.size?(f) 13 | end 14 | end 15 | total_size 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/xcode_trash_remover/xcode_dir.rb: -------------------------------------------------------------------------------- 1 | module XcodeTrashRemover 2 | module XcodeDir 3 | dir_names = %w[ 4 | Xcode/DerivedData 5 | Xcode/Archives 6 | XCPGDevices 7 | CoreSimulator/Devices 8 | ] 9 | 10 | dir_names.each do |dir| 11 | trimmed_dir_name = dir.downcase 12 | .tr('/', '_') 13 | .to_s 14 | .gsub('xcode_', '') 15 | 16 | define_method(trimmed_dir_name) do 17 | root(dir) 18 | end 19 | end 20 | 21 | private 22 | 23 | def root(dir) 24 | Dir.glob("#{File.expand_path('~')}/Library/Developer/#{dir}/*") 25 | end 26 | 27 | module_function :deriveddata, 28 | :archives, 29 | :xcpgdevices, 30 | :coresimulator_devices, 31 | :root 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /bin/xcclean: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'optparse' 3 | require 'xcode_trash_remover' 4 | 5 | ARGV[0] = '--help' if ARGV.empty? 6 | unless ARGV[0].include?('--') || ARGV[0].include?('-') 7 | puts "invalid option: #{ARGV[0]}" 8 | end 9 | 10 | options = {} 11 | opt_parser = OptionParser.new do |opt| 12 | opt.on('--check', 'Checks the volumes') do |o| 13 | options[:check] = o 14 | end 15 | opt.on('--remove', 'Removes the files from your system') do |o| 16 | options[:remove] = o 17 | end 18 | end 19 | 20 | begin 21 | opt_parser.parse! 22 | options.keys.each do |k| 23 | case k 24 | when :check 25 | XcodeTrashRemover::Core.check_volumes 26 | break 27 | when :remove 28 | XcodeTrashRemover::Core.check_volumes 29 | XcodeTrashRemover::Core.remove_trash 30 | break 31 | end 32 | end 33 | rescue StandardError => e 34 | puts e.to_s unless e.message == 'exit' 35 | end 36 | -------------------------------------------------------------------------------- /xcode_trash_remover.gemspec: -------------------------------------------------------------------------------- 1 | 2 | lib = File.expand_path('lib', __dir__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'xcode_trash_remover/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = 'xcode_trash_remover' 8 | spec.version = XcodeTrashRemover::VERSION 9 | spec.authors = ['Frank Kair'] 10 | spec.email = ['frankkair@gmail.com'] 11 | 12 | spec.summary = 'Simple script to remove Xcode trash files' 13 | spec.description = 'Script to remove trash files that Xcode generates' 14 | spec.homepage = 'https://www.github.com/FrankKair/xcode-trash-remover' 15 | spec.license = 'MIT' 16 | 17 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f =~ /docs\// } 18 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 19 | spec.require_paths = ['lib'] 20 | 21 | spec.add_development_dependency 'bundler', '~> 1.14' 22 | spec.add_development_dependency 'rake', '~> 13.0' 23 | spec.add_runtime_dependency 'filesize', '~> 0.1.1' 24 | end 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xcode Trash Remover 2 | 3 | This is a simple script to remove Xcode's trash files that are generated under development. 4 | 5 | If you need a full fledged application, check [this](https://github.com/vashpan/xcode-dev-cleaner) out. 6 | 7 | ## Installation 8 | 9 | $ gem install xcode_trash_remover 10 | 11 | ## Usage 12 | 13 | $ xcclean 14 | 15 | ``` 16 | Usage: xcclean [options] 17 | --check Checks the volumes 18 | --remove Removes the files from your system 19 | ``` 20 | 21 | 22 | 23 | ## Directories 24 | 25 | - `Derived Data`: Intermediate build information. 26 | 27 | - `Archives`: Info about the target. Used for debbuging deployd applications. 28 | 29 | - `XCPGDevices`: Xcode Playground files. 30 | 31 | - `CoreSimulator/Devices`: Simulators and devices. That's where Xcode stores the apps' data. 32 | 33 | ## Warning 34 | 35 | You should only use this program if you're sure you're not going to use the information contained in these folders. 36 | 37 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Frank Kair 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/xcode_trash_remover/core.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | module XcodeTrashRemover 4 | module Core 5 | def check_volumes 6 | puts 'Dir size' 7 | puts 8 | puts "DerivedData #{deriveddata_size.pretty}" 9 | puts "Archives #{archives_size.pretty}" 10 | puts "XCPGDevices #{xcpgdevices_size.pretty}" 11 | puts "CoreSimulator #{coresimulator_devices_size.pretty}" 12 | puts 13 | end 14 | 15 | def remove_trash 16 | total = total_size 17 | remove_dirs 18 | 19 | puts "Total #{total.pretty}" 20 | puts '-' 21 | puts 'The directories are empty. No trash files.' if total.zero? 22 | puts "#{total.pretty} removed!" unless total.zero? 23 | end 24 | 25 | private 26 | 27 | def remove_dirs 28 | dirs = [ 29 | XcodeDir.deriveddata, XcodeDir.archives, 30 | XcodeDir.xcpgdevices, XcodeDir.coresimulator_devices 31 | ] 32 | 33 | dirs.each do |dir| 34 | dir.each do |subdir| 35 | remove_dir(subdir) 36 | end 37 | end 38 | end 39 | 40 | dirs = %w[ 41 | deriveddata 42 | archives 43 | xcpgdevices 44 | coresimulator_devices 45 | ] 46 | 47 | dirs.each do |dir| 48 | define_method("#{dir}_size") do 49 | case dir 50 | when 'deriveddata' 51 | trash_size(XcodeDir.deriveddata) 52 | when 'archives' 53 | trash_size(XcodeDir.archives) 54 | when 'xcpgdevices' 55 | trash_size(XcodeDir.xcpgdevices) 56 | when 'coresimulator_devices' 57 | trash_size(XcodeDir.coresimulator_devices) 58 | end 59 | end 60 | end 61 | 62 | def total_size 63 | [deriveddata_size, 64 | archives_size, 65 | xcpgdevices_size, 66 | coresimulator_devices_size].reduce(:+) 67 | end 68 | 69 | def trash_size(dir) 70 | return 0 if dir.empty? 71 | dir.reduce(0) { |size, subdir| size += SizeHelper.dir_size(subdir) } 72 | end 73 | 74 | def remove_dir(dir) 75 | FileUtils.rm_rf(dir.gsub(/ /, '\ ')) 76 | end 77 | 78 | module_function :check_volumes, 79 | :remove_trash, 80 | :remove_dirs, 81 | :deriveddata_size, 82 | :archives_size, 83 | :xcpgdevices_size, 84 | :coresimulator_devices_size, 85 | :total_size, 86 | :trash_size, 87 | :remove_dir 88 | end 89 | end 90 | --------------------------------------------------------------------------------