mirror of
https://github.com/ldericher/autodoc.git
synced 2025-12-06 15:43:01 +00:00
Merge branch 'release/0.2'
This commit is contained in:
commit
d8ee619d60
2 changed files with 93 additions and 49 deletions
100
README.md
100
README.md
|
|
@ -1,54 +1,96 @@
|
||||||
# autodoc
|
# autodoc
|
||||||
|
|
||||||
[`autodoc`](https://github.com/ldericher/autodoc) is a simple [CI](https://en.wikipedia.org/wiki/Continuous_integration) script, primarily aimed at document creation.
|
[`autodoc`](https://github.com/ldericher/autodoc) is a simple [CI](https://en.wikipedia.org/wiki/Continuous_integration) system optimized for document creation.
|
||||||
|
|
||||||
## Basics
|
In general, any file-sharing solution -- preferably on top of `docker-compose` -- can be made into an automatic document distribution system by adding an `autodoc` instance.
|
||||||
|
|
||||||
`autodoc` relies upon [inotify-tools](https://github.com/rvoicilas/inotify-tools) to recursively watch a Linux file system directory.
|
## Quick Start Guide using Docker
|
||||||
|
|
||||||
For each file change, `autodoc` searches corresponding build instruction files (Makefiles etc.) and kicks off build processes accordingly.
|
The `autodoc` image [available on Docker Hub](https://hub.docker.com/r/ldericher/autodoc) is based on [pandocker](https://hub.docker.com/r/ldericher/pandocker) providing Ubuntu's TeXlive `LaTeX` and `pandoc` in a simple box.
|
||||||
|
|
||||||
## Usage
|
01. Install [Docker CE](https://docs.docker.com/install/)
|
||||||
|
|
||||||
`autodoc` is designed to run in a server-side, containerized context.
|
01. Clone or download the `autodoc` repository, open a terminal inside the [example_docs](https://github.com/ldericher/autodoc/tree/master/example_docs) directory
|
||||||
|
|
||||||
### Deploy a container
|
01. Deploy an `autodoc` container:
|
||||||
|
|
||||||
`autodoc` can be pulled from the docker hub using `docker pull ldericher/autodoc`.
|
```bash
|
||||||
|
docker run --rm -it \
|
||||||
|
--volume "${PWD}":/docs \
|
||||||
|
--user "$(id -u):$(id -g)" \
|
||||||
|
ldericher/autodoc
|
||||||
|
```
|
||||||
|
|
||||||
When deploying an `autodoc` container, mount your document root to `/docs`. You *should* also set the container's UID and GID.
|
The contents of the directory are now being watched by `autodoc`!
|
||||||
|
|
||||||
#### Included software
|
When deploying an `autodoc` container, just mount your document root to `/docs`. You *should* also set the container's UID and GID. These are seen above.
|
||||||
|
|
||||||
TODO `ldericher/autodoc` contains `pandoc`.
|
01. Edit some stuff, save -- and watch the magic happen (and the terminal output).
|
||||||
|
|
||||||
#### tl;dr
|
On each file change, `autodoc` searches relevant build instruction files (Makefiles etc.) and kicks off build processes accordingly.
|
||||||
|
|
||||||
Deploy an `autodoc` instance in your current working dir:
|
### How *not* to use `autodoc`
|
||||||
|
|
||||||
docker run --name autodoc -d -v "${PWD}":/docs --user "$(id -u):$(id -g)" ldericher/autodoc
|
`autodoc` is **not** a solution for Continuous Integration of large scale systems software! `autodoc` excels at building a large number of independent, small files.
|
||||||
|
|
||||||
### Automating builds
|
### Deploying without Docker
|
||||||
|
|
||||||
Example automated builds can be found [here](https://github.com/ldericher/autodoc/tree/master/example_docs).
|
`autodoc` only hard-depends on `inotifywait` from [inotify-tools](https://github.com/rvoicilas/inotify-tools) to recursively watch Linux file system directories.
|
||||||
|
|
||||||
In general, just put a build instruction file into any (sub-)directory watched by `autodoc` and add your source files.
|
You will usually want to install a `LaTeX` distribution and setup `pandoc`.
|
||||||
|
|
||||||
|
## Prime use case: Nextcloud
|
||||||
|
|
||||||
|
Nextcloud is a "safe home for all your data" that can [easily be deployed using docker-compose](https://hub.docker.com/_/nextcloud).
|
||||||
|
Add an `autodoc` container to create directories where PDFs are automatically held up to date for all your documents. This extends upon the "[Base version - apache](https://hub.docker.com/_/nextcloud#base-version---apache)" of the Nextcloud compose deployment.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
documents:
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
volumes:
|
||||||
|
- documents:/opt/autodoc
|
||||||
|
|
||||||
|
autodoc:
|
||||||
|
restart: always
|
||||||
|
image: ldericher/autodoc
|
||||||
|
user: "UID:GID"
|
||||||
|
volumes:
|
||||||
|
- documents:/docs
|
||||||
|
```
|
||||||
|
|
||||||
|
The "user" key should be set to the same numeric IDs used for the nextcloud worker processes! To find the right IDs, issue `docker-compose exec app sh -c 'id -u www-data; id -g www-data'`.
|
||||||
|
For the apache containers, this should evaluate to "33:33".
|
||||||
|
|
||||||
|
To begin, add the mounted `/opt/autodoc` as a 'local type' external storage to your Nextcloud instance.
|
||||||
|
You might need to setup the permissions on your new volume using `docker-compose exec app chown -R www-data:www-data /opt/autodoc`.
|
||||||
|
|
||||||
|
## Concept: Source patterns
|
||||||
|
|
||||||
|
To avoid unnecessary rebuilds and self-triggering, `autodoc` uses "source patterns" to filter for the relevant build instructions.
|
||||||
|
A source pattern is a `bash` regular expression matching any filename that should be regarded as a "source file" to the build instruction file.
|
||||||
|
|
||||||
|
For instance, if a Makefile instructs how to build from Markdown source files, that Makefile's source pattern should likely be `\.md$`.
|
||||||
|
|
||||||
|
## Creating an automated build
|
||||||
|
|
||||||
|
In general, just put your source files into any (sub-)directory watched by `autodoc`. Add a build instruction file.
|
||||||
|
|
||||||
On each file change, its containing directory is searched for a build instruction file. Watched parent directories are also probed for further build instructions.
|
On each file change, its containing directory is searched for a build instruction file. Watched parent directories are also probed for further build instructions.
|
||||||
Every relevant instruction file will be executed as found.
|
Every relevant instruction file will be executed as found.
|
||||||
|
|
||||||
You may combine build instruction systems to your liking.
|
You may combine build instruction systems to your liking.
|
||||||
|
|
||||||
#### SRCPAT concept, "relevant" build instructions
|
## Build instruction systems
|
||||||
|
|
||||||
To avoid unnecessary rebuilds and self-triggering, `autodoc` uses "source patterns" to decide which build instructions are relevant.
|
### GNU Make (Makefiles)
|
||||||
|
|
||||||
For instance, if a build instruction file describes building anything from Markdown files, its source pattern should be something like `\.md$` to match files with ".md" as last extension. Source patterns are `bash` regular expressions.
|
`autodoc` supports GNU Makefiles.
|
||||||
|
However, Makefiles must contain a SRCPAT annotation comment as follows, where `<regex>` is a source pattern as above.
|
||||||
#### GNU Make (Makefiles)
|
|
||||||
|
|
||||||
`autodoc` supports standard Makefiles.
|
|
||||||
`Makefile`s must contain a SRCPAT annotation comment as follows, where `<regex>` is the source pattern as above.
|
|
||||||
|
|
||||||
```Makefile
|
```Makefile
|
||||||
#@SRCPAT <regex>
|
#@SRCPAT <regex>
|
||||||
|
|
@ -56,16 +98,10 @@ For instance, if a build instruction file describes building anything from Markd
|
||||||
|
|
||||||
If there are multiple SRCPAT annotations, the lowermost one will be used.
|
If there are multiple SRCPAT annotations, the lowermost one will be used.
|
||||||
|
|
||||||
##### Advanced options
|
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.
|
|
||||||
|
|
||||||
```Makefile
|
```Makefile
|
||||||
.PHONY: autodoc
|
.PHONY: autodoc
|
||||||
autodoc:
|
autodoc:
|
||||||
@echo "Hello World!"
|
@echo "Hello World!"
|
||||||
```
|
```
|
||||||
|
|
||||||
## What not to use `autodoc` for
|
|
||||||
|
|
||||||
`autodoc` excels at building a large number of independent small files. It is **not** a solution for Continuous Integration of large scale software systems!
|
|
||||||
|
|
|
||||||
|
|
@ -4,28 +4,37 @@
|
||||||
g_watchroot="$(readlink -f "${1:-.}")"
|
g_watchroot="$(readlink -f "${1:-.}")"
|
||||||
|
|
||||||
# compile using bare make command
|
# compile using bare make command
|
||||||
do_make() { # $1:DIR $2:OBJECT
|
do_make() { # $1:DIR $2:MAKEFILE $3:OBJECT
|
||||||
# extract params
|
# extract params
|
||||||
local dir="$1"
|
local dir="$1"
|
||||||
local object="$2"
|
local makefile="$2"
|
||||||
|
local object="$3"
|
||||||
|
|
||||||
# extract Makefile 'source pattern'
|
# check Makefile 'source pattern'
|
||||||
local srcpat="$(grep -E "^#@SRCPAT" "${dir}/Makefile" | tail -n 1 | sed -r "s/^#@SRCPAT\s+//")"
|
local srcpat="$(grep -E "^#@SRCPAT" "${dir}/${makefile}" | tail -n 1 | sed -r "s/^#@SRCPAT\s+//")"
|
||||||
|
|
||||||
if [ -z "${srcpat}" ]; then
|
if [ -z "${srcpat}" ]; then
|
||||||
echo "Empty source pattern! Makefile needs '#@SRCPAT' annotation!"
|
echo -n "Empty source pattern, check '#@SRCPAT' annotation! "
|
||||||
|
return 1
|
||||||
|
|
||||||
elif [[ "${object}" =~ ${srcpat} ]]; then
|
elif [[ "${object}" =~ ${srcpat} ]]; then
|
||||||
# check for autodoc target
|
# check for autodoc target
|
||||||
local target="$(grep -E "^autodoc:" "${dir}/Makefile" | sed -r "s/:.*$//")"
|
local target="$(grep -E "^autodoc:" "${dir}/${makefile}" | sed -r "s/:.*$//")"
|
||||||
local target="${target:-all}"
|
|
||||||
|
|
||||||
echo "SRCPAT OK, building '${target}'."
|
if [ -z "${target}" ]; then
|
||||||
make --no-print-directory -C "${dir}" -j "${target}"
|
echo "Running 'make'. "
|
||||||
|
else
|
||||||
|
echo "Making '${target}'. "
|
||||||
|
fi
|
||||||
|
|
||||||
|
make --no-print-directory -C "${dir}" -j ${target}
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "SRCPAT mismatch '${srcpat}'."
|
echo -n "SRCPAT '${srcpat}' mismatch. "
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# compile a directory
|
# compile a directory
|
||||||
|
|
@ -39,16 +48,15 @@ do_compile() { # $1:DIR $2:OBJECT $3:DONE
|
||||||
|
|
||||||
if [ -r "${dir}/Makefile" ]; then
|
if [ -r "${dir}/Makefile" ]; then
|
||||||
# Makefile found
|
# Makefile found
|
||||||
echo -n "Using '${dir}/Makefile'. "
|
echo -n "Found '${dir}/Makefile': "
|
||||||
do_make "${dir}" "${object}"
|
do_make "${dir}" "Makefile" "${object}" \
|
||||||
local done="1"
|
&& local done="1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# search parent dir for more build instructions
|
# never leave $g_watchroot
|
||||||
if [ "${dir}" != "${g_watchroot}" ]; then
|
if [ "${dir}" != "${g_watchroot}" ]; then
|
||||||
# never leave $g_watchroot
|
# search parent dir for more build instructions
|
||||||
local dir="$(dirname "${dir}")"
|
do_compile "$(dirname "${dir}")" "${object}" "${done}"
|
||||||
do_compile "${dir}" "${object}" "${done}"
|
|
||||||
|
|
||||||
elif [ "${done}" == "0" ]; then
|
elif [ "${done}" == "0" ]; then
|
||||||
# hit $g_watchroot
|
# hit $g_watchroot
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue