commit 43f088e90a1255fb7159b23c2e11981c1d67a8c0
parent 7180f9df812cc27812e13ae104b32ef070a03fbb
Author: finwo <finwo@pm.me>
Date: Sat, 28 Jan 2023 03:10:48 +0100
Implemented minimalist add without preloaded repository
Diffstat:
11 files changed, 228 insertions(+), 157 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,20 +1,12 @@
-SRC=$(wildcard src/*.sh)
-
-# Idea:
-# include lib/.dep/libraries.mk
+SRC:=
+SRC+=$(wildcard src/*.sh)
+SRC+=$(wildcard src/*/*.sh)
+SRC+=$(wildcard src/*/*/*.sh)
PREPROCESS=preprocess --substitute
DESTDIR?=/usr/local
TARGET=dep
-default: $(TARGET)
-
-# util/ini.sh: src/util/ini.sh src/util/shopt.sh
-# mkdir -p util
-# echo '#!/usr/bin/env bash' > $@
-# $(PREPROCESS) -I src -v src/util/ini.sh | tee -a $@ > /dev/null
-# chmod +x $@
-
$(TARGET): $(SRC)
echo '#!/usr/bin/env bash' > "$(TARGET)"
$(PREPROCESS) -D __NAME=$(TARGET) -I src src/main.sh | tee -a $(TARGET) > /dev/null
@@ -27,4 +19,3 @@ install: $(TARGET)
.PHONY: clean
clean:
rm -f $(TARGET)
- # rm -rf util/ini.sh
diff --git a/package.ini b/package.ini
@@ -1,3 +1,3 @@
[package]
-name=dep
deps=lib
+name=dep
diff --git a/src/command/add/help.txt b/src/command/add/help.txt
@@ -0,0 +1,13 @@
+Usage: ${NAME} [global options] add <name> <url>
+
+Description:
+
+ The add command will add a dependency to your package.ini and trigger the
+ install command to do the actual install.
+
+Arguments:
+
+ name The name of the dependency that will be installed. This will be used as
+ the target directory within lib as well.
+
+ url The url pointing to the package.ini that describes the dependency.
diff --git a/src/command/add/index.sh b/src/command/add/index.sh
@@ -0,0 +1,36 @@
+#include "util/ini.sh"
+
+read -r -d '' help_topics[add] <<- EOF
+# #include "help.txt"
+EOF
+
+CMD_ADD_PKG=
+CMD_ADD_SRC=
+
+function arg_a {
+ arg_add "$@"
+ return $?
+}
+function arg_add {
+ if [ $# != 2 ]; then
+ echo "Add command requires 2 arguments" >&2
+ exit 1
+ fi
+
+ CMD_ADD_PKG="$1"
+ CMD_ADD_SRC="$2"
+
+ return 0
+}
+
+function cmd_a {
+ cmd_add "$@"
+ return $?
+}
+function cmd_add {
+ OLD_PKG=$(ini_foreach ini_output_full "package.ini")
+ (echo "dependencies.${CMD_ADD_PKG}=${CMD_ADD_SRC}" ; echo -e "${OLD_PKG}") | ini_write "package.ini"
+}
+
+cmds[${#cmds[*]}]="a"
+cmds[${#cmds[*]}]="add"
diff --git a/src/command/help/index.sh b/src/command/help/index.sh
@@ -10,7 +10,9 @@ function arg_h {
return $?
}
function arg_help {
- HELP_TOPIC=$1
+ if [[ $# -gt 0 ]]; then
+ HELP_TOPIC=$1
+ fi
shift
}
@@ -24,7 +26,7 @@ function cmd_help {
exit 1
fi
- echo "${help_topics[$HELP_TOPIC]}"
+ echo -e "\n${help_topics[$HELP_TOPIC]}\n"
}
cmds[${#cmds[*]}]="h"
diff --git a/src/command/help/topic/global.txt b/src/command/help/topic/global.txt
@@ -1,12 +1,14 @@
-
Usage: ${NAME} [global options] <command> [options] [-- ...args]
Global options:
n/a
Commands:
+ a(dd) Add a new dependency to the project
i(nstall) Install all the project's dependencies
h(elp) [topic] Show this help or the top-level info about a command
Help topics:
global This help text
+ add More detailed explanation on the add command
+ install More detailed explanation on the install command
diff --git a/src/command/install.sh b/src/command/install.sh
@@ -1,139 +0,0 @@
-# #include "util/ini.sh"
-
-function arg_i {
- arg_install "$@"
- return $?
-}
-function arg_install {
- return 0
-}
-
-function cmd_i {
- cmd_install "$@"
- return $?
-}
-function cmd_install {
-
- # Sanity check
- PACKAGE_PATH="$(pwd)/package.ini"
- if [ ! -f "${PACKAGE_PATH}" ]; then
- echo "No package.ini in the working directory!" >&2
- exit 1
- fi
-
- ini_foreach cmd_install_parse_ini_main "${PACKAGE_PATH}"
- cmd_install_execute
-}
-
-cmds[${#cmds[*]}]="i"
-cmds[${#cmds[*]}]="install"
-
-CMD_INSTALL_PKG_NAME=
-CMD_INSTALL_PKG_DEST="$(pwd)/lib"
-declare -A CMD_INSTALL_DEPS
-function cmd_install_parse_ini_main {
- case "$1" in
- package.)
- case "$2" in
- name)
- CMD_INSTALL_PKG_NAME="$3"
- ;;
- deps)
- CMD_INSTALL_PKG_DEST="$(pwd)/$3"
- ;;
- esac
- ;;
- dependencies.)
- CMD_INSTALL_DEPS["$2"]="$3"
- ;;
- esac
-}
-
-function cmd_install_execute {
- cmd_install_reset_generated
- for key in "${!CMD_INSTALL_DEPS[@]}"; do
- cmd_install_dep "$key" "${CMD_INSTALL_DEPS[$key]}"
- done
-}
-
-function cmd_install_reset_generated {
- rm -rf "${CMD_INSTALL_PKG_DEST}/.__NAME"
- mkdir -p "${CMD_INSTALL_PKG_DEST}/.__NAME/include"
- echo "INCLUDES+=-I ${CMD_INSTALL_PKG_DEST}/.__NAME/include" > "${CMD_INSTALL_PKG_DEST}/.__NAME/config.mk"
-}
-
-function cmd_install_dep {
- name=$1
- origin=$2
-
- # Full install if missing
- if [ ! -d "${CMD_INSTALL_PKG_DEST}/${name}" ]; then
-
- # Fetch package.ini for the dependency
- mkdir -p "${CMD_INSTALL_PKG_DEST}/${name}"
- curl --location --progress-bar "${origin}" --output "${CMD_INSTALL_PKG_DEST}/${name}/package.ini"
-
- # Fetch it's src (if present)
- if [ ! -z "$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.src)" ]; then
- SRC="$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.src)"
- HASH="$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.src-sha256)"
-
- # Download
- mkdir -p "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}"
- if [ ! -f "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball" ]; then
- curl --location --progress-bar "${SRC}" --output "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball"
- fi
-
- # Verify checksum
- if [ "${HASH}" != "$(sha256sum "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball" | awk '{print $1}')" ]; then
- echo "The tarball for '${name}' failed it's checksum!" >&2
- exit 1
- fi
-
- # Extract tarball
- tar --extract --directory "${CMD_INSTALL_PKG_DEST}/${name}/" --strip-components 1 --file="${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball"
- fi
-
- # Handle fetching extra files
- while read line; do
- filename=${line%%=*}
- filesource=${line#*=}
-
- # Download the extra file into cache
- mkdir -p "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/fetch"
- if [ ! -f "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/fetch/${filename}" ]; then
- curl --location --progress-bar "${filesource}" --create-dirs --output "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/fetch/${filename}"
- fi
-
- done < <(ini_foreach ini_output_section "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" "fetch.")
-
- # Copy the extra files into the target directory
- tar --create --directory "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}" "fetch" | \
- tar --extract --directory "${CMD_INSTALL_PKG_DEST}/${name}" --strip-components 1
- fi
-
- # Download package's dependencies
- while read line; do
- depname=${line%%=*}
- deplink=${line#*=}
- cmd_install_dep "$depname" "$deplink"
- done < <(ini_foreach ini_output_section "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" "dependencies.")
-
- # TODO: handle patching/building here
-
- # Fetch directory key for export absolute paths
- DIRKEY="$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.dirkey)"
- if [ -z "${DIRKEY}" ]; then
- DIRKEY=__DIRNAME__
- fi
-
- # Build the package's exports
- while read line; do
- filetarget=${line%%=*}
- filesource=${line#*=}
- mkdir -p "$(dirname "${CMD_INSTALL_PKG_DEST}/.__NAME/${filetarget}")"
- cat "${CMD_INSTALL_PKG_DEST}/${name}/${filesource}" | \
- sed "s|${DIRKEY}|${CMD_INSTALL_PKG_DEST}/${name}|g" \
- >> "${CMD_INSTALL_PKG_DEST}/.__NAME/${filetarget}"
- done < <(ini_foreach ini_output_section "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" "export.")
-}
diff --git a/src/command/install/help.txt b/src/command/install/help.txt
@@ -0,0 +1,7 @@
+Usage: ${NAME} [global options] install
+
+Description:
+
+ The install command will iterate over all dependencies listed in your
+ project's package.ini and install them 1-by-1, installing the dependency's
+ dependencies as well.
diff --git a/src/command/install/index.sh b/src/command/install/index.sh
@@ -0,0 +1,143 @@
+# #include "util/ini.sh"
+
+read -r -d '' help_topics[install] <<- EOF
+# #include "help.txt"
+EOF
+
+function arg_i {
+ arg_install "$@"
+ return $?
+}
+function arg_install {
+ return 0
+}
+
+function cmd_i {
+ cmd_install "$@"
+ return $?
+}
+function cmd_install {
+
+ # Sanity check
+ PACKAGE_PATH="$(pwd)/package.ini"
+ if [ ! -f "${PACKAGE_PATH}" ]; then
+ echo "No package.ini in the working directory!" >&2
+ exit 1
+ fi
+
+ ini_foreach cmd_install_parse_ini_main "${PACKAGE_PATH}"
+ cmd_install_execute
+}
+
+cmds[${#cmds[*]}]="i"
+cmds[${#cmds[*]}]="install"
+
+CMD_INSTALL_PKG_NAME=
+CMD_INSTALL_PKG_DEST="$(pwd)/lib"
+declare -A CMD_INSTALL_DEPS
+function cmd_install_parse_ini_main {
+ case "$1" in
+ package.)
+ case "$2" in
+ name)
+ CMD_INSTALL_PKG_NAME="$3"
+ ;;
+ deps)
+ CMD_INSTALL_PKG_DEST="$(pwd)/$3"
+ ;;
+ esac
+ ;;
+ dependencies.)
+ CMD_INSTALL_DEPS["$2"]="$3"
+ ;;
+ esac
+}
+
+function cmd_install_execute {
+ cmd_install_reset_generated
+ for key in "${!CMD_INSTALL_DEPS[@]}"; do
+ cmd_install_dep "$key" "${CMD_INSTALL_DEPS[$key]}"
+ done
+}
+
+function cmd_install_reset_generated {
+ rm -rf "${CMD_INSTALL_PKG_DEST}/.__NAME"
+ mkdir -p "${CMD_INSTALL_PKG_DEST}/.__NAME/include"
+ echo "INCLUDES+=-I ${CMD_INSTALL_PKG_DEST}/.__NAME/include" > "${CMD_INSTALL_PKG_DEST}/.__NAME/config.mk"
+}
+
+function cmd_install_dep {
+ name=$1
+ origin=$2
+
+ # Full install if missing
+ if [ ! -d "${CMD_INSTALL_PKG_DEST}/${name}" ]; then
+
+ # Fetch package.ini for the dependency
+ mkdir -p "${CMD_INSTALL_PKG_DEST}/${name}"
+ curl --location --progress-bar "${origin}" --output "${CMD_INSTALL_PKG_DEST}/${name}/package.ini"
+
+ # Fetch it's src (if present)
+ if [ ! -z "$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.src)" ]; then
+ SRC="$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.src)"
+ HASH="$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.src-sha256)"
+
+ # Download
+ mkdir -p "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}"
+ if [ ! -f "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball" ]; then
+ curl --location --progress-bar "${SRC}" --output "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball"
+ fi
+
+ # Verify checksum
+ if [ "${HASH}" != "$(sha256sum "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball" | awk '{print $1}')" ]; then
+ echo "The tarball for '${name}' failed it's checksum!" >&2
+ exit 1
+ fi
+
+ # Extract tarball
+ tar --extract --directory "${CMD_INSTALL_PKG_DEST}/${name}/" --strip-components 1 --file="${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/tarball"
+ fi
+
+ # Handle fetching extra files
+ mkdir -p "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/fetch"
+ while read line; do
+ filename=${line%%=*}
+ filesource=${line#*=}
+
+ # Download the extra file into cache
+ if [ ! -f "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/fetch/${filename}" ]; then
+ curl --location --progress-bar "${filesource}" --create-dirs --output "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}/fetch/${filename}"
+ fi
+
+ done < <(ini_foreach ini_output_section "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" "fetch.")
+
+ # Copy the extra files into the target directory
+ tar --create --directory "${CMD_INSTALL_PKG_DEST}/.__NAME/cache/${name}" "fetch" | \
+ tar --extract --directory "${CMD_INSTALL_PKG_DEST}/${name}" --strip-components 1
+ fi
+
+ # Download package's dependencies
+ while read line; do
+ depname=${line%%=*}
+ deplink=${line#*=}
+ cmd_install_dep "$depname" "$deplink"
+ done < <(ini_foreach ini_output_section "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" "dependencies.")
+
+ # TODO: handle patching/building here
+
+ # Fetch directory key for export absolute paths
+ DIRKEY="$(ini_foreach ini_output_value "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" package.dirkey)"
+ if [ -z "${DIRKEY}" ]; then
+ DIRKEY=__DIRNAME__
+ fi
+
+ # Build the package's exports
+ while read line; do
+ filetarget=${line%%=*}
+ filesource=${line#*=}
+ mkdir -p "$(dirname "${CMD_INSTALL_PKG_DEST}/.__NAME/${filetarget}")"
+ cat "${CMD_INSTALL_PKG_DEST}/${name}/${filesource}" | \
+ sed "s|${DIRKEY}|${CMD_INSTALL_PKG_DEST}/${name}|g" \
+ >> "${CMD_INSTALL_PKG_DEST}/.__NAME/${filetarget}"
+ done < <(ini_foreach ini_output_section "${CMD_INSTALL_PKG_DEST}/${name}/package.ini" "export.")
+}
diff --git a/src/main.sh b/src/main.sh
@@ -1,6 +1,7 @@
cmds=("")
# #include "command/help/index.sh"
-# #include "command/install.sh"
+# #include "command/add/index.sh"
+# #include "command/install/index.sh"
function main {
cmd=help
diff --git a/src/util/ini.sh b/src/util/ini.sh
@@ -49,7 +49,22 @@ function ini_foreach {
fi
done < "${inifile}"
+}
+function ini_write {
+ PREVIOUSSECTION=
+ echo -en "" > "$1"
+ while read line; do
+ KEYFULL=${line%%=*}
+ VALUE=${line#*=}
+ SECTION=${KEYFULL%%.*}
+ KEY=${KEYFULL#*.}
+ if [[ "${SECTION}" != "${PREVIOUSSECTION}" ]]; then
+ echo "[${SECTION}]" >> "$1"
+ PREVIOUSSECTION="${SECTION}"
+ fi
+ echo "${KEY}=${VALUE}" >> "$1"
+ done < <(sort --unique)
}
function ini_output_full {