diff options
| -rw-r--r-- | LICENSE | 21 | ||||
| -rw-r--r-- | Makefile | 13 | ||||
| -rw-r--r-- | README.md | 18 | ||||
| -rwxr-xr-x | bin/hiccup | 110 | ||||
| -rw-r--r-- | default-config.json | 17 |
5 files changed, 179 insertions, 0 deletions
@@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 seth + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..66a5f47 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +shell = /usr/bin/env bash +CONFIG = $(HOME)/.config +ifeq ($(XDG_CONFIG_HOME),) + CONFIG = $(XDG_CONFIG_HOME) +endif + +install: + install -Dm755 bin/hiccup $(DESTDIR)$(PREFIX)/bin/hiccup + install -Dm644 default-config.json $(DESTDIR)$(CONFIG)/hiccup/config.json + +uninstall: + rm $(DESTDIR)$(PREFIX)/bin/hiccup + rm $(DESTDIR)$(CONFIG)/hiccup/config.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..c20e341 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# hiccup + +hiccup is a python script that attempts to upgrade your system with multiple package managers. + +## how it works +hiccup reads from `$XDG_CONFIG_HOME/hiccup/config.json`. this file specifies distros (by their freedesktop id), shell plugin +managers, and other package managers, paired with a command that runs an update - see `default-config.json`. + +## how to install +hiccup only needs one command to install :) +```sh +make install +``` + +and to uninstall: +```sh +make uninstall +``` diff --git a/bin/hiccup b/bin/hiccup new file mode 100755 index 0000000..0354e92 --- /dev/null +++ b/bin/hiccup @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +import json +import platform +import os + +CONFIG_FILE = os.path.join(os.environ['XDG_CONFIG_HOME'], 'hiccup/config.json') +current_distro = platform.freedesktop_os_release()["ID"] + + +class DistroNotSupportedError(Exception): + def __init__(self, name): + self.message = '{} isn\'t supported yet'.format(name) + super().__init__(self.message) + + +class CommandFailedError(Exception): + def __init__(self, name): + self.message = 'failed to use {}'.format(name) + super().__init__(self.message) + + +class CurrentDistro: + def __init__(self, id: str): + try: + with open(CONFIG_FILE) as file: + data = json.load(file) + self.__system_update_cmds = data['system_update_cmds'] + self.__extra_cmds = data['extra_cmds'] + self.__shell_plugin_cmds = data['shell_plugin_cmds'] + self.__other_cmds = data['other_cmds'] + except Exception: + pass + + self.id = id + + if self.is_supported(): + self.update_cmd = self.get_update_cmd() + if self.has_extra_cmd(): + self.extra_cmd = self.get_extra_cmd() + else: + raise DistroNotSupportedError(self.id) + + def __get_cmd(self, dct: dict): + return dct[self.id] + + def __sudo_cmd(self, name: str, cmd: str): + result = os.system('sudo {}'.format(cmd)) + if result != 0: + raise CommandFailedError(name) + + def __sys_cmd(self, name: str, cmd: str): + result = os.system(cmd + ' > /dev/null 2>&1') + if result != 0: + raise CommandFailedError(name) + + def is_supported(self): + return self.id in self.__system_update_cmds + + def has_extra_cmd(self): + return self.id in self.__extra_cmds + + def get_update_cmd(self): + return self.__get_cmd(self.__system_update_cmds) + + def get_extra_cmd(self): + return self.__get_cmd(self.__extra_cmds) + + def update_system(self): + self.__sudo_cmd(self.id, self.update_cmd) + if self.has_extra_cmd(): + os.system(self.extra_cmd) + + def update_shell_plugins(self): + for shell, command in self.__shell_plugin_cmds.items(): + print('updating {} plugins...'.format(shell)) + self.__sys_cmd(shell, command) + + def update_other(self): + for name, command in self.__other_cmds.items(): + print('updating {}...'.format(name)) + self.__sys_cmd(name, command) + + def update_other_sudo(self): + for name, command in self.__other_cmds.item(): + print('updating {}...'.format(name)) + self.__sudo_cmd(name, command) + + def update_all(self): + self.update_system() + self.update_shell_plugins() + self.update_other() + + +def run(): + CurrentDistro(current_distro).update_all() + + +if __name__ == '__main__': + if os.geteuid() == 0: + print('please don\'t run this as root :(') + exit(1) + try: + run() + print('done!') + except Exception as e: + print(repr(e)) + exit(2) +else: + print('this script can only be run directly') + exit(3) diff --git a/default-config.json b/default-config.json new file mode 100644 index 0000000..0f0e609 --- /dev/null +++ b/default-config.json @@ -0,0 +1,17 @@ +{ + "system_update_cmds": { + "arch": "bash -c 'pacman -Sy --needed archlinux-keyring && pacman -Su'", + "debian": "bash -c 'apt update && apt upgrade'", + "fedora": "dnf upgrade" + }, + "extra_cmds": { + "arch": "aur sync --upgrades --rmdeps --sign --remove --verify" + }, + "shell_plugin_cmds": { + "fish": "fish -c 'fisher update'", + "zsh": "zsh -c 'source $HOME/.config/zsh/.antidote/antidote.zsh && antidote update'" + }, + "other_cmds": { + "neovim": "nvim --headless -c 'autocmd User PackerComplete quitall' -c 'PackerSync'" + } +} |
