#!/usr/bin/env bash # ------------------------------------------------------------------------------ # Run the built-in Sphinx development server. Sphinx will watch the project # directory and rebuild the documentation when a change is detected. The # documentation is available at http://localhost: (default port is 8000). # # Examples: # ./serve.sh # ./serve.sh --name my-documentation --interface 0.0.0.0 --port 9000 # ------------------------------------------------------------------------------ PROJECT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" # shellcheck disable=SC1090 source "${PROJECT_DIR}/bin/shflags/shflags" # shellcheck disable=SC1090 source "${PROJECT_DIR}/bin/ansi/ansi" # shellcheck disable=SC1090 source "${PROJECT_DIR}/bin/ndd-log4b/ndd-log4b.sh" # shellcheck disable=SC1090 source "${PROJECT_DIR}/bin/ndd-utils4b/ndd-utils4b.sh" # shellcheck disable=SC1090 source "${PROJECT_DIR}/bin/variables.sh" # disable before shflags ndd::base::catch_more_errors_off DEFINE_string "name" "${DDIDIER_SPHINX_CONTAINER_NAME}" "The name of the container" "n" DEFINE_string "interface" "${DDIDIER_SPHINX_CONTAINER_EXPOSED_INTERFACE}" "The network interface on the host machine the container is bound to" "i" DEFINE_integer "port" "${DDIDIER_SPHINX_CONTAINER_EXPOSED_PORT}" "The port on the host machine the container is bound to" "p" DEFINE_boolean "debug" false "Enable debug mode" "d" read -r -d '' FLAGS_HELP <. The default port is ${DDIDIER_SPHINX_CONTAINER_EXPOSED_PORT}. Examples: ./serve.sh ./serve.sh --name my-documentation --interface 0.0.0.0 --port 9000 EOF # parse the command-line FLAGS "$@" || exit $? eval set -- "${FLAGS_ARGV}" # enable after shflags ndd::base::catch_more_errors_on function main() { if [[ "${FLAGS_debug}" -eq "${FLAGS_TRUE}" ]]; then # shellcheck disable=SC2034 ndd::logger::set_stdout_level "DEBUG" else # shellcheck disable=SC2034 ndd::logger::set_stdout_level "INFO" fi local container_name="${FLAGS_name}" local exposed_interface="${FLAGS_interface}" local exposed_port="${FLAGS_port}" if [[ -z "${container_name}" ]]; then log error "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log error "┃ The container name cannot be empty. Please use '-n' or '--name'" log error "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" exit 1 fi if [[ -z "${exposed_interface}" ]]; then log error "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log error "┃ The exposed interface cannot be empty. Please use '-i' or '--interface'." log error "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" exit 1 fi if [[ -z "${exposed_port}" ]]; then log error "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log error "┃ The exposed port cannot be empty. Please use '-p' or '--port'." log error "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" exit 1 fi local docker_image="ddidier/sphinx-doc:${DDIDIER_SPHINX_IMAGE_VERSION}" local source_directory="${PROJECT_DIR}" # Use the terminal if present # local container_uid="${UID}" # local container_username="${USER}" local container_uid local container_username container_uid="$(id -u)" container_username="$(id -u -n)" if [[ -L "${source_directory}" ]]; then log warning "The source directory cannot be a symbolic link." source_directory="$(realpath "${source_directory}")" fi log info "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log info "┃ Serving the Sphinx documentation" log info "┃" log info "┃ - using the Docker image: ${docker_image}" log info "┃ - in the container: ${container_name}" log info "┃ - as the user: ${container_username}" log info "┃ - as the user ID: ${container_uid}" log info "┃ - listening on interface: ${exposed_interface}" log info "┃ - listening on port: ${exposed_port}" log info "┃" log info "┃ This container can usually be terminated with: Control+C" log info "┃ But if this does not work: docker kill ${container_name}" log info "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" # Use the TTY if present local docker_run_interactive="" local docker_run_tty="" if [[ -t 1 ]]; then docker_run_interactive="-i" docker_run_tty="-t" fi # Ignore files specified in variables.sh local ignored_files="" for ignored_file in "${DDIDIER_SPHINX_PROJECT_IGNORED_FILES[@]}"; do ignored_files="${ignored_files} --ignore \"${ignored_file}\"" done # echo \ # docker run --rm \ # ${docker_run_interactive} \ # ${docker_run_tty} \ # --name "${container_name}" \ # -e USER_ID="${container_uid}" \ # -e USER_NAME="${container_username}" \ # -p "${exposed_interface}:${exposed_port}:${exposed_port}" \ # -v "${source_directory}":/data \ # "${docker_image}" \ # make --makefile=Makefile-sphinx \ # SPHINXPORT="${exposed_port}" \ # SPHINXIGNORE="${ignored_files}" \ # livehtml "$@" \ # || true log debug "$(ndd::print::script_output_start)" docker run --rm \ ${docker_run_interactive} \ ${docker_run_tty} \ --name "${container_name}" \ -e USER_ID="${container_uid}" \ -e USER_NAME="${container_username}" \ -p "${exposed_interface}:${exposed_port}:${exposed_port}" \ -v "${source_directory}":/data \ "${docker_image}" \ make --makefile=Makefile-sphinx \ SPHINXPORT="${exposed_port}" \ SPHINXIGNORE="${ignored_files}" \ livehtml "$@" \ || true log debug "$(ndd::print::script_output_end)" log info " ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" log info " ┃ BUILD -- Success! " log info " ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" } function error_handler() { local error_code="$?" test $error_code == 0 && return; log error "An unexpected error has occured:\n%s" "$(ndd::base::print_stack_trace 2>&1)" exit 1 } trap 'error_handler ${?}' ERR main "${@}" exit 0