mirror of
https://github.com/ItsDrike/dotfiles.git
synced 2024-12-26 13:14:35 +00:00
remove deploy source
This commit is contained in:
parent
33cccffc7d
commit
20c1734cbc
|
@ -1,9 +0,0 @@
|
|||
if ! type "python3" &> /dev/null; then
|
||||
sudo pacman -S python
|
||||
fi
|
||||
if ! type "pip3" &> /dev/null; then
|
||||
sudo pacman -S python-pip
|
||||
fi
|
||||
|
||||
pip install -r requirements.txt
|
||||
python3 -m src
|
|
@ -1,5 +0,0 @@
|
|||
pyyaml
|
||||
psutil
|
||||
colorama
|
||||
pyinquirer
|
||||
inquirer
|
|
@ -1,26 +0,0 @@
|
|||
import sys
|
||||
|
||||
import colorama
|
||||
import inquirer.shortcuts
|
||||
|
||||
from src.arch_install import install_arch
|
||||
from src.dotfiles_install import install_dotfiles
|
||||
from src.package_install import install_packages
|
||||
from src.util.command import run_cmd
|
||||
|
||||
colorama.init(autoreset=True)
|
||||
|
||||
|
||||
if inquirer.shortcuts.confirm("Do you wish to perform Arch install? (Directly from live ISO)"):
|
||||
run_cmd("clear")
|
||||
print(f"{colorama.Fore.BLUE}Running Arch Installation")
|
||||
root_mountpoint = install_arch()
|
||||
print(f"{colorama.Fore.GREEN}Arch installation complete")
|
||||
print(f"{colorama.Fore.CYAN}To install packages and dotfiles, move this whole directory to the new installation and run it from there.")
|
||||
sys.exit()
|
||||
|
||||
if inquirer.shortcuts.confirm("Do you wish to perform package installation (from packages.yaml)"):
|
||||
install_packages()
|
||||
|
||||
if inquirer.shortcuts.confirm("Do you wish to install dotfiles? (from home and root folders)"):
|
||||
install_dotfiles()
|
|
@ -1,130 +0,0 @@
|
|||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import colorama
|
||||
import inquirer.shortcuts
|
||||
|
||||
from src.util.command import run_cmd, run_root_cmd
|
||||
from src.util.internet import connect_internet
|
||||
|
||||
colorama.init(autoreset=True)
|
||||
|
||||
|
||||
def mount_partition(partition_path: Path, mount_path: Optional[Path] = None, default_path: str = "/mnt") -> Path:
|
||||
"""
|
||||
Mount given `partition_path` to `mount_path`.;
|
||||
If `mount_path` wasn't provided, ask user for it.
|
||||
|
||||
After mounting, mount_path will be returned
|
||||
"""
|
||||
if not mount_path:
|
||||
mount_path = Path(inquirer.shortcuts.path(f"Specify mountpoint for {partition_path}", default=default_path))
|
||||
|
||||
if not mount_path.exists():
|
||||
run_root_cmd(f"mkdir -p {mount_path}")
|
||||
|
||||
run_root_cmd(f"mount {partition_path} {mount_path}")
|
||||
return mount_path
|
||||
|
||||
|
||||
def partition_disk() -> Path:
|
||||
"""Create all necessary partitions and return root mountpoint"""
|
||||
uefi = Path("/sys/firmware/efi/efivars").is_dir()
|
||||
|
||||
# Let user make partitions in shell environment
|
||||
partitions_made = inquirer.shortcuts.confirm("Do you already have partitions pre-made?")
|
||||
if not partitions_made:
|
||||
print(
|
||||
f"{colorama.Fore.CYAN}Dropping to shell environment, create your partitions here."
|
||||
" When you are done, use `exit` to return\n"
|
||||
f"{colorama.Style.DIM}This is {'UEFI' if uefi else 'LEGACY (BIOS)'} system\n"
|
||||
)
|
||||
run_cmd("exec $SHELL")
|
||||
|
||||
# Obtain partitions from user and mount them
|
||||
root_part = Path(inquirer.shortcuts.path("Specify the root partition (/dev/sdXY)", exists=True))
|
||||
if inquirer.shortcuts.confirm(f"Do you wish to make EXT4 filesystem on {root_part}?", default=True):
|
||||
run_root_cmd(f"mkfs.ext4 {root_part}")
|
||||
root_mountpoint = mount_partition(root_part)
|
||||
|
||||
if inquirer.shortcuts.confirm("Do you have an EFI partition?", default=uefi):
|
||||
if not uefi:
|
||||
print(
|
||||
f"{colorama.Fore.RED}Warning: Adding EFI partition from non-uefi system isn't adviced.\n"
|
||||
"While this process won't directly fail, you won't be able to install a bootloader from "
|
||||
"this computer. You can proceed, but you will have to use another computer to install the bootloader."
|
||||
)
|
||||
efi_part = Path(inquirer.shortcuts.path("Specify EFI partition (/dev/sdXY)", exists=True))
|
||||
if inquirer.shortcuts.confirm(f"Do you wish to make FAT32 filesystem on {efi_part}?", default=True):
|
||||
run_root_cmd(f"mkfs.fat -F32 {efi_part}")
|
||||
mount_partition(efi_part, default_path=str(Path(root_mountpoint, "boot")))
|
||||
elif uefi:
|
||||
print(
|
||||
f"{colorama.Fore.RED}Proceeding without EFI partition on UEFI system is not adviced, "
|
||||
"unless you want to run this OS with other UEFI capable system"
|
||||
)
|
||||
|
||||
if inquirer.shortcuts.confirm("Do you have a swap partition?"):
|
||||
swap_part = Path(inquirer.shortcuts.path("Specify the swap partition (/dev/sdXY)", exists=True))
|
||||
if inquirer.shortcuts.confirm(f"Do you wish to make swap system on {root_part}?", default=True):
|
||||
run_root_cmd(f"mkswap {swap_part}")
|
||||
if inquirer.shortcuts.confirm("Do you wish to turn on swap?", default=True):
|
||||
run_root_cmd(f"swapon {swap_part}")
|
||||
|
||||
while inquirer.shortcuts.confirm("Do you have any other partition?"):
|
||||
part_path = Path(inquirer.shortcuts.path("Specify partition path (/dev/sdXY)", exists=True))
|
||||
if inquirer.shortcuts.confirm("Do you wish to format this partition?"):
|
||||
print(f"{colorama.Fore.CYAN}Dropping to shell, format the partition here and type `exit` to return")
|
||||
run_cmd("exec $SHELL")
|
||||
mount_partition(part_path)
|
||||
|
||||
print(f"{colorama.Fore.LIGHTCYAN_EX}Printing disk report (with lsblk)")
|
||||
run_root_cmd("lsblk")
|
||||
if inquirer.shortcuts.confirm("Do you want to drop to shell and make some further adjustments?"):
|
||||
print(f"{colorama.Fore.CYAN}After you are done, return by typing `exit`")
|
||||
run_cmd("exec $SHELL")
|
||||
|
||||
print(f"{colorama.Fore.GREEN}Partitioning complete")
|
||||
return root_mountpoint
|
||||
|
||||
|
||||
def run_pacstrap(root_mountpoint: Path):
|
||||
mirror_setup = inquirer.shortcuts.confirm("Do you wish to setup your mirrors (This is necessary for fast downloads)?", default=True)
|
||||
if mirror_setup:
|
||||
print(
|
||||
f"{colorama.Fore.CYAN}Dropping to shell environment, setup your mirrors from here."
|
||||
" When you are done, use `exit` to return\n"
|
||||
f"{colorama.Style.DIM}Mirrors are located in `/etc/pacman.d/mirrorlist`\n"
|
||||
)
|
||||
run_cmd("exec $SHELL")
|
||||
|
||||
extra_pkgs = inquirer.shortcuts.checkbox(
|
||||
"You can choose to install additional packages with pacstrap here (select with space)",
|
||||
choices=["networkmanager", "base-devel", "vim", "nano"]
|
||||
)
|
||||
run_root_cmd(f"pacstrap {root_mountpoint} base linux linux-firmware {' '.join(extra_pkgs)}")
|
||||
|
||||
if inquirer.shortcuts.confirm("Do you wish to make some further adjustments and drop to shell?"):
|
||||
print(f"{colorama.Fore.CYAN}When you are done, use `exit` to return")
|
||||
run_cmd("exec $SHELL")
|
||||
|
||||
|
||||
def install_arch():
|
||||
"""Perform full Arch installation and return mountpoint and default user"""
|
||||
connect_internet()
|
||||
|
||||
run_root_cmd("timedatectl set-ntp true")
|
||||
root_mountpoint = partition_disk()
|
||||
run_pacstrap(root_mountpoint)
|
||||
print(f"{colorama.Fore.CYAN}Generating fstab")
|
||||
run_root_cmd(f"genfstab -U {root_mountpoint} >> {root_mountpoint}/etc/fstab")
|
||||
print(
|
||||
f"\n{colorama.Fore.GREEN}Core installation complete.\n"
|
||||
f"{colorama.Fore.YELLOW}Instalation within chroot environment is not possible from this script, "
|
||||
"run chroot_install.py within chroot environment.\n"
|
||||
f"{colorama.Fore.LIGHTBLUE_EX}Execute: {colorama.Style.BRIGHT}`arch-chroot /mnt`"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
install_arch()
|
|
@ -1,12 +0,0 @@
|
|||
import colorama
|
||||
|
||||
colorama.init(autoreset=True)
|
||||
|
||||
|
||||
def install_chroot():
|
||||
print(f"{colorama.Fore.RED}Sorry, chroot installation file is still WIP, for now, proceed manually.")
|
||||
print(f"{colorama.Fore.LIGHTCYAN_EX}You can use `arch-install-checklist.md` file which containes detailed installation steps.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
install_chroot()
|
|
@ -1,111 +0,0 @@
|
|||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import colorama
|
||||
import inquirer.shortcuts
|
||||
|
||||
from src.util.command import run_root_cmd
|
||||
|
||||
colorama.init(autoreset=True)
|
||||
|
||||
|
||||
def _find_all_files(path: Path):
|
||||
for subpath in path.iterdir():
|
||||
if subpath.is_dir():
|
||||
yield from _find_all_files(subpath)
|
||||
else:
|
||||
yield subpath
|
||||
|
||||
|
||||
def _walk_dotfiles():
|
||||
"""
|
||||
Walk through every stored file in repositorie's dotfiles,
|
||||
start by going through `home` specific files, and continue
|
||||
with `root` dotfiles.
|
||||
"""
|
||||
yield from _find_all_files(Path.cwd().joinpath("home"))
|
||||
yield from _find_all_files(Path.cwd().joinpath("root"))
|
||||
|
||||
|
||||
def _dotfile_to_system(dotfile_path: Path) -> Path:
|
||||
"""Convert dotfile path to corresponding path on real system"""
|
||||
base_dir = str(Path.cwd())
|
||||
|
||||
if base_dir + "/home/" in str(dotfile_path):
|
||||
rel_path = str(dotfile_path).replace(base_dir + "/home/", "")
|
||||
return Path.home().joinpath(rel_path)
|
||||
elif base_dir + "/root/" in str(dotfile_path):
|
||||
rel_path = str(dotfile_path).replace(base_dir + "/root/", "")
|
||||
return Path("/", rel_path)
|
||||
else:
|
||||
raise ValueError(f"Given path is not a valid dotfile path ({dotfile_path})")
|
||||
|
||||
|
||||
def make_backup() -> None:
|
||||
"""
|
||||
Find all files which will be replaced and back them up.
|
||||
Files which doesn't exist in the real system destination
|
||||
will be ignored.
|
||||
"""
|
||||
print(f"{colorama.Fore.LIGHTYELLOW_EX}Creating current dotfiles backup")
|
||||
time = str(datetime.now()).replace(" ", "--")
|
||||
backup_dir = Path.joinpath(Path.cwd(), "backup", time)
|
||||
backup_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for dotfile_path in _walk_dotfiles():
|
||||
real_path = _dotfile_to_system(dotfile_path)
|
||||
if not real_path.exists():
|
||||
continue
|
||||
|
||||
rel_path = str(dotfile_path).replace(str(Path.cwd()) + "/", "")
|
||||
backup_path = backup_dir.joinpath(rel_path)
|
||||
|
||||
# Ensure backup directory existence
|
||||
if real_path.is_dir():
|
||||
backup_path.mkdir(parents=True, exist_ok=True)
|
||||
else:
|
||||
backup_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"{colorama.Style.DIM}Backing up{real_path}")
|
||||
run_root_cmd(f"cp '{real_path}' '{backup_path}'", enable_debug=False)
|
||||
|
||||
print(f"{colorama.Fore.LIGHTYELLOW_EX}Backup complete")
|
||||
|
||||
|
||||
def overwrite_dotfiles() -> None:
|
||||
for dotfile_path in _walk_dotfiles():
|
||||
real_path = _dotfile_to_system(dotfile_path)
|
||||
# Ensure existence of system directory
|
||||
if dotfile_path.is_dir():
|
||||
real_path.mkdir(parents=True, exist_ok=True)
|
||||
else:
|
||||
dotfile_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# If we encounter placeholder file, making folder is suffictient
|
||||
# don't proceed with copying it to avoid clutterring the original system
|
||||
# with empty placeholder files, these files are here only for git to
|
||||
# recognize that directory
|
||||
if str(dotfile_path).endswith("placeholder"):
|
||||
continue
|
||||
|
||||
print(f"{colorama.Style.DIM}Overwriting {real_path}")
|
||||
run_root_cmd(f"cp '{dotfile_path}' '{real_path}'")
|
||||
|
||||
|
||||
def install_dotfiles() -> None:
|
||||
if inquirer.shortcuts.confirm("Do you want to backup current dotfiles? (Recommended)", default=True):
|
||||
make_backup()
|
||||
|
||||
print(f"{colorama.Fore.CYAN}Proceeding with dotfiles installation (this will overwrite your original files)")
|
||||
if inquirer.shortcuts.confirm(
|
||||
"Have you adjusted all dotfiles to your liking? "
|
||||
f"{colorama.Fore.RED}(proceeding without checking the dotfiles first isn't adviced){colorama.Fore.RESET}"
|
||||
):
|
||||
overwrite_dotfiles()
|
||||
print(f"{colorama.Fore.LIGHTYELLOW_EX}Dotfile installation complete, make sure to adjust the dotfiles to your liking.")
|
||||
else:
|
||||
print(f"{colorama.Fore.RED}Aborted...")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
install_dotfiles()
|
|
@ -1,45 +0,0 @@
|
|||
import typing as t
|
||||
|
||||
import colorama
|
||||
import inquirer.shortcuts
|
||||
import yaml
|
||||
|
||||
from src.util.command import run_root_cmd
|
||||
from src.util.package import InvalidPackage, Package, PackageAlreadyInstalled
|
||||
|
||||
colorama.init(autoreset=True)
|
||||
|
||||
|
||||
def obtain_packages() -> t.List[Package]:
|
||||
with open("packages.yaml") as f:
|
||||
yaml_file = yaml.safe_load(f)
|
||||
|
||||
pacman_packages = yaml_file["pacman"]
|
||||
aur_packages = yaml_file["aur"]
|
||||
git_packages = yaml_file["git"]
|
||||
|
||||
packages = []
|
||||
packages += Package.safe_load(pacman_packages)
|
||||
packages += Package.safe_load(git_packages, git=True)
|
||||
packages += Package.safe_load(aur_packages, aur=True)
|
||||
|
||||
return packages
|
||||
|
||||
|
||||
def install_packages() -> None:
|
||||
packages = obtain_packages()
|
||||
if inquirer.shortcuts.confirm("Do you wish to perform system upgrade first? (Recommended)", default=True):
|
||||
run_root_cmd("pacman -Syu")
|
||||
|
||||
for package in packages:
|
||||
try:
|
||||
print(f"{colorama.Fore.CYAN}Installing {package}")
|
||||
package.install()
|
||||
except PackageAlreadyInstalled:
|
||||
print(f"{colorama.Style.DIM}Package {package} is already installed, skipping")
|
||||
except InvalidPackage as e:
|
||||
print(f"{colorama.Fore.RED}{str(e)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
install_packages()
|
|
@ -1,47 +0,0 @@
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
import colorama
|
||||
import inquirer.shortcuts
|
||||
|
||||
DEBUG = True
|
||||
|
||||
|
||||
def debug_confirm_run(cmd):
|
||||
if DEBUG:
|
||||
cnfrm = inquirer.shortcuts.confirm(
|
||||
f"{colorama.Fore.BLUE}[DEBUG] Running command: "
|
||||
f"{colorama.Fore.YELLOW}{cmd}{colorama.Fore.RESET}"
|
||||
)
|
||||
return cnfrm
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def run_root_cmd(cmd: str, enable_debug: bool = True) -> subprocess.CompletedProcess:
|
||||
"""Run command as root"""
|
||||
if os.geteuid() != 0:
|
||||
return run_cmd(f"sudo {cmd}", enable_debug=enable_debug)
|
||||
else:
|
||||
return run_cmd(cmd, enable_debug=enable_debug)
|
||||
|
||||
|
||||
def run_cmd(cmd: str, capture_out: bool = False, enable_debug: bool = True) -> subprocess.CompletedProcess:
|
||||
"""Run given command"""
|
||||
args = {}
|
||||
if capture_out:
|
||||
args.update({"stdout": subprocess.PIPE, "stderr": subprocess.STDOUT})
|
||||
|
||||
if not enable_debug or debug_confirm_run(cmd):
|
||||
return subprocess.run(cmd, shell=True, **args)
|
||||
else:
|
||||
# If debug confirm wasn't confirmed, return code 1 (error)
|
||||
return subprocess.CompletedProcess(cmd, returncode=1)
|
||||
|
||||
|
||||
def command_exists(cmd) -> bool:
|
||||
"""Check if given command can be executed"""
|
||||
parts = cmd.split()
|
||||
executable = parts[0] if parts[0] != "sudo" else parts[1]
|
||||
proc = run_cmd(f"which {executable}", capture_out=True)
|
||||
return proc.returncode != 1
|
|
@ -1,95 +0,0 @@
|
|||
import sys
|
||||
import time
|
||||
import urllib.request
|
||||
from urllib.error import URLError
|
||||
|
||||
import colorama
|
||||
import inquirer.shortcuts
|
||||
|
||||
from src.util.command import command_exists, run_cmd, run_root_cmd
|
||||
|
||||
|
||||
def _connect_wifi() -> bool:
|
||||
"""
|
||||
Attempt to connect to internet using WiFI.
|
||||
|
||||
This uses `nmtui` with fallback to `iwctl`, if none
|
||||
of these tools are aviable, either quit or return False,
|
||||
if the tool was executed properly, return True
|
||||
|
||||
Note: True doesn't mean we connected, just that the tool was ran,
|
||||
it is up to user to use that tool properly and make the connection.
|
||||
"""
|
||||
if command_exists("nmtui"):
|
||||
run_root_cmd("nmtui")
|
||||
elif command_exists("iwctl"):
|
||||
run_root_cmd("iwctl")
|
||||
else:
|
||||
print(
|
||||
f"{colorama.Fore.RED}{colorama.Style.BRIGHT}ERROR: "
|
||||
"WiFi connection tool not found: `nmtui`/`iwctl`, please use Ethernet instead.\n"
|
||||
"Alternatively, connect manually outside of this script and re-run it."
|
||||
)
|
||||
opt = inquirer.shortcuts.list_input(
|
||||
"How do you wish to proceed?",
|
||||
choices=["Quit and connect manually", "Proceed with Ethernet"]
|
||||
)
|
||||
if opt == "Quit and connect manually":
|
||||
sys.exit()
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _connect_ethernet(max_wait_time: int = 20, iteration_time: int = 1) -> bool:
|
||||
"""
|
||||
Attempt to connect to internet using Ethernet.
|
||||
|
||||
This will simply wait for the user to plug in the ethernet cable,
|
||||
once that happens loop is interrupted and True is returned. In case
|
||||
it takes over the `max_wait_time`, loop ends and False is returned.
|
||||
|
||||
`iteration_time` is the time of each loop iteration, after whcih we
|
||||
check if connection is valid, if not, we continue iterating.
|
||||
"""
|
||||
print(f"{colorama.Style.DIM}Please plug in the Ethernet cable, waiting 20s")
|
||||
time_elapsed = 0
|
||||
while not check_connection() and time_elapsed < max_wait_time:
|
||||
time.sleep(iteration_time)
|
||||
time_elapsed += iteration_time
|
||||
|
||||
if time_elapsed >= max_wait_time:
|
||||
# We stopped because max wait time was crossed
|
||||
return False
|
||||
else:
|
||||
# We stopped because connection to internet was successful
|
||||
return True
|
||||
|
||||
|
||||
def connect_internet():
|
||||
wifi_possible = True
|
||||
|
||||
while not check_connection():
|
||||
run_cmd("clear")
|
||||
print(f"{colorama.Fore.RED}Internet connection unaviable")
|
||||
if wifi_possible:
|
||||
connect_opt = inquirer.shortcuts.list_input("How do you wish to connect to internet?", choices=["Wi-Fi", "Ethernet"])
|
||||
else:
|
||||
connect_opt = "Ethernet"
|
||||
|
||||
if connect_opt == "Wi-Fi":
|
||||
wifi_possible = _connect_wifi()
|
||||
else:
|
||||
if _connect_ethernet():
|
||||
break
|
||||
|
||||
print(f"{colorama.Fore.GREEN}Internet connection successful")
|
||||
|
||||
|
||||
def check_connection(host="https://google.com") -> bool:
|
||||
"""Check if system is connected to the internet"""
|
||||
try:
|
||||
urllib.request.urlopen(host)
|
||||
return True
|
||||
except URLError:
|
||||
return False
|
|
@ -1,113 +0,0 @@
|
|||
import os
|
||||
import typing as t
|
||||
from pathlib import Path
|
||||
|
||||
import colorama
|
||||
import inquirer.shortcuts
|
||||
|
||||
from src.util.command import run_cmd, run_root_cmd
|
||||
|
||||
colorama.init(autoreset=True)
|
||||
|
||||
|
||||
class InvalidPackage(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PackageAlreadyInstalled(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def is_installed(pkg: str) -> bool:
|
||||
"""Check if the package is already installed in the system"""
|
||||
return run_cmd(f"pacman -Qi {pkg}", capture_out=True).returncode != 1
|
||||
|
||||
|
||||
def pacman_install(package: str) -> None:
|
||||
"""Install given `package`"""
|
||||
run_root_cmd(f"pacman -S {package}")
|
||||
|
||||
|
||||
def yay_install(package: str) -> None:
|
||||
"""Install give package via `yay` (from AUR)"""
|
||||
run_cmd(f"yay -S {package}")
|
||||
|
||||
|
||||
def git_install(url: str) -> None:
|
||||
"""Clone a git repository with given `url`"""
|
||||
dir_name = Path(url.split("/")[-1].replace(".git", ""))
|
||||
if dir_name.exists():
|
||||
print(f"{colorama.Style.DIM}Git repository {dir_name} already exists")
|
||||
|
||||
ret_code = run_cmd(f"git clone {url}").returncode
|
||||
if ret_code == 128:
|
||||
print(f"{colorama.Fore.RED}Unable to install git repository {url}")
|
||||
return
|
||||
|
||||
if not Path(dir_name, "PKGBUILD").exists:
|
||||
print(f"{colorama.Fore.YELLOW}Git repository {dir_name} doesn't contain PKGBUILD, only downloaded.")
|
||||
return
|
||||
|
||||
if inquirer.shortcuts.confirm("Do you wish to run makepkg on the downloaded git repository?"):
|
||||
cwd = os.getcwd()
|
||||
os.chdir(dir_name)
|
||||
run_cmd("makepkg -si")
|
||||
os.chdir(cwd)
|
||||
run_cmd(f"rm -rf {dir_name}")
|
||||
else:
|
||||
os.makedirs("download")
|
||||
run_cmd(f"mv {dir_name} download/")
|
||||
print(f"{colorama.Style.DIM}Your git repository was cloned into `download/{dir_name}`")
|
||||
|
||||
|
||||
class Package:
|
||||
def __init__(self, name: str, aur: bool = False, git: bool = False):
|
||||
self.name = name
|
||||
self.aur = aur
|
||||
self.git = git
|
||||
|
||||
if self.git:
|
||||
self._resolve_git_package()
|
||||
|
||||
def _resolve_git_package(self) -> None:
|
||||
"""Figure out `git_url` variable from `name`."""
|
||||
if "/" not in self.name:
|
||||
raise InvalidPackage("You need to specify both author and repository name for git packages (f.e. `ItsDrike/dotfiles`)")
|
||||
|
||||
if "http://" in self.name or "https://" in self.name:
|
||||
self.git_url = self.name
|
||||
else:
|
||||
self.git_url = f"https://github.com/{self.name}"
|
||||
|
||||
def install(self) -> None:
|
||||
if not self.git and is_installed(self.name):
|
||||
raise PackageAlreadyInstalled(f"Package {self} is already installed")
|
||||
|
||||
if self.aur:
|
||||
if not is_installed("yay"):
|
||||
raise InvalidPackage(f"Package {self} can't be installed (missing `yay` - AUR installation software), alternatively, you can use git")
|
||||
yay_install(self.name)
|
||||
elif self.git:
|
||||
git_install(self.git_url)
|
||||
else:
|
||||
pacman_install(self.name)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self.git:
|
||||
if self.name == self.git_url:
|
||||
return f"<Git package: {self.name}>"
|
||||
return f"<Git package: {self.name} ({self.git_url})>"
|
||||
elif self.aur:
|
||||
return f"<Aur package: {self.name}>"
|
||||
return f"<Package: {self.name}>"
|
||||
|
||||
@classmethod
|
||||
def safe_load(cls, packages: t.List[str], aur: bool = False, git: bool = False) -> t.List["Package"]:
|
||||
loaded_packages = []
|
||||
for package in packages:
|
||||
try:
|
||||
loaded_packages.append(cls(package, aur=aur, git=git))
|
||||
except InvalidPackage as e:
|
||||
print(f"{colorama.Fore.RED}{str(e)}")
|
||||
|
||||
return loaded_packages
|
19
tox.ini
19
tox.ini
|
@ -1,19 +0,0 @@
|
|||
[flake8]
|
||||
max_line_length=150
|
||||
import-order-style=pycharm
|
||||
application_import_names=src
|
||||
exclude=
|
||||
.venv/**,
|
||||
.git/**
|
||||
ignore=
|
||||
# Ignore missing return type annotations for special methods
|
||||
ANN204
|
||||
# Ignore missing type annotations
|
||||
ANN101 # Init
|
||||
ANN102 # cls
|
||||
ANN002, # *Args
|
||||
ANN003, # **Kwargs
|
||||
# Allow lambdas
|
||||
E731
|
||||
# Allow markdown inline HTML
|
||||
MD033
|
Loading…
Reference in a new issue