From 3f2d77b862027bb8db6ac59c723b661405e4d4df Mon Sep 17 00:00:00 2001 From: developomp Date: Thu, 7 Jul 2022 10:20:36 +0900 Subject: [PATCH] replace all usage of os.system with src.util.run - combine `system` and `silent_system` function int o `run` - remove `zsh_system` - replace alacritty terminal with kitty terminal --- setup.py | 29 ++++--- src/initialize.py | 7 +- src/setup/apps/discord.py | 8 +- src/setup/apps/nautilus.py | 22 +++--- src/setup/apps/osu_lazer.py | 15 ++-- src/setup/apps/pomky.py | 9 +-- src/setup/apps/tenacity.py | 8 +- src/setup/dev/docker.py | 7 +- src/setup/dev/git.py | 13 ++-- src/setup/dev/node.py | 17 +++-- src/setup/dev/rust.py | 11 ++- src/setup/dev/virtualbox.py | 9 +-- src/setup/dev/vscodium.py | 6 +- src/setup/system/fonts.py | 4 +- src/setup/system/fstab.py | 4 +- src/setup/system/gnome_extensions.py | 6 +- src/setup/system/zsh.py | 13 ++-- src/util.py | 109 ++++++++++++++++----------- 18 files changed, 152 insertions(+), 145 deletions(-) diff --git a/setup.py b/setup.py index 77a627e..45c88c7 100755 --- a/setup.py +++ b/setup.py @@ -17,24 +17,30 @@ tmp_dir = "/tmp/com.developomp.setup" # # Utility functions # -# These functions are copied from `src/util.py`. +# These functions are copied from `src/util.py` (except for cleanup). # Comments can only be found over there. # -def silent_system(command: str, suppress_error: bool = False) -> None: - if suppress_error: +def run(command: str, hide_stdout: bool = True, hide_stderr: bool = True): + if hide_stderr: system(f"{command} &> /dev/null") - else: + return + + if hide_stdout: system(f"{command} > /dev/null") + return + + system(command) -def run(command: str) -> list[str]: +def run_and_return(command: str) -> list[str]: return popen(command).readlines() def command_exists(command: str) -> bool: - return len(run(f"command -v {command}")) == 1 + return len(run_and_return(f"command -v {command}")) == 1 + def cleanup() -> None: """Remove temporary files downloaded or created by this script""" @@ -42,6 +48,7 @@ def cleanup() -> None: if exists(tmp_dir): rmtree(tmp_dir) + # # Check functions # @@ -96,7 +103,7 @@ def exit_if_no_internet(): """Exits script if there's no internet connection. Pings archlinux.org for testing.""" - if silent_system("ping -c 1 archlinux.org"): + if run("ping -c 1 archlinux.org"): print(" Failed to connect to the internet.", file=sys.stderr) exit(1) @@ -132,7 +139,7 @@ def install_git(): """Install git if it's not installed already.""" if not command_exists("git"): - system("sudo pacman -S --noconfirm --needed git") + run("sudo pacman -S --noconfirm --needed git") def clone_repository(): @@ -142,14 +149,12 @@ def clone_repository(): cleanup() # clone repository - if silent_system( - f"git clone --depth 1 https://github.com/developomp/setup.git {tmp_dir}" - ): + if run(f"git clone --depth 1 https://github.com/developomp/setup.git {tmp_dir}"): print(" Failed to clone repository", file=sys.stderr) exit(1) # allow everyone to read and write. - if system(f"chmod -R a+rw {tmp_dir}"): + if run(f"chmod -R a+rw {tmp_dir}"): print(" Failed to change file permission for cloned repo", file=sys.stderr) exit(1) diff --git a/src/initialize.py b/src/initialize.py index b56881e..8616045 100644 --- a/src/initialize.py +++ b/src/initialize.py @@ -1,16 +1,15 @@ -from os import system from src import log -from src.util import silent_system +from src.util import run def install_via_pacman(package: str): - if silent_system(f"paru -S --noconfirm {package}", True): + if run(f"paru -S --noconfirm {package}", True): log.error(f"Failed to install {package} via pacman") exit(1) def install_via_pip(package: str): - if silent_system(f"pip install {package}"): + if run(f"pip install {package}"): log.error(f"Failed to install {package} via pip") exit(1) diff --git a/src/setup/apps/discord.py b/src/setup/apps/discord.py index 2079fdf..3fbfdc2 100644 --- a/src/setup/apps/discord.py +++ b/src/setup/apps/discord.py @@ -1,6 +1,6 @@ -from src.util import flatpak_install, paru_install, copy_file +from src.util import flatpak_install, paru_install, copy_file, run from src import log -from os import system + name = "Discord" @@ -58,8 +58,8 @@ def setup(): log.log(f"installing {url}") # assumes that plugins is located in "~/.var/app/com.discordapp.Discord/config/BetterDiscord/plugins" because I'm using flatpak - system( + run( f'wget --content-disposition --no-clobber -P ~/.var/app/com.discordapp.Discord/config/BetterDiscord/plugins "{url}"' ) - system("betterdiscordctl -i flatpak install") + run("betterdiscordctl -i flatpak install") diff --git a/src/setup/apps/nautilus.py b/src/setup/apps/nautilus.py index e36ade5..89e531b 100644 --- a/src/setup/apps/nautilus.py +++ b/src/setup/apps/nautilus.py @@ -1,6 +1,6 @@ -from src.util import paru_install, load_dconf, command_exists -from src.setup.apps import alacritty -from os import system +from src.util import paru_install, load_dconf, command_exists, run +from src.setup.apps import terminal + name = "Nautilus" @@ -11,23 +11,21 @@ def setup(): paru_install( [ "nautilus", - "nautilus-open-any-terminal", # allow nautilus to use alacrittty terminal + "nautilus-open-any-terminal", # allow nautilus to use kitty terminal ] ) - if not command_exists("alacritty"): - alacritty.setup() + if not command_exists("kitty"): + terminal.setup() # set nautilus settings load_dconf("nautilus.conf") # set nautilus terminal settings - system( - "gsettings set com.github.stunkymonkey.nautilus-open-any-terminal terminal alacritty" + run( + "gsettings set com.github.stunkymonkey.nautilus-open-any-terminal terminal kitty" ) - system( + run( "gsettings set com.github.stunkymonkey.nautilus-open-any-terminal keybindings ''" ) - system( - "gsettings set com.github.stunkymonkey.nautilus-open-any-terminal new-tab true" - ) + run("gsettings set com.github.stunkymonkey.nautilus-open-any-terminal new-tab true") diff --git a/src/setup/apps/osu_lazer.py b/src/setup/apps/osu_lazer.py index 305485f..19a6967 100644 --- a/src/setup/apps/osu_lazer.py +++ b/src/setup/apps/osu_lazer.py @@ -1,9 +1,8 @@ -from os.path import exists -from os import system - -from src.util import flatpak_install, paru_install, copy_file, silent_system +from src.util import flatpak_install, paru_install, copy_file, run from src.setup.system import system76_scheduler +from os.path import exists + name = "osu!lazer" post_install = ["Install osu! skin from https://github.com/developomp/osu-pomp-skin"] @@ -38,15 +37,15 @@ def setup(): for name in modules_to_disable: # Add blacklist rule if it does not exist - silent_system( + run( f'sudo grep -qxF "blacklist {name}" /etc/modprobe.d/blacklist.conf || echo "blacklist {name}" | sudo tee -a /etc/modprobe.d/blacklist.conf' ) # remove module from kernel if it's loaded - silent_system(f"sudo rmmod {name}") + run(f"sudo rmmod {name}") # Reload the systemd user unit daemon - system("systemctl --user daemon-reload") + run("systemctl --user daemon-reload") # Enable and start the user service - system("systemctl --user enable opentabletdriver --now") + run("systemctl --user enable opentabletdriver --now") diff --git a/src/setup/apps/pomky.py b/src/setup/apps/pomky.py index 4b1b519..03f9d40 100644 --- a/src/setup/apps/pomky.py +++ b/src/setup/apps/pomky.py @@ -1,5 +1,4 @@ -from os import system -from src.util import silent_system, copy_file +from src.util import run, copy_file from src.constants import tmp_dir name = "pomky" @@ -8,8 +7,6 @@ name = "pomky" def setup(): """conky but rusty""" - silent_system( - f"git clone --depth 1 https://github.com/developomp/pomky {tmp_dir}/pomky" - ) - silent_system(f"cd {tmp_dir}/pomky && cargo install --path .") + run(f"git clone --depth 1 https://github.com/developomp/pomky {tmp_dir}/pomky") + run(f"cd {tmp_dir}/pomky && cargo install --path .") copy_file("home/.config/autostart/pomky.desktop") diff --git a/src/setup/apps/tenacity.py b/src/setup/apps/tenacity.py index 0839ae7..db5ea11 100644 --- a/src/setup/apps/tenacity.py +++ b/src/setup/apps/tenacity.py @@ -1,6 +1,6 @@ # https://github.com/tenacityteam/tenacity-flatpak-nightly -from os import system +from src.util import run name = "Tenacity" @@ -8,5 +8,7 @@ name = "Tenacity" def setup(): """Safe audacity fork""" - system("flatpak remote-add tenacity oci+https://tenacityteam.github.io/tenacity-flatpak-nightly") - system("flatpak install tenacity org.tenacityaudio.Tenacity") + run( + "flatpak remote-add tenacity oci+https://tenacityteam.github.io/tenacity-flatpak-nightly" + ) + run("flatpak install tenacity org.tenacityaudio.Tenacity") diff --git a/src/setup/dev/docker.py b/src/setup/dev/docker.py index 2e7f08b..a2f6c8d 100644 --- a/src/setup/dev/docker.py +++ b/src/setup/dev/docker.py @@ -1,5 +1,4 @@ -from src.util import paru_install -from os import system +from src.util import paru_install, run from getpass import getuser name = "Docker" @@ -10,5 +9,5 @@ def setup(): paru_install("docker") - system(f'sudo usermod -aG docker "{getuser()}"') - system("sudo systemctl --now enable docker") + run(f'sudo usermod -aG docker "{getuser()}"') + run("sudo systemctl --now enable docker") diff --git a/src/setup/dev/git.py b/src/setup/dev/git.py index d43d6f2..bb184c2 100644 --- a/src/setup/dev/git.py +++ b/src/setup/dev/git.py @@ -1,5 +1,4 @@ -from src.util import paru_install -from os import system +from src.util import paru_install, run name = "git" @@ -9,8 +8,8 @@ def setup(): paru_install("git") - system('git config --global user.email "developomp@gmail.com"') - system('git config --global user.name "developomp"') - system("git config --global pull.rebase false") - system("git config --global init.defaultBranch master") - system("git config --global credential.helper store") + run('git config --global user.email "developomp@gmail.com"') + run('git config --global user.name "developomp"') + run("git config --global pull.rebase false") + run("git config --global init.defaultBranch master") + run("git config --global credential.helper store") diff --git a/src/setup/dev/node.py b/src/setup/dev/node.py index 4551df1..0ee4158 100644 --- a/src/setup/dev/node.py +++ b/src/setup/dev/node.py @@ -1,11 +1,10 @@ -from os import system -from os.path import isdir - from src.constants import home_dir -from src.util import paru_install, zsh_system, command_exists +from src.util import paru_install, run, command_exists from src.setup.system import zsh from src import log +from os.path import isdir + name = "node" @@ -27,13 +26,15 @@ def setup(): paru_install("nvm") log.log("Installing Node.JS LTS") - zsh_system("source /usr/share/nvm/init-nvm.sh; nvm install --lts") + run("source /usr/share/nvm/init-nvm.sh; nvm install --lts") + + # todo: add "source /usr/share/nvm/init-nvm.sh" to ~/.zshrc log.log("Installing npm") - system("npm install --global npm") + run("npm install --global npm") log.log("Installing pnpm") - system("npm install --global pnpm") + run("npm install --global pnpm") log.log("Installing yarn") - system("npm install --global yarn") + run("npm install --global yarn") diff --git a/src/setup/dev/rust.py b/src/setup/dev/rust.py index a5e9169..e38ff36 100644 --- a/src/setup/dev/rust.py +++ b/src/setup/dev/rust.py @@ -1,12 +1,11 @@ -from src.util import paru_install -from os import system +from src.util import paru_install, run + name = "rust" def setup(): - """The next C""" + """C++ but modern""" - paru_install("rustup") - - system("rustup install stable") + paru_install(["rustup", "rust-analyzer"]) + run("rustup install stable") diff --git a/src/setup/dev/virtualbox.py b/src/setup/dev/virtualbox.py index e337ba2..8fa974b 100644 --- a/src/setup/dev/virtualbox.py +++ b/src/setup/dev/virtualbox.py @@ -1,5 +1,4 @@ -from src.util import paru_install -from os import system +from src.util import paru_install, run name = "virtualbox" @@ -15,6 +14,6 @@ def setup(): ] ) - system("sudo systemctl enable systemd-modules-load") - system("sudo systemctl start systemd-modules-load") - system("sudo modprobe vboxdrv") + run("sudo systemctl enable systemd-modules-load") + run("sudo systemctl start systemd-modules-load") + run("sudo modprobe vboxdrv") diff --git a/src/setup/dev/vscodium.py b/src/setup/dev/vscodium.py index 0c052e8..e11c3eb 100644 --- a/src/setup/dev/vscodium.py +++ b/src/setup/dev/vscodium.py @@ -1,6 +1,4 @@ -from os import system - -from src.util import paru_install, copy_file +from src.util import paru_install, copy_file, run name = "Vscodium" @@ -52,7 +50,7 @@ def setup(): # codium --list-extensions for extension in EXTENSIONS: - system(f"codium --install-extension {extension} --force") + run(f"codium --install-extension {extension} --force") # vscodium settings copy_file("home/.config/VSCodium/User/settings.json") diff --git a/src/setup/system/fonts.py b/src/setup/system/fonts.py index c965b50..6f20fdb 100644 --- a/src/setup/system/fonts.py +++ b/src/setup/system/fonts.py @@ -1,7 +1,7 @@ from src.util import paru_install, smart_mkdir, download, unzip from src.constants import tmp_dir, home_dir from shutil import rmtree, move -from os import remove, system +from os import remove from os.path import exists, basename import requests import glob @@ -61,7 +61,7 @@ def setup(): move(ttf_file_path, f"{FONT_INSTALL_DIR}/{basename(ttf_file_path)}") # regenerate font cache - system("fc-cache -vf") + run("fc-cache -vf") # cleanup rmtree(TMP_FONTS_DIRECTORY) diff --git a/src/setup/system/fstab.py b/src/setup/system/fstab.py index 988822a..3c5936c 100644 --- a/src/setup/system/fstab.py +++ b/src/setup/system/fstab.py @@ -1,4 +1,4 @@ -from os import system +from src.util import run name = "fstab" @@ -19,4 +19,4 @@ def setup(): # append a line to the end and ignore output # not using python's file interface because I don't wanna deal with permission stuff - system(f'echo "{line_to_write}" | sudo tee -a {fstab_path} >/dev/null') + run(f'echo "{line_to_write}" | sudo tee -a {fstab_path} >/dev/null') diff --git a/src/setup/system/gnome_extensions.py b/src/setup/system/gnome_extensions.py index 3807401..e9d701a 100644 --- a/src/setup/system/gnome_extensions.py +++ b/src/setup/system/gnome_extensions.py @@ -1,6 +1,4 @@ -from os import system - -from src.util import paru_install, load_dconf +from src.util import paru_install, load_dconf, run from src import log name = "GNOME extensions" @@ -41,7 +39,7 @@ def setup(): for (extension, dconf_file) in EXTENSIONS: log.log("installing: https://extensions.gnome.org/extension/$1") - system(f"gnome-shell-extension-installer {extension} --yes --update") + run(f"gnome-shell-extension-installer {extension} --yes --update") if dconf_file: # if dconf_file is not empty load_dconf(dconf_file) diff --git a/src/setup/system/zsh.py b/src/setup/system/zsh.py index 1affe5b..519fe39 100644 --- a/src/setup/system/zsh.py +++ b/src/setup/system/zsh.py @@ -1,9 +1,8 @@ -from src.util import paru_install, copy_file, trash +from src.util import paru_install, copy_file, trash, run from src.constants import home_dir from src import log from os.path import isdir -from os import system name = "Zsh" @@ -14,23 +13,21 @@ def setup(): paru_install("zsh") log.log("Installing Oh My Zsh") - system( + run( 'sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"' ) log.log("Installing powerlevel10k theme") p10k_path = f"{home_dir}/.oh-my-zsh/custom/themes/powerlevel10k" trash(p10k_path) - system( - f"git clone --depth=1 https://github.com/romkatv/powerlevel10k.git {p10k_path}" - ) + run(f"git clone --depth=1 https://github.com/romkatv/powerlevel10k.git {p10k_path}") log.log("Installing zsh syntax highlighter") zsh_syntax_highlighting_path = ( f"{home_dir}/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting" ) trash(zsh_syntax_highlighting_path) - system( + run( f"git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git {zsh_syntax_highlighting_path}" ) @@ -38,4 +35,4 @@ def setup(): copy_file("home/.zshrc") # set the default terminal to zsh - system("chsh -s /bin/zsh") + run("chsh -s /bin/zsh") diff --git a/src/util.py b/src/util.py index 5e25674..b91898f 100644 --- a/src/util.py +++ b/src/util.py @@ -8,7 +8,32 @@ from src.log import error import src.constants -def paru_install(packages: str | list[str]) -> None: +def run(command: str, hide_stdout: bool = True, hide_stderr: bool = True) -> None: + """os.system but has an option to hide stdout and/or stderr. + A copy of this function also exists in `setup.py`.""" + + if hide_stderr: + system(f"{command} &> /dev/null") + return + + if hide_stdout: + system(f"{command} > /dev/null") + return + + system(command) + + +def run_and_return(command: str) -> list[str]: + """Runs command in system shell and return the result. + This is a blocking function. + Use this if you want to get the output of the command.""" + + return popen(command).readlines() + + +def paru_install( + packages: str | list[str], hide_stdout: bool = True, hide_stderr: bool = True +) -> None: """ Download arch linux packages (including AUR). @@ -17,15 +42,19 @@ def paru_install(packages: str | list[str]) -> None: """ if type(packages) == str: - system(f"paru -S --noconfirm {packages}") + pass elif type(packages) == list: packages = " ".join(packages) - system(f"paru -S --noconfirm {packages}") else: error("Invalid paru packages format.") + return + + run(f"paru -S --noconfirm {packages}", hide_stdout, hide_stderr) -def flatpak_install(packages: str) -> None: +def flatpak_install( + packages: str, hide_stdout: bool = True, hide_stderr: bool = True +) -> None: """ Download packages from flathub. @@ -33,10 +62,10 @@ def flatpak_install(packages: str) -> None: packages: space-separated list of packages. """ - system(f"flatpak install -y {packages}") + run(f"flatpak install -y {packages}", hide_stdout, hide_stderr) -def smart_mkdir(path: str): +def smart_mkdir(path: str) -> None: """ Recursively create directories if it doesn't exist already. """ @@ -47,17 +76,23 @@ def smart_mkdir(path: str): pass -def trash(path): +def trash(path, hide_stdout: bool = True, hide_stderr: bool = True) -> None: """Moves a file or directory to freedesktop trash.""" try: - system(f"trash-put {path}") + run(f"trash-put {path}", hide_stdout, hide_stderr) except Exception as err: print(f"Failed to remove: {path}") raise err -def copy_file(src_file: str, mode="644", sudo=False): +def copy_file( + src_file: str, + mode="644", + sudo=False, + hide_stdout: bool = True, + hide_stderr: bool = True, +) -> None: """ Copies a file in the repo to the system. If the `src_file` starts with `home/`, it maps to $HOME. @@ -80,12 +115,14 @@ def copy_file(src_file: str, mode="644", sudo=False): command = f"install -Dm{mode} {src.constants.content_dir}/{src_file} {dst_file}" if sudo: - system(f"sudo {command}") - else: - system(command) + command = f"sudo {command}" + + run(command, hide_stdout, hide_stderr) -def copy_directory(src: str, dst: str): +def copy_directory( + src: str, dst: str, hide_stdout: bool = True, hide_stderr: bool = True +) -> None: """Copy a directory. Automatically creates parent directory/directories of dst if it does not exist already @@ -94,16 +131,22 @@ def copy_directory(src: str, dst: str): dst: A path-like object or string pointing to a directory. """ - system(f"cp -R {src} {dst}") + run(f"cp -R {src} {dst}", hide_stdout, hide_stderr) -def load_dconf(file_name: str): +def load_dconf( + file_name: str, hide_stdout: bool = True, hide_stderr: bool = True +) -> None: """Loads dconf configuration""" - system(f'dconf load / < "{src.constants.content_dir}/files/dconf/{file_name}"') + run( + f'dconf load / < "{src.constants.content_dir}/files/dconf/{file_name}"', + hide_stdout, + hide_stderr, + ) -def download(file_name: str, url: str): +def download(file_name: str, url: str) -> None: """Downloads a file from a url.""" r = requests.get(url) @@ -111,7 +154,7 @@ def download(file_name: str, url: str): f.write(r.content) -def unzip(zip_path: str, dst_dir: str): +def unzip(zip_path: str, dst_dir: str) -> None: """Unzips a .zip file to a directory.""" smart_mkdir(dst_dir) @@ -119,38 +162,12 @@ def unzip(zip_path: str, dst_dir: str): zip_ref.extractall(dst_dir) -def import_file(name, path): +def import_file(name, path) -> None: return SourceFileLoader(name, path).load_module() -def zsh_system(command: str) -> None: - """os.system but uses zsh. - The command should not contain a single quote (') that's not escaped. - Use this if the command has output you want to display in real time.""" - - system(f"/usr/bin/zsh -c '{command}'") - - -def silent_system(command: str, suppress_error: bool = False) -> None: - """os.system but does not show its log and error to the terminal. - A copy of this function also exists in `setup.py`.""" - - if suppress_error: - system(f"{command} &> /dev/null") - else: - system(f"{command} > /dev/null") - - -def run(command: str) -> list[str]: - """Runs command in system shell and return the result. - This is a blocking function. - Use this if you want to get the output of the command.""" - - return popen(command).readlines() - - def command_exists(command: str) -> bool: """Check if a command can be found in the current default shell. A copy of this function also exists in `setup.py`.""" - return len(run(f"command -v {command}")) == 1 + return len(run_and_return(f"command -v {command}")) == 1