1
1
Fork 0
mirror of https://github.com/tonydamage/nux-env.git synced 2025-12-11 13:24:28 +01:00
nux-env/inc/dsl/nuxfs.dsl
Tony Tkacik 1f07be6e0d nuxfs: Updated nuxfs to behave better in REPL mode.
Signed-off-by: Tony Tkacik <tonydamage@gmail.com>
2017-06-29 14:12:25 +02:00

222 lines
5.6 KiB
Text

#/bin/sh
## # NUXFS Domain Specific Language
##
## *nuxfs* command has its own DSL to describe rules and structure of filesystem
## and content of files. It uses file structure definition present in *.nuxfs*
## file to understand intented state of directory / filesystem of user.
##
## This definition is not only used to create filesystem hierarchy, checkout git
## repositories but also to verify state of filesystem afterwards.
##
## ## Example of .nuxfs file in home directory
##
## *dir* github
## *git* nux-env https://github.com/tonydamage/nux-env.git
## *git* bats https://github.com/sstephenson/bats.git
## *enddir*
## *link* .bashrc github/nux-env/bashrc
##
## This *.nuxfs* file describes simple home structure. When *nuxfs apply*
## is executed in folder containing this file, it is equivalent of executing
## following commands:
##
## mkdir -p github
## git clone https://github.com/tonydamage/nux-env.git github/nux-env
## git clone https://github.com/sstephenson/bats.git
## ln -s github/nux-env/bashrc .bashrc
##
## If we manually remove *github/bats* directory and run *nuxfs check* afterwards
## the *github/bats* directory will be reported as missing.
##
## If we execute *nuxfs apply*, only missing *github/bats* will be cloned.
##
## # Available Keywords
## dir <name>
## Block keyword which defines directory with specified *name*.
## All subsequent keywords represent nested items in these directory
## unless **enddir** keyword is encountered.
##
.block dir name
dir.entered() {
if nux.check.file.exists "$abs_path/.nuxfs"; then
source "$abs_path/.nuxfs"
fi
}
.block opt-dir name
use-template() {
local template=$1;
local possible=$(nux.cfg.get.path "templates/$template.nuxfs");
if [ -z "$possible" ] ; then
rel_path=$template .error Template not found.
return
fi
to_include=$(echo "$possible" | head -n1)
nux.log trace "Possible templates: '$possible'"
nux.log trace "Template $to_include will be used"
source "$to_include"
}
## link <name> <target>
## Defines a symbolik link with specified *name*, which points to
## specified target
##
.keyword link name target
## git <name> <origin>
## Defines an existence of folder with specified *name*, which
## is git repository clone of specified *origin*
##
.keyword git name origin
.keyword origin
.keyword name name
.keyword template
## exists <name>
## Defines an existence of file with specified *name*.
## When *nuxfs check* is executed absence of this file would result
## into error report.
##
.keyword exists name
## should-not-exists <match>
## Defines a requirement for file not to be present.
## *nuxfs check*: error will be raised if file exists.
## *nuxfs fix*: files which match the match will be deleted.
##
##
.keyword should-not-exists match
should-not-exists.check() {
test $(find "$(dirname "$abs_path")" -maxdepth 1 -iname "$match" | wc -l) -eq 0
}
should-not-exists.check.failed() {
find "$(dirname "$rel_path")" -maxdepth 1 -iname "$match" | while read f
do
nux.dsl.error $f Should not exists, but is present.
done
}
.keyword cathegorize match min delimiter
cathegorize.check() {
test $(find "$(dirname "$abs_path")" -maxdepth 1 -iname "$match" | wc -l) -gt 0
}
cathegorize.cathegory() {
sed -r -e "s/$delimiter/:/g" | cut -d: -f1
}
cathegorize.entered() {
local parent_dir=$(dirname "$rel_path");
local cathegories=$((cd "$parent_dir"; find -maxdepth 1 -iname "$match") \
| cut -d"/" -f2 \
| cathegorize.cathegory | sort | uniq -c \
| while IFS=" " read count cathegory
do
if [ $count -ge $min ]; then
echo $theme $cathegory
fi
done
)
for cat in $cathegories; do
cat_dir=$parent_dir/$cat;
if [ ! -d "$cat_dir" ]; then
cathegorize.process.dir "$@"
fi
done
(cd "$parent_dir"; find -maxdepth 1 -iname "$match") \
| while read file
do
file=$(basename "$file")
cathegory=$(echo $file | cathegorize.cathegory)
if [[ $cathegories =~ "$cathegory" ]];then
rel_file=$parent_dir/$file
cat_dir=$parent_dir/$cathegory
cathegorize.process.file "$@"
fi
done
}
cathegorize.process.dir() {
nux.dsl.error "$cat_dir" Does not exits. Required by cathegorize
}
cathegorize.process.file() {
nux.dsl.error "$rel_file" Should be in $NC_White$cat_dir$NC_No
}
cathegorize.check.failed() {
nux.log debug Noop, no files to cathegorize
}
directory() {
dir
}
sdir() {
dir "$@"
enddir
}
##
## #Using custom keywords
##
## *nuxfs* allows for addition of custom directory specific keywords,
## since it is based on *nuxdsl* library.
##
## FIXME: Describe how to add keywords
##
.info() {
nux.dsl.info "$rel_path" "$@"
}
.warning() {
nux.dsl.warning "$rel_path" "$@"
}
.error() {
nux.dsl.error "$rel_path" "$@"
}
.should.eq() {
local actual="$1"
local expected="$2"
shift;shift;
if [ "$actual" != "$expected" ]; then
.warning "$@"
fi
}
.must.eq() {
local actual="$1"
local expected="$2"
shift;shift;
if [ "$actual" != "$expected" ]; then
.error "$@"
fi
}
.allways.preprocess() {
abs_path=$(realpath -Lms "$NUXFS_DEF_DIR/$path");
rel_path=$(realpath -Lms "$abs_path" --relative-base="$WORKDIR");
def_path=$(realpath -Lms "$path" --relative-to="$NUXFS_DEF_DIR")
}
.check() {
nux.log trace "Checking existence of $NC_White$abs_path$NC_No"
nux.check.file.exists "$abs_path"
}
.check.failed() {
if [ -z "$NUXFS_IGNORE_MISSING" ]; then
.error does not exists.
fi
}