michael@0: # Any copyright is dedicated to the Public Domain. michael@0: # http://creativecommons.org/publicdomain/zero/1.0/ michael@0: michael@0: # Creates the precomplete file containing the remove and rmdir application michael@0: # update instructions which is used to remove files and directories that are no michael@0: # longer present in a complete update. The current working directory is used for michael@0: # the location to enumerate and to create the precomplete file. michael@0: # For symlinks, remove instructions are always generated. michael@0: michael@0: import sys michael@0: import os michael@0: michael@0: def get_build_entries(root_path): michael@0: """ Iterates through the root_path, creating a list for each file and michael@0: directory. Excludes any file paths ending with channel-prefs.js. michael@0: To support Tor Browser updates, excludes: michael@0: TorBrowser/Data/Browser/profiles.ini michael@0: TorBrowser/Data/Browser/profile.default/bookmarks.html michael@0: TorBrowser/Data/Tor/torrc michael@0: """ michael@0: rel_file_path_set = set() michael@0: rel_dir_path_set = set() michael@0: for root, dirs, files in os.walk(root_path): michael@0: for file_name in files: michael@0: parent_dir_rel_path = root[len(root_path)+1:] michael@0: rel_path_file = os.path.join(parent_dir_rel_path, file_name) michael@0: rel_path_file = rel_path_file.replace("\\", "/") michael@0: if not (rel_path_file.endswith("channel-prefs.js") or michael@0: rel_path_file.endswith("update-settings.ini") or michael@0: rel_path_file == "TorBrowser/Data/Browser/profiles.ini" or michael@0: rel_path_file == "TorBrowser/Data/Browser/profile.default/bookmarks.html" or michael@0: rel_path_file == "TorBrowser/Data/Tor/torrc" or michael@0: rel_path_file.find("distribution/") != -1): michael@0: rel_file_path_set.add(rel_path_file) michael@0: michael@0: for dir_name in dirs: michael@0: parent_dir_rel_path = root[len(root_path)+1:] michael@0: rel_path_dir = os.path.join(parent_dir_rel_path, dir_name) michael@0: rel_path_dir = rel_path_dir.replace("\\", "/")+"/" michael@0: if rel_path_dir.find("distribution/") == -1: michael@0: if (os.path.islink(rel_path_dir[:-1])): michael@0: rel_file_path_set.add(rel_path_dir[:-1]) michael@0: else: michael@0: rel_dir_path_set.add(rel_path_dir) michael@0: michael@0: rel_file_path_list = list(rel_file_path_set) michael@0: rel_file_path_list.sort(reverse=True) michael@0: rel_dir_path_list = list(rel_dir_path_set) michael@0: rel_dir_path_list.sort(reverse=True) michael@0: michael@0: return rel_file_path_list, rel_dir_path_list michael@0: michael@0: def generate_precomplete(root_path): michael@0: """ Creates the precomplete file containing the remove and rmdir michael@0: application update instructions. The given directory is used michael@0: for the location to enumerate and to create the precomplete file. michael@0: """ michael@0: # If inside a Mac bundle use the root of the bundle for the path. michael@0: if os.path.basename(root_path) == "MacOS": michael@0: root_path = os.path.abspath(os.path.join(root_path, '../../')) michael@0: michael@0: rel_file_path_list, rel_dir_path_list = get_build_entries(root_path) michael@0: precomplete_file_path = os.path.join(root_path,"precomplete") michael@0: # open in binary mode to prevent OS specific line endings. michael@0: precomplete_file = open(precomplete_file_path, "wb") michael@0: for rel_file_path in rel_file_path_list: michael@0: precomplete_file.writelines("remove \""+rel_file_path+"\"\n") michael@0: michael@0: for rel_dir_path in rel_dir_path_list: michael@0: precomplete_file.writelines("rmdir \""+rel_dir_path+"\"\n") michael@0: michael@0: precomplete_file.close() michael@0: michael@0: if __name__ == "__main__": michael@0: generate_precomplete(os.getcwd())