BUGFIX: ensure_dir function

This commit is contained in:
koumakpet 2020-03-29 17:59:24 +02:00
parent 7e9cc80a0e
commit 08c0933b27
2 changed files with 87 additions and 48 deletions

View file

@ -2,17 +2,21 @@ from lib import Input, Print, Install, Path
import os import os
from datetime import datetime from datetime import datetime
def make_backup(files_dir): 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') Print.action('Creating dotfiles backup')
backup_dir = str(datetime.now()).replace(' ', '--') 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) Path.ensure_dirs(current_backup_dir)
for file in Path.get_all_files(files_dir): for file in Path.get_all_files(files_dir):
from_pos = os.path.join( from_pos = os.path.join(Path.get_home(),
Path.get_home(), file.replace(f'{files_dir}/', '')) file.replace(f'{files_dir}/', ''))
to_pos = os.path.join( to_pos = os.path.join(current_backup_dir,
current_backup_dir, file.replace(f'{files_dir}/', '')) file.replace(f'{files_dir}/', ''))
if Path.check_file_exists(from_pos): if Path.check_file_exists(from_pos):
Path.copy(from_pos, to_pos) Path.copy(from_pos, to_pos)
@ -25,14 +29,17 @@ def make_backup(files_dir):
def check_installation(): def check_installation():
if Install.check_not_installed('zsh'): 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') Print.err('Dotfiles installation cancelled - zsh not installed')
return False return False
global oh_my_zsh_path, zsh_highlight_path global oh_my_zsh_path, zsh_highlight_path
zsh_highlight_path = None 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' zsh_highlight_path = '/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh'
oh_my_zsh_path = None oh_my_zsh_path = None
@ -55,7 +62,6 @@ def check_installation():
return False return False
def personalized_changes(file): def personalized_changes(file):
if '.zshrc' in file: if '.zshrc' in file:
global oh_my_zsh_path, zsh_highlight_path global oh_my_zsh_path, zsh_highlight_path
@ -65,17 +71,23 @@ def personalized_changes(file):
filedata_old = filedata filedata_old = filedata
# Change path to oh-my-zsh # 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 # Change path to zsh-color-highlight
if zsh_highlight_path is not None: if zsh_highlight_path is not None:
original_path='/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh' 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}') filedata = filedata.replace(f'source {original_path}',
f'source {zsh_highlight_path}')
else: else:
if Install.package('zsh-syntax-highlighting', 'default'): 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 != '': 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: else:
filedata = filedata.replace(f'source {original_path}', f'') filedata = filedata.replace(f'source {original_path}', f'')
else: else:
@ -87,7 +99,9 @@ def personalized_changes(file):
f.write(filedata) f.write(filedata)
if 'vimrc' in file: 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 # TODO: Install vundle
return False return False
return True return True
@ -95,16 +109,16 @@ def personalized_changes(file):
def init(symlink): def init(symlink):
# Get path to files/ floder (contains all dotfiles) # Get path to files/ floder (contains all dotfiles)
files_dir = os.path.join( files_dir = os.path.join(Path.get_parent(__file__), 'files')
Path.get_parent(__file__), 'files')
# Create optional backup # Create optional backup
make_backup(files_dir) make_backup(files_dir)
files_list, dirs_list = Path.get_all_dirs_and_files(files_dir) files_list, dirs_list = Path.get_all_dirs_and_files(files_dir)
# Create all dirs # Create all dirs
for directory in dirs_list: for directory in dirs_list:
position = os.path.join( if Path.check_dir_exists(directory):
Path.get_home(), directory.replace(f'{files_dir}/', '')) position = os.path.join(Path.get_home(),
directory.replace(f'{files_dir}/', ''))
Path.ensure_dirs(position) Path.ensure_dirs(position)
# Go through all files # Go through all files
@ -112,8 +126,8 @@ def init(symlink):
# Make personalized changes to files # Make personalized changes to files
personalized_changes(file) personalized_changes(file)
# Set symlink position ($HOME/filepath) # Set symlink position ($HOME/filepath)
position = os.path.join( position = os.path.join(Path.get_home(),
Path.get_home(), file.replace(f'{files_dir}/', '')) file.replace(f'{files_dir}/', ''))
if symlink: if symlink:
# Make symlink # Make symlink
@ -129,7 +143,9 @@ def main():
return False return False
choice = Input.multiple('Do you wish to create dotfiles', [ 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 # Create symlinks
if choice == 'symlinks (dotfiles/ dir will be required)': if choice == 'symlinks (dotfiles/ dir will be required)':
init(symlink=True) init(symlink=True)
@ -139,9 +155,11 @@ def main():
Print.warning( Print.warning(
'Do not delete this floder, all dotfile symlinks are linked to it') 'Do not delete this floder, all dotfile symlinks are linked to it')
Print.warning( 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( 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 # Create files
elif choice == 'files (dotfiles/ dir can be removed afterwards)': elif choice == 'files (dotfiles/ dir can be removed afterwards)':

67
lib.py
View file

@ -35,8 +35,9 @@ class Command:
str -- stdout str -- stdout
''' '''
command = command.split(' ') command = command.split(' ')
return subprocess.run( return subprocess.run(command,
command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).stdout.decode('utf-8') stderr=subprocess.STDOUT,
stdout=subprocess.PIPE).stdout.decode('utf-8')
def get_return_code(command): def get_return_code(command):
'''Get return code of command '''Get return code of command
@ -48,8 +49,9 @@ class Command:
int -- returncode int -- returncode
''' '''
command = command.split(' ') command = command.split(' ')
return subprocess.run( return subprocess.run(command,
command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).returncode stderr=subprocess.STDOUT,
stdout=subprocess.PIPE).returncode
class Color: class Color:
@ -206,9 +208,12 @@ class Input:
Print.question(text) Print.question(text)
return input(' >>') 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': if install_text == 'default':
install_text = f'Do you wish to install {package_name}?' install_text = f'Do you wish to install {package_name}?'
if install_text[:10] == 'default + ': if install_text[:10] == 'default + ':
@ -247,13 +252,15 @@ class Install:
package_name = package_name.split(' ') package_name = package_name.split(' ')
elif type(package_name) != list: elif type(package_name) != list:
Print.err( 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( raise TypeError(
'check_not_installed() only takes string or list parameters') 'check_not_installed() only takes string or list parameters')
if package_name == ['base-devel']: if package_name == ['base-devel']:
# Check dependencies for base-devel (group packages are not detected directly) # Check dependencies for base-devel (group packages are not detected directly)
return Install.check_not_installed( 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: for package in package_name:
if Install.check_installed(package): if Install.check_installed(package):
return False return False
@ -277,18 +284,21 @@ class Install:
if Install.check_not_installed('git'): if Install.check_not_installed('git'):
Print.warning( 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 return False
# Base-devel group includes (required for makepkg) # Base-devel group includes (required for makepkg)
if Install.check_not_installed('base-devel'): if Install.check_not_installed('base-devel'):
Print.warning( 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 return False
if Install.check_not_installed(repository) or force: if Install.check_not_installed(repository) or force:
install_text = Install._generate_install_text( install_text = Install._generate_install_text(install_text,
install_text, repository, git=True) repository,
git=True)
if Input.yes_no(install_text): if Input.yes_no(install_text):
url = f'https://aur.archlinux.org/{repository}.git' url = f'https://aur.archlinux.org/{repository}.git'
Command.execute(f'git clone {url}') Command.execute(f'git clone {url}')
@ -302,10 +312,14 @@ class Install:
return False return False
else: else:
Print.cancel( Print.cancel(
f'assuming {repository} already installed ({repository} is installed)') f'assuming {repository} already installed ({repository} is installed)'
)
return True 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 '''Installation of package
Arguments: Arguments:
@ -322,11 +336,13 @@ class Install:
if aur: if aur:
if Install.check_not_installed('yay'): if Install.check_not_installed('yay'):
Print.cancel( 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) Install.git_aur(package_name, install_text)
if Install.check_not_installed(package_name) or reinstall: if Install.check_not_installed(package_name) or reinstall:
install_text = Install._generate_install_text( install_text = Install._generate_install_text(install_text,
install_text, package_name, yay=aur) package_name,
yay=aur)
if Input.yes_no(install_text): if Input.yes_no(install_text):
if aur: if aur:
Command.execute(f'yay -S {package_name}') Command.execute(f'yay -S {package_name}')
@ -340,7 +356,10 @@ class Install:
Print.cancel(f'{package_name} already installed') Print.cancel(f'{package_name} already installed')
return True 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 '''Installation of multiple packages
Arguments: Arguments:
@ -370,7 +389,9 @@ class Install:
return False return False
def upgrade_pacman(): 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') Command.execute('sudo pacman -Syu')
else: else:
Print.warning('Pacman upgrade cancelled.') Print.warning('Pacman upgrade cancelled.')
@ -461,7 +482,7 @@ class Path:
dirs_found.append(os.path.join(subdir, directory)) dirs_found.append(os.path.join(subdir, directory))
return files_found, dirs_found 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) '''Ensure existence of directories (usually before creating files in it)
Arguments: Arguments:
@ -473,7 +494,7 @@ class Path:
''' '''
if not absolute_path: if not absolute_path:
path = pathlib.Path(path).absolute() 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) path = Path.get_parent(path)
if not Path.check_dir_exists(path): if not Path.check_dir_exists(path):
@ -495,7 +516,7 @@ class Path:
symlink_pointer {str} -- path where symlink should be pointing symlink_pointer {str} -- path where symlink should be pointing
path {str} -- path in which the symlink should be created 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}') Command.execute(f'ln -sf {symlink_pointer} {path}')
Print.comment(f'Created symlink: {path} -> {symlink_pointer}') Print.comment(f'Created symlink: {path} -> {symlink_pointer}')
@ -506,6 +527,6 @@ class Path:
path {str} -- path to original file path {str} -- path to original file
copied_path {str} -- path to new 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}') Command.execute(f'cp {path} {copied_path}')
Print.comment(f'Copied {path} to {copied_path}') Print.comment(f'Copied {path} to {copied_path}')