Last active
April 26, 2024 07:29
-
-
Save koiralakiran1/2d9a28c7cf42c64cd744b17371630e7e to your computer and use it in GitHub Desktop.
How I used to setup my device.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# pylint: disable=line-too-long,missing-module-docstring | |
import os | |
import sys | |
import logging | |
import platform | |
import subprocess | |
class SetupDevice(): | |
"""Executes my new device setup flows""" | |
logger: logging.Logger | |
ssh_setup_script = 'https://gist.githubusercontent.com/koiralakiran1/fd33f2b6162f827a0a90a7c45011df53/raw/8dca96fcf5ea49b3c353fa6f437da28bb1c7baef/setup_github_ssh_keys.sh' | |
default_browser_preference = 'brave-bin' # Pacman's "brave-browser" doesn't work for some reason | |
# Dotfiles specific config | |
clone_directory = os.path.expanduser('~/dotfiles') | |
link_files_script_path_in_dotfiles = 'v2/home/.scripts/link_files.py' | |
def __init__(self) -> None: | |
self.logger = self._get_logger() | |
def _get_logger(self): | |
handler = logging.StreamHandler() | |
handler.setLevel(logging.NOTSET) | |
handler.setFormatter(self._CustomFormatter()) | |
logger = logging.getLogger('SetupDevice') | |
logger.setLevel(logging.DEBUG) | |
logger.addHandler(handler) | |
return logger | |
def _ask_yes_no(self, question: str, defaultValue = 'no'): | |
answer = input(f'{question} (y/n/yes/no, default = {defaultValue}): ') or defaultValue | |
return answer.lower() == 'yes' or answer.lower() == 'y' | |
def _exec_full(self, filepath): | |
global_namespace = { | |
"__file__": filepath, | |
"__name__": "__main__", | |
} | |
with open(filepath, 'rb') as file: | |
exec(compile(file.read(), filepath, 'exec'), global_namespace) | |
def _sync_packages(self): | |
if self._ask_yes_no('Sync packages?', 'y'): | |
self.logger.info('Syncing pacman package list. (sudo pacman -Sy)') | |
subprocess.run(['sudo', 'pacman', '-Sy'], check=True) | |
def _instal_necessary_utilities(self): | |
self.logger.info('Installing yay and necessary utilities using pacman..') | |
subprocess.run(['sudo', 'pacman', '-S', '--needed', 'curl', 'wget', 'bash', 'git', 'base-devel', 'yay'], check=True) | |
def _install_preferred_browser(self): | |
preferred_browser = input(f'Enter preferred browser (default = {self.default_browser_preference}): ') or self.default_browser_preference | |
self.logger.info('Installing %s...', preferred_browser) | |
subprocess.run(['yay', '-S', '--needed', preferred_browser], check=True) | |
self.logger.info('Now open %s and sync it; Setup password manager, accounts etc.', preferred_browser) | |
input('Press any key to continue...') | |
def _setup_github_ssh_access(self): | |
""" | |
Setup ssh access to github. Using existing shell file from gist | |
TODO: Make python version of the shell file | |
""" | |
if not self._ask_yes_no('Do you have git ssh setup already?'): | |
self.logger.info('Setting up new github ssh access') | |
self.logger.info('Running "%s"', self.ssh_setup_script) | |
os.system(f'bash <(curl -s {self.ssh_setup_script})') | |
self.logger.info('Github ssh access setup complete!') | |
else: | |
self.logger.info('Skipping ssh setup...') | |
def _clone_dotfiles(self): | |
dotfiles_profile = input('Enter github profile to clone "dotfiles" repo from: ') | |
dotfiles_link = f'git@github.com:{dotfiles_profile}/dotfiles.git' | |
# Backup existing dotfiles if any | |
self.logger.info('Backing up existing dotfiles if exists') | |
subprocess.run(['mv', '-f', self.clone_directory, f'{self.clone_directory}.bkp'], check=False) | |
# Clone dotfiles | |
self.logger.info('Cloning dotfiles from %s to %s', dotfiles_link, self.clone_directory) | |
subprocess.run(['git', 'clone', dotfiles_link, self.clone_directory], check=True) | |
self.logger.info('Dotfiles cloned!') | |
def _execute_link_files(self): | |
if self._ask_yes_no('Link files?'): | |
self.logger.info('Executing link-files') | |
self._exec_full(os.path.expanduser(f'{self.clone_directory}/{self.link_files_script_path_in_dotfiles}')) | |
self.logger.info('Linked files!') | |
def _install_package_list(self): | |
if self._ask_yes_no('Install ~/.packagelist?', 'yes'): | |
subprocess.run(['install-packagelist'], check=True) # alias install-packagelist="yay -S --needed --noconfirm - < ~/.packagelist" | |
self.logger.info('All packages from packagelist are installed!') | |
class _CustomFormatter(logging.Formatter): | |
"""Custom log formatter""" | |
grey = "\x1b[38m" | |
green = "\x1B[32m" | |
yellow = "\x1b[33m" | |
red = "\x1b[31m" | |
bold_red = "\x1b[31;1m" | |
reset = "\x1b[0m" | |
message_format = "%(asctime)s - %(name)s - %(levelname)s -> %(message)s (%(filename)s:%(lineno)d)" | |
FORMATS = { | |
logging.DEBUG: grey + message_format + reset, | |
logging.INFO: green + message_format + reset, | |
logging.WARNING: yellow + message_format + reset, | |
logging.ERROR: red + message_format + reset, | |
logging.CRITICAL: bold_red + message_format + reset | |
} | |
def format(self, record): | |
log_fmt = self.FORMATS.get(record.levelno) | |
formatter = logging.Formatter(log_fmt) | |
return formatter.format(record) | |
def main(self): | |
"""Main function to run setup device flow""" | |
self.logger.info('Setting up new system: %s', platform.node()) | |
self._sync_packages() | |
self._instal_necessary_utilities() | |
self._install_preferred_browser() | |
self._setup_github_ssh_access() | |
self._clone_dotfiles() | |
self._execute_link_files() | |
self.logger.info('Now install packagelist. Run `install-packagelist`') | |
self._install_package_list() | |
self.logger.info('Setup Complete!') | |
if __name__ == "__main__": | |
obj = SetupDevice() | |
sys.exit(obj.main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment