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 backup_dotfiles(backup_path): """ Create `dotfiles` dir and makes copies of dotfiles and dotfolders. """ print_section_header("DOTFILES", Fore.BLUE) mkdir_warn_overwrite(backup_path) # assumes dotfiles are stored in home directory home_path = os.path.expanduser('~') # get dotfolders and dotfiles config = get_config() dotfiles_for_backup = config["dotfiles"] dotfolders_for_backup = config["dotfolders"] # Add dotfile/folder for backup if it exists on the machine dotfiles = [ file for file in dotfiles_for_backup if os.path.isfile(os.path.join(home_path, file)) ] dotfolders = [ folder for folder in dotfolders_for_backup if os.path.exists(os.path.join(home_path, folder)) ] # dotfiles/folders multiprocessing format: [(full_dotfile_path, full_dest_path), ...] dotfolders_mp_in = [] for dotfolder in dotfolders: dotfolders_mp_in.append((os.path.join(home_path, dotfolder), backup_path)) dotfiles_mp_in = [] for dotfile in dotfiles: dotfiles_mp_in.append( (os.path.join(home_path, dotfile), os.path.join(backup_path, dotfile))) # Multiprocessing with mp.Pool(mp.cpu_count()): print(Fore.BLUE + Style.BRIGHT + "Backing up dotfolders..." + Style.RESET_ALL) for x in dotfolders_mp_in: x = list(x) mp.Process(target=copy_dir, args=( x[0], x[1], )).start() with mp.Pool(mp.cpu_count()): print(Fore.BLUE + Style.BRIGHT + "Backing up dotfiles..." + Style.RESET_ALL) for x in dotfiles_mp_in: x = list(x) mp.Process(target=copyfile, args=( x[0], x[1], )).start()
def reinstall_packages_sb(packages_path): """ Reinstall all packages from the files in backup/installs. """ print_section_header("REINSTALLING PACKAGES", Fore.BLUE) # Figure out which install lists they have saved package_mgrs = set() for file in os.listdir(packages_path): manager = file.split("_")[0].replace("-", " ") if manager in [ "gem", "brew-cask", "cargo", "npm", "pip", "brew", "apm", "macports" ]: package_mgrs.add(file.split("_")[0]) print_blue_bold("Package Manager Backups Found:") for mgr in package_mgrs: print_yellow("\t{}".format(mgr)) print() # TODO: Multithreading for reinstallation. # construct commands for pm in package_mgrs: if pm in ["brew", "brew-cask"]: pm_formatted = pm.replace("-", " ") print_pkg_mgr_reinstall(pm_formatted) cmd = "xargs {0} install < {1}/{2}_list.txt".format( pm.replace("-", " "), packages_path, pm_formatted) run_cmd(cmd) elif pm == "npm": print_pkg_mgr_reinstall(pm) cmd = "cat {0}/npm_list.txt | xargs npm install -g".format( packages_path) run_cmd(cmd) elif pm == "pip": print_pkg_mgr_reinstall(pm) cmd = "pip install -r {0}/pip_list.txt".format(packages_path) run_cmd(cmd) elif pm == "apm": print_pkg_mgr_reinstall(pm) cmd = "apm install --packages-file {0}/apm_list.txt".format( packages_path) run_cmd(cmd) elif pm == "macports": print_red_bold( "WARNING: Macports reinstallation is not supported.") elif pm == "gem": print_red_bold("WARNING: Gem reinstallation is not supported.") elif pm == "cargo": print_red_bold( "WARNING: Cargo reinstallation is not possible at the moment." "\n -> https://github.com/rust-lang/cargo/issues/5593") print_section_header("PACKAGE REINSTALLATION COMPLETED", Fore.BLUE)
def reinstall_fonts_sb(fonts_path): """ Reinstall all fonts. TODO: MAKE LINUX/WINDOWS COMPATIBLE. """ print_section_header("REINSTALLING FONTS", Fore.BLUE) # Copy every file in fonts_path to ~/Library/Fonts for font in get_abs_path_subfiles(fonts_path): # TODO: This doesn't work for some reason. (#145) copyfile(font, os.path.join("~/Library/Fonts", font.split("/")[-1])) print_section_header("FONT REINSTALLATION COMPLETED", Fore.BLUE)
def reinstall_dots_sb(dots_path): """ Reinstall all dotfiles and folders by copying them to the home dir. """ print_section_header("REINSTALLING DOTFILES", Fore.BLUE) home_path = os.path.expanduser('~') for file in get_abs_path_subfiles(dots_path): if os.path.isdir(file): copytree(file, home_path, symlinks=True) else: copyfile(file, home_path) print_section_header("DOTFILE REINSTALLATION COMPLETED", Fore.BLUE) pass
def reinstall_packages_from_lists(packages_path): """ Reinstall all packages from the files in backup/installs. """ print_section_header("REINSTALLING PACKAGES", Fore.BLUE) # Figure out which install lists they have saved package_mgrs = set() for file in os.listdir(packages_path): # print(file) manager = file.split("_")[0].replace("-", " ") # TODO: Add macports if manager in ["gem", "brew-cask", "cargo", "npm", "pip", "brew", "apm"]: package_mgrs.add(file.split("_")[0]) # TODO: USE print_pkg_mgr_reinstall() # TODO: Restylize this printing print(Fore.BLUE + Style.BRIGHT + "Package Managers detected:" + Style.RESET_ALL) for mgr in package_mgrs: print(Fore.BLUE + Style.BRIGHT + "\t" + mgr) print(Style.RESET_ALL) # TODO: Multithreading for reinstallation. # construct commands for pm in package_mgrs: if pm in ["brew", "brew-cask"]: pm_formatted = pm.replace("-", " ") print(Fore.BLUE + Style.BRIGHT + "Reinstalling {} packages...".format(pm_formatted) + Style.RESET_ALL) cmd = "xargs {0} install < {1}/{2}_list.txt".format(pm.replace("-", " "), packages_path, pm_formatted) run_cmd(cmd) elif pm == "npm": print(Fore.BLUE + Style.BRIGHT + "Reinstalling {} packages...".format(pm) + Style.RESET_ALL) cmd = "cat {0}/npm_list.txt | xargs npm install -g".format(packages_path) run_cmd(cmd) elif pm == "pip": print(Fore.BLUE + Style.BRIGHT + "Reinstalling {} packages...".format(pm) + Style.RESET_ALL) cmd = "pip install -r {0}/pip_list.txt".format(packages_path) run_cmd(cmd) elif pm == "apm": print(Fore.BLUE + Style.BRIGHT + "Reinstalling {} packages...".format(pm) + Style.RESET_ALL) cmd = "apm install --packages-file {0}/apm_list.txt".format(packages_path) run_cmd(cmd) elif pm == "macports": print(Fore.RED + "WARNING: Macports reinstallation is not supported." + Style.RESET_ALL) elif pm == "gem": print(Fore.RED + "WARNING: Gem reinstallation is not supported." + Style.RESET_ALL) elif pm == "cargo": print(Fore.RED + "WARNING: Cargo reinstallation is not possible at the moment." "\n -> https://github.com/rust-lang/cargo/issues/5593" + Style.RESET_ALL) print_section_header("SUCCESSFUL PACKAGE 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 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_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)