init
This commit is contained in:
commit
243e102b10
10 changed files with 282 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
test/
|
8
README.md
Normal file
8
README.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# AAA (a3)
|
||||||
|
|
||||||
|
AAA stands for "AAA, I want a package"
|
||||||
|
|
||||||
|
## What does it do?
|
||||||
|
Manage packages and setup software.
|
||||||
|
|
||||||
|
(It also provides a useful library!)
|
96
bin/a3
Executable file
96
bin/a3
Executable file
|
@ -0,0 +1,96 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
. ${A3_LIB_PATH:-/usr/lib/a3}/include.sh
|
||||||
|
a3include_lib a3
|
||||||
|
a3include_lib log
|
||||||
|
a3include_lib util
|
||||||
|
|
||||||
|
A3_FILE=$1
|
||||||
|
[ -z "$A3_FILE" ] && exit 1
|
||||||
|
if ! [ -f "$A3_FILE" ]; then
|
||||||
|
LOGD "lfa3"
|
||||||
|
A3_FILE=$(a3index_find $A3_FILE)
|
||||||
|
[ -z "$A3_FILE" ] && fatal_log "no a3 file found"
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
|
||||||
|
name=$(a3ff a3read_meta name)
|
||||||
|
description=$(a3ff a3read_meta description)
|
||||||
|
author=$(a3ff a3read_meta author)
|
||||||
|
url=$(a3ff a3read_meta url)
|
||||||
|
require_value meta:a3.name $name
|
||||||
|
|
||||||
|
echo "name: $name"
|
||||||
|
[ -n "$description" ] && echo "description: $description"
|
||||||
|
[ -n "$author" ] && echo "author: $author"
|
||||||
|
[ -n "$url" ] && echo "url: $url"
|
||||||
|
echo "status: $(a3index_current_status $name || echo "not installed")"
|
||||||
|
echo "---"
|
||||||
|
|
||||||
|
A3_INSTALL_BIN_PATH=${A3_INSTALL_BIN_PATH:-/usr/bin}
|
||||||
|
A3_INSTALL_LIB_PATH=${A3_INSTALL_LIB_PATH:-/usr/lib}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
case $1 in
|
||||||
|
update)
|
||||||
|
a3index_is $name installed || fatal_log not installed.
|
||||||
|
a3index_update $name pending
|
||||||
|
A3_FILE=$(a3index_find $name)
|
||||||
|
main install
|
||||||
|
;;
|
||||||
|
install)
|
||||||
|
a3index_is $name installed && fatal_log "$name is already installed."
|
||||||
|
oldpwd=$(pwd)
|
||||||
|
if [ -n "$(a3ff a3read_declaration declare_workdir | head -n 1)" ]; then
|
||||||
|
cd $(a3ff a3read_declaration declare_workdir | head -n 1)
|
||||||
|
fi
|
||||||
|
a3ff a3index_create $name
|
||||||
|
a3ff a3read_declaration declare_executable | while read ex; do
|
||||||
|
[ -z "$ex" ] && continue
|
||||||
|
filename=$(basename $ex)
|
||||||
|
if [ -f "$A3_INSTALL_BIN_PATH/$filename" ]; then
|
||||||
|
LOGW "overwriting $A3_INSTALL_BIN_PATH/$filename..."
|
||||||
|
else
|
||||||
|
LOGI "copying $ex to $A3_INSTALL_BIN_PATH/$filename..."
|
||||||
|
fi
|
||||||
|
cp $ex $A3_INSTALL_BIN_PATH/$filename
|
||||||
|
chmod +x $A3_INSTALL_BIN_PATH/$filename
|
||||||
|
done
|
||||||
|
a3ff a3read_declaration declare_library | while read lib; do
|
||||||
|
[ -z "$lib" ] && continue
|
||||||
|
if [ -d "$A3_INSTALL_LIB_PATH/$name" ]; then
|
||||||
|
LOGW "overwriting $A3_INSTALL_LIB_PATH/$name..."
|
||||||
|
else
|
||||||
|
LOGI "copying library..."
|
||||||
|
fi
|
||||||
|
cp -r $lib/. $A3_INSTALL_LIB_PATH/$name
|
||||||
|
done
|
||||||
|
a3index_update $name installed
|
||||||
|
cd $oldpwd
|
||||||
|
;;
|
||||||
|
eval) shift; $@ ;;
|
||||||
|
remove)
|
||||||
|
a3index_is $name installed || fatal_log "$name is not installed."
|
||||||
|
a3ff a3read_declaration declare_executable | while read ex; do
|
||||||
|
filename=$(basename $ex)
|
||||||
|
[ -f "$A3_INSTALL_BIN_PATH/$filename" ] || fatal_log "$A3_INSTALL_BIN_PATH/$filename does not exist"
|
||||||
|
LOGI "removing $A3_INSTALL_BIN_PATH/$filename..."
|
||||||
|
rm $A3_INSTALL_BIN_PATH/$filename
|
||||||
|
done
|
||||||
|
a3ff a3read_declaration declare_library | while read lib; do
|
||||||
|
[ -d "$A3_INSTALL_LIB_PATH/$name" ] || continue
|
||||||
|
LOGI "removing library..."
|
||||||
|
rm -r $A3_INSTALL_LIB_PATH/$name
|
||||||
|
done
|
||||||
|
a3index_update $name cache
|
||||||
|
;;
|
||||||
|
list)
|
||||||
|
for f in $(find $A3_INDEX_ROOT -iname "*.a3"); do
|
||||||
|
echo "$(a3read_meta "$f" name): $(basename $(dirname $f))"
|
||||||
|
done
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main $@
|
13
dev
Executable file
13
dev
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export A3_LIB_PATH="./lib"
|
||||||
|
export A3_INDEX_ROOT="./test/index"
|
||||||
|
export A3_INSTALL_BIN_PATH="./test/bin"
|
||||||
|
export A3_INSTALL_LIB_PATH="./test/lib"
|
||||||
|
|
||||||
|
mkdir -p \
|
||||||
|
$A3_INDEX_ROOT \
|
||||||
|
$A3_INSTALL_BIN_PATH \
|
||||||
|
$A3_INSTALL_LIB_PATH
|
||||||
|
|
||||||
|
exec ./bin/a3 $@
|
6
doc/declarations.md
Normal file
6
doc/declarations.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Declarations for a3
|
||||||
|
|
||||||
|
| usage | description |
|
||||||
|
| ----------------------------------- | ------------------------------------------------- |
|
||||||
|
| `declare_executable <path>` | the executable to put in /usr/bin |
|
||||||
|
| `declare_library <path> [lib_name]` | library to put at /usr/lib/<a3.name>(/<lib_name>) |
|
82
lib/a3.sh
Normal file
82
lib/a3.sh
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# General purpose for a3
|
||||||
|
|
||||||
|
# a3ff <func> [args]: runs functions and automatically makes the first arg the file
|
||||||
|
# a3ff => a3 file function
|
||||||
|
A3_FILE=${A3_FILE:-}
|
||||||
|
a3ff() {
|
||||||
|
[ -z "$A3_FILE" ] && return 1
|
||||||
|
local func=$1
|
||||||
|
[ -z "$func" ] && return 1
|
||||||
|
shift
|
||||||
|
$func $A3_FILE $@
|
||||||
|
}
|
||||||
|
|
||||||
|
A3_INDEX_ROOT=${A3_INDEX_ROOT:-/var/lib/a3/index}
|
||||||
|
|
||||||
|
a3index_create() {
|
||||||
|
file=$1
|
||||||
|
name=$2
|
||||||
|
[ -z "$file" ] && return 1
|
||||||
|
[ -z "$name" ] && return 1
|
||||||
|
[ "$file" = "$A3_INDEX_ROOT/pending/$name.a3" ] && return 0
|
||||||
|
mkdir -p $A3_INDEX_ROOT/pending
|
||||||
|
cp $file $A3_INDEX_ROOT/pending/$name.a3
|
||||||
|
if ! grep -q "declare_workdir" $A3_INDEX_ROOT/pending/$name.a3; then
|
||||||
|
echo -e "\ndeclare_workdir $(pwd)" >> $A3_INDEX_ROOT/pending/$name.a3
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
a3index_find() {
|
||||||
|
name=$1
|
||||||
|
[ -z "$name" ] && return 1
|
||||||
|
find $A3_INDEX_ROOT -iname "$name.a3" | head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
a3index_current_status() {
|
||||||
|
name=$1
|
||||||
|
[ -z "$name" ] && return 1
|
||||||
|
file=$(a3index_find $name)
|
||||||
|
[ -z "$file" ] && return 1
|
||||||
|
basename $(dirname $file)
|
||||||
|
}
|
||||||
|
|
||||||
|
a3index_update() {
|
||||||
|
name=$1
|
||||||
|
status=$2
|
||||||
|
[ -z "$name" ] && return 1
|
||||||
|
[ -z "$status" ] && return 1
|
||||||
|
[ -f "$A3_INDEX_ROOT/$status/$name.a3" ] && return 0
|
||||||
|
file=$(a3index_find $name)
|
||||||
|
[ -z "$file" ] && return 1
|
||||||
|
mkdir -p $A3_INDEX_ROOT/$status
|
||||||
|
mv $file $A3_INDEX_ROOT/$status/$name.a3
|
||||||
|
}
|
||||||
|
|
||||||
|
a3index_is() {
|
||||||
|
name=$1
|
||||||
|
status=$2
|
||||||
|
[ -z "$name" ] && return 1
|
||||||
|
[ -z "$status" ] && return 1
|
||||||
|
[ -f "$A3_INDEX_ROOT/$status/$name.a3" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
a3read_declaration() {
|
||||||
|
file=$1
|
||||||
|
declaration=$2
|
||||||
|
[ -z "$file" ] && return 1
|
||||||
|
[ -z "$declaration" ] && return 1
|
||||||
|
shift; shift
|
||||||
|
grep "$declaration" $file | sed "s/$declaration//" | awk '{$1=$1};1'
|
||||||
|
}
|
||||||
|
|
||||||
|
a3read_meta() {
|
||||||
|
file=$1
|
||||||
|
prop=$2
|
||||||
|
[ -z "$file" ] && return 1
|
||||||
|
[ -z "$prop" ] && return 1
|
||||||
|
shift; shift
|
||||||
|
|
||||||
|
grep "#a3.$prop:" $file | sed "s/#a3.$prop://" | xargs
|
||||||
|
}
|
21
lib/include.sh
Normal file
21
lib/include.sh
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if ! [ $A3_INCLUDE ]; then
|
||||||
|
A3_INCLUDE=1
|
||||||
|
A3_INCLUDED=""
|
||||||
|
A3_LIB_PATH=${A3_LIB_PATH:-/usr/lib/a3}
|
||||||
|
is_included() {
|
||||||
|
echo "$A3_INCLUDED" | grep -q "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
include() {
|
||||||
|
[ -z "$1" ] && return 0
|
||||||
|
is_included $1 && return 0
|
||||||
|
. $1
|
||||||
|
A3_INCLUDED="$A3_INCLUDED $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
a3include_lib() {
|
||||||
|
include $A3_LIB_PATH/$1.sh
|
||||||
|
}
|
||||||
|
fi
|
37
lib/log.sh
Normal file
37
lib/log.sh
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
|
||||||
|
# levels:
|
||||||
|
# DEBUG = 0
|
||||||
|
# INFO = 1
|
||||||
|
# WARN = 2
|
||||||
|
# ERROR = 3
|
||||||
|
A3_LOG_LEVEL=${A3_LOG_LEVEL:-1}
|
||||||
|
|
||||||
|
__a3_log_level_to_text() {
|
||||||
|
case $1 in
|
||||||
|
0) echo "debug" ;;
|
||||||
|
1) echo "info" ;;
|
||||||
|
2) echo "warn" ;;
|
||||||
|
3) echo "error" ;;
|
||||||
|
4) echo "fatal" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
__a3_log() {
|
||||||
|
level=$1
|
||||||
|
shift
|
||||||
|
if [ $level -ge $A3_LOG_LEVEL ]; then
|
||||||
|
echo "[$(__a3_log_level_to_text $level)] $@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
alias LOGD="__a3_log 0"
|
||||||
|
alias LOGI="__a3_log 1"
|
||||||
|
alias LOGW="__a3_log 2"
|
||||||
|
alias LOGE="__a3_log 3"
|
||||||
|
|
||||||
|
fatal_log() {
|
||||||
|
__a3_log 4 $@
|
||||||
|
exit 1
|
||||||
|
}
|
9
lib/util.sh
Normal file
9
lib/util.sh
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
require_value() {
|
||||||
|
local name=$1; shift
|
||||||
|
if [ -z "$@" ]; then
|
||||||
|
echo "expected value for: $name"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
9
meta.a3
Executable file
9
meta.a3
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!bin/a3
|
||||||
|
|
||||||
|
#a3.name: a3
|
||||||
|
#a3.description: a tool to manage packages and setup software.
|
||||||
|
#a3.author: Strix
|
||||||
|
#a3.url: https://git.saluco.nl/strix/aaa
|
||||||
|
|
||||||
|
declare_executable ./bin/a3
|
||||||
|
declare_library ./lib
|
Loading…
Reference in a new issue