Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sanity check against deleting user files #6610

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions lib/cask/artifact/uninstall_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,138 @@ class Cask::Artifact::UninstallBase < Cask::Artifact::Base

PATH_ARG_SLICE_SIZE = 500

# todo: There should be a way to specify a containing
# directory under which nothing can be deleted.
#
# This set should be merged with the SYSTEM_DIRS
# set found in lib/cask/pkg.rb.
UNDELETABLE_PATHS = Set.new [
'~/',
'~/Applications',
'~/Desktop',
'~/Documents',
'~/Downloads',
'~/Mail',
'~/Movies',
'~/Music',
'~/Music/iTunes',
'~/Music/iTunes/iTunes Music',
'~/Music/iTunes/Album Artwork',
'~/News',
'~/Pictures',
'~/Pictures/Desktops',
'~/Pictures/Photo Booth',
'~/Pictures/iChat Icons',
'~/Pictures/iPhoto Library',
'~/Public',
'~/Sites',
'~/Library',
'~/Library/.localized',
'~/Library/Accessibility',
'~/Library/Accounts',
'~/Library/Address Book Plug-Ins',
'~/Library/Application Scripts',
'~/Library/Application Support',
'~/Library/Application Support/Apple',
'~/Library/Application Support/com.apple.AssistiveControl',
'~/Library/Application Support/com.apple.QuickLook',
'~/Library/Application Support/com.apple.TCC',
'~/Library/Assistants',
'~/Library/Audio',
'~/Library/Automator',
'~/Library/Autosave Information',
'~/Library/Caches',
'~/Library/Calendars',
'~/Library/ColorPickers',
'~/Library/ColorSync',
'~/Library/Colors',
'~/Library/Components',
'~/Library/Compositions',
'~/Library/Containers',
'~/Library/Contextual Menu Items',
'~/Library/Cookies',
'~/Library/DTDs',
'~/Library/Desktop Pictures',
'~/Library/Developer',
'~/Library/Dictionaries',
'~/Library/DirectoryServices',
'~/Library/Displays',
'~/Library/Documentation',
'~/Library/Extensions',
'~/Library/Favorites',
'~/Library/FileSync',
'~/Library/Filesystems',
'~/Library/Filters',
'~/Library/FontCollections',
'~/Library/Fonts',
'~/Library/Frameworks',
'~/Library/GameKit',
'~/Library/Graphics',
'~/Library/Group Containers',
'~/Library/Icons',
'~/Library/IdentityServices',
'~/Library/Image Capture',
'~/Library/Images',
'~/Library/Input Methods',
'~/Library/Internet Plug-Ins',
'~/Library/InternetAccounts',
'~/Library/iTunes',
'~/Library/KeyBindings',
'~/Library/Keyboard Layouts',
'~/Library/Keychains',
'~/Library/LaunchAgents',
'~/Library/LaunchDaemons',
'~/Library/LocationBundles',
'~/Library/LoginPlugins',
'~/Library/Logs',
'~/Library/Mail',
'~/Library/Mail Downloads',
'~/Library/Messages',
'~/Library/Metadata',
'~/Library/Mobile Documents',
'~/Library/MonitorPanels',
'~/Library/OpenDirectory',
'~/Library/PDF Services',
'~/Library/PhonePlugins',
'~/Library/Phones',
'~/Library/PreferencePanes',
'~/Library/Preferences',
'~/Library/Printers',
'~/Library/PrivateFrameworks',
'~/Library/PubSub',
'~/Library/QuickLook',
'~/Library/QuickTime',
'~/Library/Receipts',
'~/Library/Recent Servers',
'~/Library/Recents',
'~/Library/Safari',
'~/Library/Saved Application State',
'~/Library/Screen Savers',
'~/Library/ScreenReader',
'~/Library/ScriptingAdditions',
'~/Library/ScriptingDefinitions',
'~/Library/Scripts',
'~/Library/Security',
'~/Library/Services',
'~/Library/Sounds',
'~/Library/Speech',
'~/Library/Spelling',
'~/Library/Spotlight',
'~/Library/StartupItems',
'~/Library/StickiesDatabase',
'~/Library/Sync Services',
'~/Library/SyncServices',
'~/Library/SyncedPreferences',
'~/Library/TextEncodings',
'~/Library/User Pictures',
'~/Library/Video',
'~/Library/Voices',
'~/Library/WebKit',
'~/Library/WidgetResources',
'~/Library/Widgets',
'~/Library/Workflows',
].map{|x| %r{\A~}.match(x) ? Pathname.new(x).expand_path : Pathname.new(x)}

# todo: these methods were consolidated here from separate
# sources and should be refactored for consistency

Expand All @@ -24,6 +156,16 @@ def self.remove_relative_path_strings(action, path_strings)
path_strings - relative
end

def self.remove_undeletable_path_strings(action, path_strings)
undeletable = path_strings.map do |path_string|
path_string if UNDELETABLE_PATHS.include?(Pathname.new(path_string))
end.compact
undeletable.each do |path_string|
opoo %Q{Skipping #{action} for undeletable path #{path_string}}
end
path_strings - undeletable
end

def install_phase
odebug "Nothing to do. The uninstall artifact has no install phase."
end
Expand Down Expand Up @@ -149,6 +291,7 @@ def dispatch_uninstall_directives(stanza, expand_tilde=false)
ohai "Removing files: #{path_slice.utf8_inspect}"
path_slice = self.class.expand_path_strings(path_slice) if expand_tilde
path_slice = self.class.remove_relative_path_strings(:delete, path_slice)
path_slice = self.class.remove_undeletable_path_strings(:delete, path_slice)
@command.run!('/bin/rm', :args => path_slice.unshift('-rf', '--'), :sudo => true)
end
end
Expand All @@ -160,6 +303,7 @@ def dispatch_uninstall_directives(stanza, expand_tilde=false)
ohai "Removing files: #{path_slice.utf8_inspect}"
path_slice = self.class.expand_path_strings(path_slice) if expand_tilde
path_slice = self.class.remove_relative_path_strings(:trash, path_slice)
path_slice = self.class.remove_undeletable_path_strings(:trash, path_slice)
@command.run!('/bin/rm', :args => path_slice.unshift('-rf', '--'), :sudo => true)
end
end
Expand All @@ -170,6 +314,7 @@ def dispatch_uninstall_directives(stanza, expand_tilde=false)
ohai "Removing files: #{path_slice.utf8_inspect}"
path_slice = self.class.expand_path_strings(path_slice) if expand_tilde
path_slice = self.class.remove_relative_path_strings(:delete, path_slice) # :delete for messages
path_slice = self.class.remove_undeletable_path_strings(:delete, path_slice)
@command.run!('/bin/rm', :args => path_slice.unshift('-rf', '--'), :sudo => true)
end
end
Expand All @@ -178,6 +323,7 @@ def dispatch_uninstall_directives(stanza, expand_tilde=false)
Array(directives[:rmdir]).flatten.each do |directory|
directory = self.class.expand_path_strings([directory]).first if expand_tilde
directory = self.class.remove_relative_path_strings(:rmdir, [ directory ]).first
directory = self.class.remove_undeletable_path_strings(:rmdir, [ directory ]).first
next unless directory.respond_to?(:length)
next unless directory.length > 0
ohai "Removing directory if empty: #{directory.utf8_inspect}"
Expand Down