os/brick.sh

361 lines
7.1 KiB
Bash
Raw Normal View History

2024-02-13 09:55:29 +01:00
#!/bin/sh
# brick - a simple userspace package manager for blek!OS
# also built on top of pacman
#
# made by alice
# also it is GPL3 only uwu
# settings
set -e
2024-02-14 02:54:09 +01:00
start_time=$(date +%s)
2024-02-14 03:06:19 +01:00
version=1.1
2024-02-13 09:55:29 +01:00
# functions
errcho() {
# now this was stolen from https://stackoverflow.com/a/2990533
# uwu
echo "$@" 1>&2;
}
err() {
printf "\x1b[1;31m[!]\x1b[0m $@\n" 1>&2;
}
inf() {
printf " $@\n"
}
getbrick() {
echo $BRICKS_DIR/$1.brick
}
brickdb() {
mkdir -p $BRICKS_DIR/.db
if ! [ -f $BRICKS_DIR/.db/installed ]; then
touch $BRICKS_DIR/.db/installed
fi
echo $BRICKS_DIR/.db
}
pkg_installed() {
if [ ! -z $(echo "$BRICKS_INSTALLED" | grep -E "^$1 \\\\d") ]; then
2024-02-13 09:55:29 +01:00
return 0
fi
return 1
}
user_confirm() {
# base function was stolen from https://stackoverflow.com/a/32708121
if [ "$AUTOMATIC" == "true" ]; then
return 0
fi
while true; do
read -r -n 1 -p "$(inf "- ${1:-Continue?} [Y/n]: ")" REPLY
2024-02-13 09:55:29 +01:00
case $REPLY in
[yY]) echo ; return 0 ;;
[nN]) echo ; return 1 ;;
*) return 0 ;;
esac
done
}
bricksenv() {
echo "export BRICKS_DIR=$BRICKS_DIR"
echo "export BRICKS_DB=$BRICKS_DB"
echo "export AUTOMATIC=$AUTOMATIC"
}
tmpdir() {
if ! [ -f $BRICKS_DIR/.tmp ]; then
mkdir -p $BRICKS_DB/.tmp
fi
echo $BRICKS_DB/.tmp
}
2024-02-14 03:21:28 +01:00
exec_brick() {
echo -e "$(bricksenv)\n$*" | bash
}
2024-02-20 02:46:57 +01:00
print_long_list() {
list=($@)
i=0
printf '%s' "$(inf)$(inf)"
for el in ${list[@]}; do
printf '%s ' $el
if [ "$i" == "2" ]; then
2024-02-21 16:09:36 +01:00
if ! [ "$(( "${#list[@]}" % 3 ))" == "0" ]; then
printf '\n%s' "$(inf)$(inf)"
fi
2024-02-20 02:46:57 +01:00
fi
i=$(( i + 1 ))
done
echo
}
2024-02-14 03:21:28 +01:00
2024-02-14 02:54:09 +01:00
# checking that brick's dependencies are installed
BRICK_DEPS=(curl)
NO_DEPS=()
for dep in ${BRICK_DEPS[@]}; do
if ! command -v $dep > /dev/null; then
NO_DEPS=(${NO_DEPS[@]} $dep)
fi
done
if ! [ "${#NO_DEPS[@]}" == "0" ]; then
errcho 'Error!'
errcho 'brick itself depends on some stuff, which you dont have installed:'
errcho "${NO_DEPS[@]}"
fi
2024-02-13 09:55:29 +01:00
# some vars
BRICKS_DIR=${BRICKS_DIR:-}
PKGS=()
ERRORED=false
AUTOMATIC=false
# setting the BRICKS_DIR var
BRICKS_PWD=$(pwd)
while :; do
# lets jump to the parent dir until we find the bricks dir
if [ -d $BRICKS_PWD/bricks ]; then
# yay we found it ^^
BRICKS_DIR=$BRICKS_PWD/bricks
break
fi
if [ $BRICKS_PWD = "/" ]; then
err "Didnt find the bricksdir in this or any parent directory (excluding root)"
exit 1
fi
done
unset BRICKS_PWD
2024-02-13 10:26:55 +01:00
2024-02-13 09:55:29 +01:00
BRICKS_DB=$(brickdb)
BRICKS_INSTALLED=$(cat $BRICKS_DB/installed)
2024-02-13 10:26:55 +01:00
# settings the PKGS var
# lets grab those from argv
while [[ $# -gt 0 ]]; do
case $1 in
-y|--noconfirm)
AUTOMATIC=true
shift;;
-L)
inf "listing packages"
for pkg in $(find $BRICKS_DIR -maxdepth 1 -type f -printf "%f\n" | grep -E \\.brick$ | sed 's/.brick//'); do
2024-02-14 03:21:28 +01:00
SCRIPT="\n
source $(getbrick $pkg)\n
if [ \"\$(command -v info)\" == \"info\" ]; then\n
echo \$(info)\n
else\n
echo 'no info provided'\n
fi\n
"
# exec_brick $SCRIPT
inf "$(inf "$pkg - $(exec_brick $SCRIPT)")"
2024-02-13 10:26:55 +01:00
done
inf 'done'
2024-02-13 10:26:55 +01:00
exit 0
;;
2024-02-14 03:06:19 +01:00
-v|--version)
echo "brick $version (gpl 3 only)"
echo "made by alice with <3"
echo "https://git.blek.codes/blek/os"
exit 0
;;
-h|--help)
echo "brick $version (gpl 3 only)"
inf "Usage: $0 [PACKAGES]"
inf "$(inf "-h --help \t - Display this message")"
inf "$(inf "-v --version \t - Print version and exit")"
inf "$(inf "-L \t - List all packages")"
exit 0
;;
2024-02-13 10:26:55 +01:00
-*)
# meh domt need unkonw args
shift;;
*)
# everything else is a package name however
PKGS+=("$1")
shift;;
esac
done
2024-02-13 09:55:29 +01:00
PPKGS=()
# now step 1 is to check that all packages are there
for pkg in "${PKGS[@]}"; do
if ! [ -f $(getbrick $pkg) ]; then
err "Oh no! Brick $pkg is not found in $BRICKS_DIR"
ERRORED=true
fi
if pkg_installed "$pkg"; then
echo $pkg is installed, skipping
else
PPKGS=("${PPKGS[@]}" $pkg)
fi
done
PKGS=("${PPKGS[@]}")
if [ "$ERRORED" == "true" ]; then
exit 1
fi
2024-02-20 02:46:57 +01:00
# lets resolve the dependencies huh
find_deps_for() {
brick=$1
deps=()
SCRIPT="
source $(getbrick $brick)\n
if ! [ \"\$dependencies\" == \"\" ]; then\n
echo \"\${dependencies[@]}\"\n
fi\n
"
deps=$(exec_brick $SCRIPT)
deps=(${deps[@]})
if ! [ "${#deps[@]}" == "0" ]; then
for dep in "${deps[@]}"; do
if ! [ -f "$(getbrick $dep)" ]; then
err "$brick depends on $dep, which is not an available package"
ERRORED=true
fi
ndeps=$(find_deps_for $dep)
deps=(${deps[@]} ${ndeps[@]})
done
fi
echo ${deps[@]}
}
for pkg in "${PKGS[@]}"; do
PKGS=(${PKGS[@]} $(find_deps_for $pkg))
done
if [ "$ERRORED" == "true" ]; then
exit 1
fi
2024-02-13 09:55:29 +01:00
if [ "${#PKGS[@]}" == "0" ]; then
inf "nothing to do"
exit
else
2024-02-20 02:46:57 +01:00
inf "packages to install:"
print_long_list "${PKGS[@]}"
if ! user_confirm; then
inf "canceled"
exit
fi
2024-02-13 09:55:29 +01:00
fi
PACDEPS=()
# lets first collect the packages
2024-02-13 09:55:29 +01:00
for pkg in "${PKGS[@]}"; do
source $(getbrick $pkg)
IFS=' ' read -ra DEPS <<< $(pkgs)
PACDEPS=("${PACDEPS[@]}" "${DEPS[@]}")
done
# so yeah lets do it
2024-02-13 09:55:29 +01:00
if [ "${#PACDEPS[@]}" != "0" ]; then
# first, gotta filter out the ones that are already installed
INSTALLED=$(pacman -Qe)
TO_INSTALL=''
removed=0
for pkg in $PACDEPS; do
if [[ -z $(echo $INSTALLED | grep $pkg) ]]; then
TO_INSTALL="$TO_INSTALL $pkg"
else
removed=$(($removed + 1))
fi
done
if ! [ "$removed" == "0" ]; then
inf "removed $removed installed pacman deps"
fi
# then there might actually be no work to be done
if [ "$TO_INSTALL" != "" ]; then
if [ -f /var/lib/pacman/db.lck ]; then
errcho "pacman is running now; can't install pacman deps"
errcho "if you are sure that pacman is not running, delete /var/lib/pacman/db.lck manually"
fi
inf "installing pacman packages:"
inf "$TO_INSTALL"
# welp lets install those
sudo pacman -S --needed --noconfirm $TO_INSTALL &> $BRICKS_DB/.pacman-log
PACCODE="$?"
if ! [ "$PACCODE" == "0" ]; then
err "pacman exited with code $PACCODE"
err "pacman's output log is in $BRICKS_DB/.pacman-log"
exit
fi
inf "installed all pacman deps"
else
inf "no pacman deps to install"
fi
2024-02-13 09:55:29 +01:00
else
inf "no pacman deps to install"
fi
DOWNLOADED_FILES=()
2024-02-13 09:55:29 +01:00
i=1
# pacman deps installed, lets install the actual shit
for pkg in "${PKGS[@]}"; do
# first check if there is stuff we need to download for that brick
SCRIPT="
source $(getbrick $pkg)
if [ -z ${var+x} ]; then
echo \${downloads[@]}
fi
"
DOWNLOADS=$(exec_brick "$SCRIPT")
DOWNLOADS_MAP=()
if ! [ "$DOWNLOADS" == "" ]; then
DOWNLOADS=($DOWNLOADS)
inf "$(inf "downloading files for $pkg...")"
2024-02-14 02:54:09 +01:00
ii=1
for download in $DOWNLOADS; do
curl -s $download > $(tmpdir)/$pkg-file-$i &
DOWNLOADS_MAP=(${DOWNLOADS_MAP[@]} $(tmpdir)/$pkg-file-$i)
2024-02-14 02:54:09 +01:00
ii=$(($ii + 1))
done
wait
inf "$(inf "downloaded")"
fi
DOWNLOADED_FILES=(${DOWNLOADED_FILES[@]} ${DOWNLOADS_MAP[@]})
SCRIPT="
source $(getbrick $pkg)\n
downloads=(${DOWNLOADS_MAP[@]})\n
install
"
2024-02-14 02:54:09 +01:00
inf "installing $pkg [$i/${#PKGS[@]}]"
exec_brick "$SCRIPT" > $BRICKS_DB/.$pkg-install-log
2024-02-13 09:55:29 +01:00
i=$(($i + 1))
done
if ! [ "${#DOWNLOADED_FILES[@]}" == "0" ]; then
2024-02-14 02:54:09 +01:00
inf 'cleaning up downloaded files'
for file in $DOWNLOADED_FILES; do
rm $file &
done
wait
fi
2024-02-14 02:54:09 +01:00
inf "done in $(($(date +%s) - $start_time)) seconds"