diff --git a/dotfiles_install.py b/dotfiles_install.py index ef13872..688009a 100644 --- a/dotfiles_install.py +++ b/dotfiles_install.py @@ -2,17 +2,21 @@ from lib import Input, Print, Install, Path import os from datetime import datetime + def make_backup(files_dir): - if Input.yes_no('Do you wish to create a backup of current state of your dotfiles?'): + if Input.yes_no( + 'Do you wish to create a backup of current state of your dotfiles?' + ): Print.action('Creating dotfiles backup') backup_dir = str(datetime.now()).replace(' ', '--') - current_backup_dir = os.path.join(Path.get_parent(__file__), 'Backups', backup_dir) + current_backup_dir = os.path.join(Path.get_parent(__file__), 'Backups', + backup_dir) Path.ensure_dirs(current_backup_dir) for file in Path.get_all_files(files_dir): - from_pos = os.path.join( - Path.get_home(), file.replace(f'{files_dir}/', '')) - to_pos = os.path.join( - current_backup_dir, file.replace(f'{files_dir}/', '')) + from_pos = os.path.join(Path.get_home(), + file.replace(f'{files_dir}/', '')) + to_pos = os.path.join(current_backup_dir, + file.replace(f'{files_dir}/', '')) if Path.check_file_exists(from_pos): Path.copy(from_pos, to_pos) @@ -25,14 +29,17 @@ def make_backup(files_dir): def check_installation(): if Install.check_not_installed('zsh'): - if not Install.package('zsh', 'default + (This is required shell for dotfiles)'): + if not Install.package( + 'zsh', 'default + (This is required shell for dotfiles)'): Print.err('Dotfiles installation cancelled - zsh not installed') return False global oh_my_zsh_path, zsh_highlight_path zsh_highlight_path = None - if Path.check_file_exists('/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh'): + if Path.check_file_exists( + '/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh' + ): zsh_highlight_path = '/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh' oh_my_zsh_path = None @@ -55,7 +62,6 @@ def check_installation(): return False - def personalized_changes(file): if '.zshrc' in file: global oh_my_zsh_path, zsh_highlight_path @@ -65,17 +71,23 @@ def personalized_changes(file): filedata_old = filedata # Change path to oh-my-zsh - filedata = filedata.replace('"$HOME/.config/oh-my-zsh"', f'"{oh_my_zsh_path}"') + filedata = filedata.replace('"$HOME/.config/oh-my-zsh"', + f'"{oh_my_zsh_path}"') # Change path to zsh-color-highlight if zsh_highlight_path is not None: - original_path='/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh' - filedata = filedata.replace(f'source {original_path}', f'source {zsh_highlight_path}') + original_path = '/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh' + filedata = filedata.replace(f'source {original_path}', + f'source {zsh_highlight_path}') else: if Install.package('zsh-syntax-highlighting', 'default'): - zsh_highlight_path = Input.question('Please specify path to your zsh-syntax-highlighting plugin (blank=do not include)') + zsh_highlight_path = Input.question( + 'Please specify path to your zsh-syntax-highlighting plugin (blank=do not include)' + ) if zsh_highlight_path != '': - filedata = filedata.replace(f'source {original_path}', f'source {zsh_highlight_path}') + filedata = filedata.replace( + f'source {original_path}', + f'source {zsh_highlight_path}') else: filedata = filedata.replace(f'source {original_path}', f'') else: @@ -87,7 +99,9 @@ def personalized_changes(file): f.write(filedata) if 'vimrc' in file: - if not Input.yes_no('Do you wish to use .vimrc (If you choose yes, please install Vundle or you will get errors)'): + if not Input.yes_no( + 'Do you wish to use .vimrc (If you choose yes, please install Vundle or you will get errors)' + ): # TODO: Install vundle return False return True @@ -95,25 +109,25 @@ def personalized_changes(file): def init(symlink): # Get path to files/ floder (contains all dotfiles) - files_dir = os.path.join( - Path.get_parent(__file__), 'files') + files_dir = os.path.join(Path.get_parent(__file__), 'files') # Create optional backup make_backup(files_dir) files_list, dirs_list = Path.get_all_dirs_and_files(files_dir) # Create all dirs for directory in dirs_list: - position = os.path.join( - Path.get_home(), directory.replace(f'{files_dir}/', '')) - Path.ensure_dirs(position) + if Path.check_dir_exists(directory): + position = os.path.join(Path.get_home(), + directory.replace(f'{files_dir}/', '')) + Path.ensure_dirs(position) # Go through all files for file in files_list: # Make personalized changes to files personalized_changes(file) # Set symlink position ($HOME/filepath) - position = os.path.join( - Path.get_home(), file.replace(f'{files_dir}/', '')) + position = os.path.join(Path.get_home(), + file.replace(f'{files_dir}/', '')) if symlink: # Make symlink @@ -129,7 +143,9 @@ def main(): return False choice = Input.multiple('Do you wish to create dotfiles', [ - 'symlinks (dotfiles/ dir will be required)', 'files (dotfiles/ dir can be removed afterwards)']) + 'symlinks (dotfiles/ dir will be required)', + 'files (dotfiles/ dir can be removed afterwards)' + ]) # Create symlinks if choice == 'symlinks (dotfiles/ dir will be required)': init(symlink=True) @@ -139,9 +155,11 @@ def main(): Print.warning( 'Do not delete this floder, all dotfile symlinks are linked to it') Print.warning( - 'Deletion would cause errors on all your dotfiles managed by this program') + 'Deletion would cause errors on all your dotfiles managed by this program' + ) Print.comment( - 'If you wish to remove this floder, please select files instead of symlinks for dotfile creation') + 'If you wish to remove this floder, please select files instead of symlinks for dotfile creation' + ) # Create files elif choice == 'files (dotfiles/ dir can be removed afterwards)': diff --git a/lib.py b/lib.py index 2fe09b6..15430e5 100644 --- a/lib.py +++ b/lib.py @@ -35,8 +35,9 @@ class Command: str -- stdout ''' command = command.split(' ') - return subprocess.run( - command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).stdout.decode('utf-8') + return subprocess.run(command, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE).stdout.decode('utf-8') def get_return_code(command): '''Get return code of command @@ -48,8 +49,9 @@ class Command: int -- returncode ''' command = command.split(' ') - return subprocess.run( - command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).returncode + return subprocess.run(command, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE).returncode class Color: @@ -206,9 +208,12 @@ class Input: Print.question(text) return input(' >>') -class Install: - def _generate_install_text(install_text, package_name, yay=False, git=False): +class Install: + def _generate_install_text(install_text, + package_name, + yay=False, + git=False): if install_text == 'default': install_text = f'Do you wish to install {package_name}?' if install_text[:10] == 'default + ': @@ -247,13 +252,15 @@ class Install: package_name = package_name.split(' ') elif type(package_name) != list: Print.err( - 'Function Install.check_not_installed() only accepts string or list parameters') + 'Function Install.check_not_installed() only accepts string or list parameters' + ) raise TypeError( 'check_not_installed() only takes string or list parameters') if package_name == ['base-devel']: # Check dependencies for base-devel (group packages are not detected directly) return Install.check_not_installed( - 'guile libmpc autoconf automake binutils bison fakeroot file findutils flex gawk gcc gettext grep groff gzip libtool m4 make pacman patch pkgconf sed sudo texinfo which') + 'guile libmpc autoconf automake binutils bison fakeroot file findutils flex gawk gcc gettext grep groff gzip libtool m4 make pacman patch pkgconf sed sudo texinfo which' + ) for package in package_name: if Install.check_installed(package): return False @@ -277,18 +284,21 @@ class Install: if Install.check_not_installed('git'): Print.warning( - f'Unable to install AUR repository: {repository}, git is not installed') + f'Unable to install AUR repository: {repository}, git is not installed' + ) return False # Base-devel group includes (required for makepkg) if Install.check_not_installed('base-devel'): Print.warning( - f'Unable to install AUR repository: {repository}, base-devel is not installed') + f'Unable to install AUR repository: {repository}, base-devel is not installed' + ) return False if Install.check_not_installed(repository) or force: - install_text = Install._generate_install_text( - install_text, repository, git=True) + install_text = Install._generate_install_text(install_text, + repository, + git=True) if Input.yes_no(install_text): url = f'https://aur.archlinux.org/{repository}.git' Command.execute(f'git clone {url}') @@ -302,10 +312,14 @@ class Install: return False else: Print.cancel( - f'assuming {repository} already installed ({repository} is installed)') + f'assuming {repository} already installed ({repository} is installed)' + ) return True - def package(package_name, install_text='default', aur=False, reinstall=False): + def package(package_name, + install_text='default', + aur=False, + reinstall=False): '''Installation of package Arguments: @@ -322,11 +336,13 @@ class Install: if aur: if Install.check_not_installed('yay'): Print.cancel( - f'Unable to install with yay (not installed), installing AUR package: {package_name} with git instead') + f'Unable to install with yay (not installed), installing AUR package: {package_name} with git instead' + ) Install.git_aur(package_name, install_text) if Install.check_not_installed(package_name) or reinstall: - install_text = Install._generate_install_text( - install_text, package_name, yay=aur) + install_text = Install._generate_install_text(install_text, + package_name, + yay=aur) if Input.yes_no(install_text): if aur: Command.execute(f'yay -S {package_name}') @@ -340,7 +356,10 @@ class Install: Print.cancel(f'{package_name} already installed') return True - def multiple_packages(packages, install_text, options=False, reinstall=False): + def multiple_packages(packages, + install_text, + options=False, + reinstall=False): '''Installation of multiple packages Arguments: @@ -370,7 +389,9 @@ class Install: return False def upgrade_pacman(): - if Input.yes_no('Do you wish to Sync(S), refresh(y) and upgrade(u) pacman - Recommended?'): + if Input.yes_no( + 'Do you wish to Sync(S), refresh(y) and upgrade(u) pacman - Recommended?' + ): Command.execute('sudo pacman -Syu') else: Print.warning('Pacman upgrade cancelled.') @@ -461,7 +482,7 @@ class Path: dirs_found.append(os.path.join(subdir, directory)) return files_found, dirs_found - def ensure_dirs(path, absolute_path=True): + def ensure_dirs(path, file_end=False, absolute_path=True): '''Ensure existence of directories (usually before creating files in it) Arguments: @@ -473,7 +494,7 @@ class Path: ''' if not absolute_path: path = pathlib.Path(path).absolute() - if Path.check_file_exists(path): + if Path.check_file_exists(path) or file_end: path = Path.get_parent(path) if not Path.check_dir_exists(path): @@ -495,7 +516,7 @@ class Path: symlink_pointer {str} -- path where symlink should be pointing path {str} -- path in which the symlink should be created ''' - Path.ensure_dirs(path) + Path.ensure_dirs(path, file_end=True) Command.execute(f'ln -sf {symlink_pointer} {path}') Print.comment(f'Created symlink: {path} -> {symlink_pointer}') @@ -506,6 +527,6 @@ class Path: path {str} -- path to original file copied_path {str} -- path to new file ''' - Path.ensure_dirs(copied_path) + Path.ensure_dirs(copied_path, file_end=True) Command.execute(f'cp {path} {copied_path}') Print.comment(f'Copied {path} to {copied_path}')