def create_base_folder(path): """ Create base directory if needed """ basePath = pathlib.Path(path).parent # Check if the base folder is a file if basePath.exists(): # Check if the parent is a file or if its a symlink if basePath.is_file() or basePath.is_symlink(): logging.print_error( "Base directory is a file or link: {}".format(basePath)) return False # If not, it must be a directory, so we are ok else: return True # Create path and parents (or ignore if folder already exists) try: basePath.mkdir(parents=True, exist_ok=True) except Exception as error: logging.print_error( "Could not create parent folder \"{}\" due to following error: {}". format(basePath, error)) return False else: logging.print_verbose( "Parent folder dosent exist and was created: {}".format(basePath)) return True
def unlink_packages(): """ Unlink all files in packages_to_unlink """ for path in packages_to_unlink: if directories.is_folder(path): directories.delete_folder(path) elif directories.is_file(path): directories.delete_file(path) else: logging.print_error("Nothing to unlink")
def create_symlink(source, destination): """ Creates symlink from source to destination """ try: os.symlink(source, destination) except OSError as error: logging.print_error("Unable to create symlink: {}".format(error)) else: logging.print_verbose("Linking {} <-> {}".format(source, destination))
def copy_folder(source, destination): """ Copies frolder from source to destination """ try: copytree(source, destination) except IOError as error: logging.print_error("Unable to copy folder: {}".format(error)) else: logging.print_verbose("Copied {} --> {}".format(source, destination))
def delete_file(path): """ Deletes file """ try: os.remove(path) except OSError as error: logging.print_error("File Deletion Failed: {}".format(path)) else: logging.print_verbose("File Successfully Deleted: {}".format(path))
def is_file(path): """ Checks to see if path is a file """ try: if os.path.isfile(path): return True else: return False except OSError as error: logging.print_error("Path doesn't exist: {}".format(path))
def create_folder(path): """ Creates a folder """ try: os.makedirs(path) except OSError as error: logging.print_error( "Could not create folder \"{}\" due to following error: {}".format( path, error)) else: logging.print_verbose( "Folder doesn't exist and was created: {}".format(path))
def delete_folder(path): """ Deletes a folder """ basePath = pathlib.Path(path) if not basePath.exists(): logging.print_error("Folder doesn't exist: {}".format(path)) return try: if basePath.is_symlink(): basePath.unlink() else: shutil.rmtree(basePath) except OSError as error: logging.print_error( "Folder Deletion/Unsymlink Failed: {}".format(error)) else: logging.print_verbose("Folder Deleted Successfully: {}".format(path))
def main(): # Grab user inputted args from the module and make sure they entered some. args = arguments.get_arguments() if args is None: logging.print_error("Must pass arguments") sys.exit() config_file = None config_dict = {} package_list = [] try: config_file = open("config.yaml", "r") except IOError: logging.print_error("No configuration found") sys.exit() config_dict = yaml.load(config_file) # Grab list of directories from the config. for key, value in config_dict['options'].items(): if key.endswith("Package"): friendly_name = key[:-7] config_dict['options'][key]['package_name'] = friendly_name package_list.append(friendly_name) # Error checking for proper config if "base" not in config_dict['options']: logging.print_fatal( "Invalid config file, a base package needs to be defined") elif "dotfileDirectory" not in config_dict['options']['base']: logging.print_fatal("Missing dotfileDirectory in base package") # Grab the path of the dotfile directory dotfile_path = HOME_PATH + \ config_dict['options']['base']['dotfileDirectory'] + "/" # Install the files from the dotfiles. Symlinks the files from the # specified packages to the local system files. If the file or folder # already exists on the local system, delete it then symlink properly to # avoid errors. if args[0] == "Install": # Install all packages if args[1] == "all": for key, value in config_dict['options'].items(): if key.endswith("Package"): check_dotfile_locations(key, config_dict, dotfile_path, "Dirty") for key, value in config_dict['options'].items(): if key.endswith("Package"): if "commandsBefore" in value: options.run_commands( config_dict['options'][key]['commandsBefore'], config_dict['options'][key]['package_name']) install_package(key, config_dict, dotfile_path) if "commandsAfter" in value: options.run_commands( config_dict['options'][key]['commandsAfter'], config_dict['options'][key]['package_name']) logging.print_info("Complete installation complete") # The option to only install one package instead of all your dotfiles. elif args[1] in package_list: for key, value in config_dict['options'].items(): if key == args[1] + "Package": check_dotfile_locations(key, config_dict, dotfile_path, "Dirty") for key, value in config_dict['options'].items(): if key == args[1] + "Package": if "commandsBefore" in value: options.run_commands( config_dict['options'][key]["commandsBefore"]) install_package(key, config_dict, dotfile_path) if "commandsAfter" in value: options.run_commands( config_dict['options'][key]["commandsAfter"]) logging.print_info("{} installation complete".format(args[1])) else: logging.print_error("Invalid Package") # Refresh # ------- # Refreshs the symlinks with the current file. This is so users don't have to manually # move files around and can instead manage their dotfiles in one file. # TODO: Remove files with warning if they are gone from the config elif args[0] == "Refresh": if args[1] == "all": for key, value in config_dict['options'].items(): if key.endswith("Package"): if "commandsBefore" in value: options.run_commands( config_dict['options'][key]["commandsBefore"]) setup_package(key, config_dict, dotfile_path) if "commandsAfter" in value: options.run_commands( config_dict['options'][key]["commandsAfter"]) logging.print_info("Dotfile refresh complete") else: logging.print_error("Error 102 Please report to GH") # Unlink the source files. This doesn't really "unlink", instead it actually just # deletes the files. It collects a list of files to unlink then it goes through and # unlinks them all. # TODO: Add safety to make sure both the files exist elif args[0] == "Unlink": if args[1] == "all": for key, value in config_dict['options'].items(): if key.endswith("Package"): get_packages_to_unlink(key, config_dict, dotfile_path) unlink_packages() logging.print_info("Completele unlink complete") elif args[1] in package_list: for key, value in config_dict['options'].items(): if key == args[1] + "Package": get_packages_to_unlink(key, config_dict, dotfile_path) unlink_packages() logging.print_info("{} unlink complete".format(args[1])) else: logging.print_error("Invalid Package") else: logging.print_error("Invalid Command")