#!/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 # 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 "$1") ]; then 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 "${1:-Continue?} [Y/n]: " REPLY 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 } # 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 BRICKS_DB=$(brickdb) BRICKS_INSTALLED=$(cat $BRICKS_DB/installed) # 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 source $(getbrick $pkg) inf "$(inf "$pkg - $(info)")" done inf 'done' exit 0 ;; -*) # meh domt need unkonw args shift;; *) # everything else is a package name however PKGS+=("$1") shift;; esac done 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 if [ "${#PKGS[@]}" == "0" ]; then inf "nothing to do" exit else echo "Packages to install: ${PKGS[@]}" user_confirm fi PACDEPS=() # lets first collect the packages for pkg in "${PKGS[@]}"; do source $(getbrick $pkg) IFS=' ' read -ra DEPS <<< $(pkgs) PACDEPS=("${PACDEPS[@]}" "${DEPS[@]}") done # so yeah lets do it 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 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 else inf "no pacman deps to install" fi DOWNLOADED_FILES=() i=1 # pacman deps installed, lets install the actual shit for pkg in "${PKGS[@]}"; do inf "installing $pkg [$i/${#PKGS[@]}]" exec_brick() { echo -e "$(bricksenv)$1" | bash } # 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...")" i=1 for download in $DOWNLOADS; do curl -s $download > $(tmpdir)/$pkg-file-$i & DOWNLOADS_MAP=(${DOWNLOADS_MAP[@]} $(tmpdir)/$pkg-file-$i) i=$(($i + 1)) done wait inf "$(inf "downloaded")" fi DOWNLOADED_FILES=(${DOWNLOADED_FILES[@]} ${DOWNLOADS_MAP[@]}) SCRIPT=" source $(getbrick $pkg)\n downloads=(${DOWNLOADS_MAP[@]})\n install " exec_brick "$SCRIPT" > $BRICKS_DB/.$pkg-install-log i=$(($i + 1)) done if ! [ "${#DOWNLOADED_FILES[@]}" == "0" ]; then inf "$(inf 'cleaning up downloaded files')" for file in $DOWNLOADED_FILES; do rm $file & done wait fi inf "done"