def backup_configs(backup_path): """ Creates `configs` directory and places config backups there. Configs are application settings, generally. .plist files count. """ print_section_header("CONFIGS", Fore.BLUE) mkdir_warn_overwrite(backup_path) config = get_config() configs_dir_mapping = config["config_path_to_dest_map"] plist_files = config["plist_path_to_dest_map"] print(Fore.BLUE + Style.BRIGHT + "Backing up configs..." + Style.RESET_ALL) # backup config dirs in backup_path/<target>/ for config, target in configs_dir_mapping.items(): src_dir = home_prefix(config) configs_backup_path = os.path.join(backup_path, target) if os.path.isdir(src_dir): # TODO: Exclude Sublime/Atom/VS Code Packages here to speed things up copytree(src_dir, configs_backup_path, symlinks=True) # backup plist files in backup_path/configs/plist/ print(Fore.BLUE + Style.BRIGHT + "Backing up plist files..." + Style.RESET_ALL) plist_backup_path = os.path.join(backup_path, "plist") mkdir_or_pass(plist_backup_path) for plist, dest in plist_files.items(): plist_path = home_prefix(plist) if os.path.exists(plist_path): copyfile(plist_path, os.path.join(backup_path, dest))
def reinstall_config_files(configs_path): """ Reinstall all configs from the backup. """ print_section_header("REINSTALLING CONFIG FILES", Fore.BLUE) def backup_prefix(path): return os.path.join(configs_path, path) config = get_config() configs_dir_mapping = config["config_path_to_dest_map"] plist_files = config["plist_path_to_dest_map"] for target, backup in configs_dir_mapping.items(): if os.path.isdir(backup_prefix(backup)): copytree(backup_prefix(backup), home_prefix(target)) for target, backup in plist_files.items(): if os.path.exists(backup_prefix(backup)): copyfile(backup_prefix(backup), home_prefix(target)) print_section_header("SUCCESSFUL CONFIG REINSTALLATION", Fore.BLUE)
def backup_fonts(path): """ Creates list of all .ttf and .otf files in ~/Library/Fonts/ """ print_section_header("FONTS", Fore.BLUE) mkdir_warn_overwrite(path) print(Fore.BLUE + "Copying '.otf' and '.ttf' fonts..." + Style.RESET_ALL) fonts_path = home_prefix("Library/Fonts/") fonts = [ os.path.join(fonts_path, font) for font in os.listdir(fonts_path) if font.endswith(".otf") or font.endswith(".ttf") ] for font in fonts: if os.path.exists(font): copyfile(font, os.path.join(path, font.split("/")[-1]))
def backup_fonts(backup_path, skip=False): """ Copies all .ttf and .otf files in ~/Library/Fonts/ to backup/fonts/ TODO: Windows and Linux Compatibility """ print_section_header("FONTS", Fore.BLUE) overwrite_dir_prompt_if_needed(backup_path, skip) print_blue("Copying '.otf' and '.ttf' fonts...") fonts_path = home_prefix("Library/Fonts/") fonts = [os.path.join(fonts_path, font) for font in os.listdir(fonts_path) if font.endswith(".otf") or font.endswith(".ttf")] # TODO: Collapse into list comprehension for font in fonts: if os.path.exists(font): copyfile(font, os.path.join(backup_path, font.split("/")[-1]))
def add_path_to_config(section, path): """ Adds the path under the correct section in the config file. FIRST ARG: [dot, config, other] SECOND ARG: path, relative to home directory for dotfiles, absolute for configs """ full_path = home_prefix(path) if not os.path.exists(full_path): print_bright_red("ERR: {} doesn't exist.".format(full_path)) sys.exit(1) if section == "dot": # Make sure dotfile starts with a period if path[0] != ".": print_bright_red("ERR: Not a dotfile.") sys.exit(1) if not os.path.isdir(full_path): section = "dotfiles" print(Fore.BLUE + Style.BRIGHT + "Adding {} to dotfile backup.".format(full_path) + Style.RESET_ALL) else: section = "dotfolders" if path[-1] != "/": full_path += "/" path += "/" print(Fore.BLUE + Style.BRIGHT + "Adding {} to dotfolder backup.".format(full_path) + Style.RESET_ALL) # TODO: Add config section once configs backup prefs are moved to the config file elif section == "config": print(Fore.RED + Style.BRIGHT + "ERR: Option not currently supported." + Style.RESET_ALL) sys.exit(1) elif section == "other": print(Fore.RED + Style.BRIGHT + "ERR: Option not currently supported." + Style.RESET_ALL) sys.exit(1) config = get_config() file_set = set(config[section]) file_set.update([path]) config[section] = list(file_set) write_config(config)
def reinstall_configs_sb(configs_path): """ Reinstall all configs from the backup. """ print_section_header("REINSTALLING CONFIG FILES", Fore.BLUE) def backup_prefix(path): return os.path.join(configs_path, path) config = get_config() configs_dir_mapping = config["config_path_to_dest_map"] for target, backup in configs_dir_mapping.items(): path_to_backup = backup_prefix(backup) dest_path = home_prefix(target) # TODO: REFACTOR WITH GENERIC COPY FUNCTION. if os.path.isdir(path_to_backup): copytree(path_to_backup, dest_path) elif os.path.isfile(path_to_backup): copyfile(path_to_backup, dest_path) print_section_header("CONFIG REINSTALLATION COMPLETED", Fore.BLUE)
def get_config_path(): return home_prefix(".shallow-backup")
def backup_packages(backup_path): """ Creates `packages` directory and places install list text files there. """ print_section_header("PACKAGES", Fore.BLUE) mkdir_warn_overwrite(backup_path) std_package_managers = ["brew", "brew cask", "gem"] for mgr in std_package_managers: # deal with package managers that have spaces in them. print_pkg_mgr_backup(mgr) command = "{} list".format(mgr) dest = "{}/{}_list.txt".format(backup_path, mgr.replace(" ", "-")) run_cmd_write_stdout(command, dest) # cargo print_pkg_mgr_backup("cargo") command = "ls {}".format(home_prefix(".cargo/bin/")) dest = "{}/cargo_list.txt".format(backup_path) run_cmd_write_stdout(command, dest) # pip print_pkg_mgr_backup("pip") command = "pip list --format=freeze".format(backup_path) dest = "{}/pip_list.txt".format(backup_path) run_cmd_write_stdout(command, dest) # npm print_pkg_mgr_backup("npm") command = "npm ls --global --parseable=true --depth=0" temp_file_path = "{}/npm_temp_list.txt".format(backup_path) run_cmd_write_stdout(command, temp_file_path) npm_dest_file = "{0}/npm_list.txt".format(backup_path) # Parse npm output with open(temp_file_path, mode="r+") as temp_file: # Skip first line of file temp_file.seek(1) with open(npm_dest_file, mode="w+") as dest: for line in temp_file: dest.write(line.split("/")[-1]) os.remove(temp_file_path) # atom package manager print_pkg_mgr_backup("Atom") command = "apm list --installed --bare" dest = "{}/apm_list.txt".format(backup_path) run_cmd_write_stdout(command, dest) # sublime text 2 packages sublime_2_path = home_prefix( "Library/Application Support/Sublime Text 2/Packages/") if os.path.isdir(sublime_2_path): print_pkg_mgr_backup("Sublime Text 2") command = ["ls", sublime_2_path] dest = "{}/sublime2_list.txt".format(backup_path) run_cmd_write_stdout(command, dest) # sublime text 3 packages sublime_3_path = home_prefix( "Library/Application Support/Sublime Text 3/Installed Packages/") if os.path.isdir(sublime_3_path): print_pkg_mgr_backup("Sublime Text 3") command = ["ls", sublime_3_path] dest = "{}/sublime3_list.txt".format(backup_path) run_cmd_write_stdout(command, dest) else: print(sublime_3_path, "IS NOT DIR") # macports print_pkg_mgr_backup("macports") command = "port installed requested" dest = "{}/macports_list.txt".format(backup_path) run_cmd_write_stdout(command, dest) # system installs print_pkg_mgr_backup("macOS Applications") command = "ls /Applications/" dest = "{}/system_apps_list.txt".format(backup_path) run_cmd_write_stdout(command, dest) # Clean up empty package list files print(Fore.BLUE + "Cleaning up empty package lists..." + Style.RESET_ALL) for file in get_subfiles(backup_path): if os.path.getsize(file) == 0: os.remove(file)