Merge branch 'release/0.3'

This commit is contained in:
Jörn-Michael Miehe 2019-09-24 15:06:24 +02:00
commit 437cc98711
19 changed files with 188 additions and 116 deletions

View file

@ -10,7 +10,7 @@ The `autodoc` image [available on Docker Hub](https://hub.docker.com/r/ldericher
01. Install [Docker CE](https://docs.docker.com/install/)
01. Clone or download the `autodoc` repository, open a terminal inside the [example_docs](https://github.com/ldericher/autodoc/tree/master/example_docs) directory
01. Clone or download the `autodoc` repository, open a terminal inside the [examples](https://github.com/ldericher/autodoc/tree/master/examples) directory
01. Deploy an `autodoc` container:
@ -93,12 +93,12 @@ You may combine build instruction systems to your liking.
However, Makefiles must contain a SRCPAT annotation comment as follows, where `<regex>` is a source pattern as above.
```Makefile
#@SRCPAT <regex>
#%SRCPAT% <regex>
```
If there are multiple SRCPAT annotations, the lowermost one will be used.
You *may* add a PHONY target "autodoc" which will be built *instead* of the default target.
You *may* add a PHONY target "autodoc" which will be built *instead* of the default target. This is demonstrated in [examples/automatic directory listing/a directory in space/Makefile](https://github.com/ldericher/autodoc/blob/develop/examples/automatic%20directory%20listing/a%20directory%20in%20space/Makefile).
```Makefile
.PHONY: autodoc

View file

@ -4,7 +4,6 @@ RUN apt-get update && apt-get -y install \
inotify-tools \
&& rm -rf /var/lib/apt/lists/*
COPY autodoc.sh /usr/local/bin/autodoc
RUN chmod +x /usr/local/bin/autodoc
COPY usr /usr
CMD ["autodoc"]

View file

@ -1,102 +0,0 @@
#!/bin/bash
# $1:WATCHROOT (default: ".")
g_watchroot="$(readlink -f "${1:-.}")"
# compile using bare make command
do_make() { # $1:DIR $2:MAKEFILE $3:OBJECT
# extract params
local dir="$1"
local makefile="$2"
local object="$3"
# check Makefile 'source pattern'
local srcpat="$(grep -E "^#@SRCPAT" "${dir}/${makefile}" | tail -n 1 | sed -r "s/^#@SRCPAT\s+//")"
if [ -z "${srcpat}" ]; then
echo -n "Empty source pattern, check '#@SRCPAT' annotation! "
return 1
elif [[ "${object}" =~ ${srcpat} ]]; then
# check for autodoc target
local target="$(grep -E "^autodoc:" "${dir}/${makefile}" | sed -r "s/:.*$//")"
if [ -z "${target}" ]; then
echo "Running 'make'. "
else
echo "Making '${target}'. "
fi
make --no-print-directory -C "${dir}" -j ${target}
else
echo -n "SRCPAT '${srcpat}' mismatch. "
return 1
fi
return 0
}
# compile a directory
do_compile() { # $1:DIR $2:OBJECT $3:DONE
# extract params
local dir="$1"
local object="$2"
local done="${3:-0}"
# build systems
if [ -r "${dir}/Makefile" ]; then
# Makefile found
echo -n "Found '${dir}/Makefile': "
do_make "${dir}" "Makefile" "${object}" \
&& local done="1"
fi
# never leave $g_watchroot
if [ "${dir}" != "${g_watchroot}" ]; then
# search parent dir for more build instructions
do_compile "$(dirname "${dir}")" "${object}" "${done}"
elif [ "${done}" == "0" ]; then
# hit $g_watchroot
echo "No build instructions found!"
fi
}
# process an inotify event
do_handle() { # $1:FLAGS $2:OBJECT
# extract params
local flags="$1"
shift 1
local dir="$(dirname "$*")"
local object="$(basename "$*")"
if [[ "${flags}" =~ "ISDIR" ]]; then
# object refers to directory
local dir="${dir}/${object}"
local object="."
fi
# start using toolchain
echo -n "'${object}': '${flags}' in '${dir}'. "
do_compile "${dir}" "${object}"
}
#
# MAIN
#
echo "Booting ${0} in '${g_watchroot}'."
# setup inotify:
# -mrq monitor, recursive, quiet
# -e events
# --format %e eventlist csv, %w workdir, %f filename
inotifywait -mrq \
-e create -e delete -e moved_to -e close_write \
--format '%e %w%f' \
"${g_watchroot}" | \
\
while read FILE; do
do_handle ${FILE}
done

37
build/usr/local/bin/autodoc Executable file
View file

@ -0,0 +1,37 @@
#!/bin/bash
#
# hard globals
#
g_bin="$(readlink -f "$(which "$0")")"
g_lib=${g_bin/"bin"/"lib"}
declare -a g_build_systems
declare -A g_build_systems_glob
#
# load base program
#
source "${g_lib}/globals"
source "${g_lib}/logging"
source "${g_lib}/plugins/"*".sh"
source "${g_lib}/handle_inotify"
#
# MAIN
#
echo "Booting '${g_bin}' in '${g_watchroot}'."
# setup inotify:
# -mrq monitor, recursive, quiet
# -e events
# --format %e eventlist csv, %w workdir, %f filename
inotifywait -mrq \
-e create -e delete -e moved_to -e close_write \
--format '%e %w%f' \
"${g_watchroot}" | \
\
while read NOTIFICATION; do
do_handle ${NOTIFICATION}
done

View file

@ -0,0 +1,4 @@
#!/bin/bash
# $WATCHROOT (default: ".")
g_watchroot="$(readlink -f "${1:-.}")"

View file

@ -0,0 +1,72 @@
#!/bin/bash
# process an inotify event
do_handle() { # $FLAGS $OBJECT
# extract params
local flags="$1"
shift 1
local dir="$(dirname "$*")"
local object="$(basename "$*")"
if [[ "${flags}" =~ "ISDIR" ]]; then
# object refers to directory
local dir="${dir}/${object}"
local object="."
fi
# start using toolchain
logline_append "'${object}': '${flags}' in '${dir}'."
do_compile "${dir}" "${object}"
logline_flush
}
# compile an OBJECT using build instructions found in DIRectory
do_compile() { # $DIR $OBJECT $DONE
# extract params
local dir="$1"
local object="$2"
local done="${3:-0}"
# build systems
for build_system in ${g_build_systems[@]}; do
do_build_system "${dir}" "${object}" "${build_system}" \
&& local done="1"
done
# never leave $g_watchroot
if [ "${dir}" != "${g_watchroot}" ]; then
# search parent dir for more build instructions
do_compile "$(dirname "${dir}")" "${object}" "${done}"
elif [ "${done}" == "0" ]; then
# hit $g_watchroot
logline_append "Not a source file."
fi
}
# use given BUILD_SYSTEM to process an OBJECT from a DIRectory
do_build_system() { # $DIR $OBJECT $BUILD_SYSTEM
# extract params
local dir="$1"
local object="$2"
local build_system="$3"
# not done yet
local result=1
# get glob pattern for plugin
for glob in ${g_build_systems_glob[${build_system}]}; do
# match glob in directory
for file in "${dir}"/${glob}; do
# check file readability
if [ -r "${file}" ]; then
# actually call into build system
logline_append "Found '${file}':"
do_${build_system} "${dir}" "${object}" "$(basename "${file}")" \
&& local result=0
fi
done
done
return ${result}
}

View file

@ -0,0 +1,12 @@
#!/bin/bash
g_logline=""
logline_append() { # $STRING
g_logline="${g_logline}${1} "
}
logline_flush() {
echo "${g_logline}"
g_logline=""
}

View file

@ -0,0 +1,45 @@
#!/bin/bash
# plugin name
g_build_systems+=(make)
# build instruction file globs for this plugin
g_build_systems_glob[make]="Makefile *.mk"
# compile using bare make command
do_make() { # $DIR $OBJECT $MAKEFILE
# extract params
local dir="$1"
local object="$2"
local makefile="$3"
# check Makefile 'source pattern'
local srcpat="$(grep -E "^#%SRCPAT%" "${dir}/${makefile}" | tail -n 1 | sed -r "s/^#%SRCPAT%\s+//")"
if [ -z "${srcpat}" ]; then
logline_append "Empty source pattern, check '#%SRCPAT%' annotation!"
return 1
elif [[ "${object}" =~ ${srcpat} ]]; then
# check for autodoc target
local target="$(grep -E "^autodoc:" "${dir}/${makefile}" | sed -r "s/:.*$//")"
if [ -z "${target}" ]; then
logline_append "Running 'make'!"
else
logline_append "Making '${target}'!"
fi
# actually run "make" and save (truncated) output
local makelog="$(make --no-print-directory -C "${dir}" -f "${makefile}" -j ${target})"
logline_append "$(echo "${makelog}" | head -n 10 | sed 's/$/;/g' | tr '\n' ' ' | sed 's/ *$//')"
logline_append "Done."
else
logline_append "SRCPAT '${srcpat}' mismatch."
return 1
fi
return 0
}

View file

@ -14,5 +14,6 @@ services:
command: "bash"
volumes:
- "${PWD}/build/autodoc.sh:/usr/local/bin/autodoc:ro"
- "${PWD}/example_docs:/docs"
- "${PWD}/build/usr/local/bin/autodoc:/usr/local/bin/autodoc:ro"
- "${PWD}/build/usr/local/lib/autodoc:/usr/local/lib/autodoc:ro"
- "${PWD}/examples:/docs"

View file

@ -1,5 +0,0 @@
#@SRCPAT .*
.PHONY: all
all:
@echo "Hello World!"

View file

@ -1,4 +1,4 @@
#@SRCPAT (file|\.tex)$
#%SRCPAT% (file|\.tex)$
.PHONY: all
all: files.txt

View file

@ -0,0 +1,9 @@
#%SRCPAT% .*
.PHONY: all
all:
@echo "Hello World!"
.PHONY: autodoc
autodoc:
@echo "Hello autodoc!"

View file

@ -1,4 +1,4 @@
#@SRCPAT \.md$
#%SRCPAT% \.md$
.PHONY: all
all: simple.pdf simple.html