diff --git a/README.md b/README.md index 20430a4..43966a8 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,13 @@ scripts/setup-dcmtk.sh --source-dir /path/to/dcmtk/bin scripts/setup-microdicom.sh --source-dir /path/to/microdicom ``` +Or download your hosted release assets directly: + +```bash +scripts/setup-dcmtk.sh --archive-url https://github.com///releases/download//dcmtk-bin.tar.gz +scripts/setup-microdicom.sh --archive-url https://github.com///releases/download//microdicom.zip +``` + Create a local config file from the template: ```bash diff --git a/scripts/setup-dcmtk.sh b/scripts/setup-dcmtk.sh index 27694ad..223d072 100755 --- a/scripts/setup-dcmtk.sh +++ b/scripts/setup-dcmtk.sh @@ -4,29 +4,69 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" INSTALL_DIR="${INSTALL_DIR:-$ROOT_DIR/.local/dcmtk-bin}" REQUIRED_BINS=(storescp movescu storescu findscu dcmdump dcmodify getscu echoscu dcmj2pnm) +SOURCE_DIR="" +ARCHIVE_URL="" +TMP_DIR="" usage() { cat <<'EOF' Usage: - scripts/setup-dcmtk.sh [--source-dir DIR] [--install-dir DIR] + scripts/setup-dcmtk.sh [--source-dir DIR | --archive-url URL] [--install-dir DIR] Behavior: - Copies required DCMTK binaries into a local ignored directory. - If --source-dir is omitted, binaries are resolved from PATH. + - If --archive-url is given, the script downloads and extracts an archive, + then searches for the required binaries inside it. Examples: scripts/setup-dcmtk.sh --source-dir /opt/dcmtk/bin + scripts/setup-dcmtk.sh --archive-url https://github.com///releases/download//dcmtk-bin.tar.gz scripts/setup-dcmtk.sh --install-dir /data/dcmtk-bin EOF } -SOURCE_DIR="" +download() { + local url="$1" + local out="$2" + if command -v curl >/dev/null 2>&1; then + curl -fL "$url" -o "$out" + elif command -v wget >/dev/null 2>&1; then + wget -O "$out" "$url" + else + echo "need curl or wget to download $url" >&2 + exit 1 + fi +} + +extract_archive() { + local archive="$1" + local dest="$2" + case "$archive" in + *.tar.gz|*.tgz) tar -xzf "$archive" -C "$dest" ;; + *.tar.xz) tar -xJf "$archive" -C "$dest" ;; + *.tar) tar -xf "$archive" -C "$dest" ;; + *.zip) + command -v unzip >/dev/null 2>&1 || { echo "unzip is required for $archive" >&2; exit 1; } + unzip -q "$archive" -d "$dest" + ;; + *) + echo "unsupported archive format: $archive" >&2 + exit 1 + ;; + esac +} + while [[ $# -gt 0 ]]; do case "$1" in --source-dir) SOURCE_DIR="${2:?missing value for --source-dir}" shift 2 ;; + --archive-url) + ARCHIVE_URL="${2:?missing value for --archive-url}" + shift 2 + ;; --install-dir) INSTALL_DIR="${2:?missing value for --install-dir}" shift 2 @@ -43,13 +83,36 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -n "$SOURCE_DIR" && -n "$ARCHIVE_URL" ]]; then + echo "use only one of --source-dir or --archive-url" >&2 + exit 1 +fi + +cleanup() { + [[ -n "$TMP_DIR" && -d "$TMP_DIR" ]] && rm -rf "$TMP_DIR" +} +trap cleanup EXIT + +if [[ -n "$ARCHIVE_URL" ]]; then + TMP_DIR="$(mktemp -d)" + archive="$TMP_DIR/archive" + download "$ARCHIVE_URL" "$archive" + mkdir -p "$TMP_DIR/extracted" + mv "$archive" "$TMP_DIR/archive$(basename "$ARCHIVE_URL" | sed 's/.*\(\.[^.][^.]*\)$/\1/')" 2>/dev/null || true + archive_path="$(find "$TMP_DIR" -maxdepth 1 -type f | head -n 1)" + extract_archive "$archive_path" "$TMP_DIR/extracted" + SOURCE_DIR="$TMP_DIR/extracted" +fi + mkdir -p "$INSTALL_DIR" resolve_bin() { local name="$1" if [[ -n "$SOURCE_DIR" ]]; then - local candidate="$SOURCE_DIR/$name" - [[ -x "$candidate" ]] || { echo "missing executable: $candidate" >&2; return 1; } + local candidate + candidate="$(find "$SOURCE_DIR" -type f -name "$name" -perm -u+x | head -n 1 || true)" + [[ -n "$candidate" ]] || candidate="$(find "$SOURCE_DIR" -type f -name "$name" | head -n 1 || true)" + [[ -n "$candidate" ]] || { echo "missing binary in source: $name" >&2; return 1; } printf '%s\n' "$candidate" return 0 fi diff --git a/scripts/setup-microdicom.sh b/scripts/setup-microdicom.sh index 30eac98..93c4d9d 100755 --- a/scripts/setup-microdicom.sh +++ b/scripts/setup-microdicom.sh @@ -3,25 +3,66 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" INSTALL_DIR="${INSTALL_DIR:-$ROOT_DIR/.local/microdicom}" +SOURCE_DIR="" +ARCHIVE_URL="" +TMP_DIR="" usage() { cat <<'EOF' Usage: - scripts/setup-microdicom.sh --source-dir DIR [--install-dir DIR] + scripts/setup-microdicom.sh [--source-dir DIR | --archive-url URL] [--install-dir DIR] Behavior: - Copies a prepared MicroDicom directory into a local ignored directory. - - Expected source contents include files like AUTORUN.INF, RUN.BAT, and MICROD/. + - With --archive-url, downloads and extracts an archive, then searches for + a directory containing AUTORUN.INF and MICROD/. + +Example: + scripts/setup-microdicom.sh --archive-url https://github.com///releases/download//microdicom.zip EOF } -SOURCE_DIR="" +download() { + local url="$1" + local out="$2" + if command -v curl >/dev/null 2>&1; then + curl -fL "$url" -o "$out" + elif command -v wget >/dev/null 2>&1; then + wget -O "$out" "$url" + else + echo "need curl or wget to download $url" >&2 + exit 1 + fi +} + +extract_archive() { + local archive="$1" + local dest="$2" + case "$archive" in + *.tar.gz|*.tgz) tar -xzf "$archive" -C "$dest" ;; + *.tar.xz) tar -xJf "$archive" -C "$dest" ;; + *.tar) tar -xf "$archive" -C "$dest" ;; + *.zip) + command -v unzip >/dev/null 2>&1 || { echo "unzip is required for $archive" >&2; exit 1; } + unzip -q "$archive" -d "$dest" + ;; + *) + echo "unsupported archive format: $archive" >&2 + exit 1 + ;; + esac +} + while [[ $# -gt 0 ]]; do case "$1" in --source-dir) SOURCE_DIR="${2:?missing value for --source-dir}" shift 2 ;; + --archive-url) + ARCHIVE_URL="${2:?missing value for --archive-url}" + shift 2 + ;; --install-dir) INSTALL_DIR="${2:?missing value for --install-dir}" shift 2 @@ -38,7 +79,26 @@ while [[ $# -gt 0 ]]; do esac done -[[ -n "$SOURCE_DIR" ]] || { echo "--source-dir is required" >&2; exit 1; } +if [[ -n "$SOURCE_DIR" && -n "$ARCHIVE_URL" ]]; then + echo "use only one of --source-dir or --archive-url" >&2 + exit 1 +fi + +cleanup() { + [[ -n "$TMP_DIR" && -d "$TMP_DIR" ]] && rm -rf "$TMP_DIR" +} +trap cleanup EXIT + +if [[ -n "$ARCHIVE_URL" ]]; then + TMP_DIR="$(mktemp -d)" + archive="$TMP_DIR/$(basename "$ARCHIVE_URL")" + download "$ARCHIVE_URL" "$archive" + mkdir -p "$TMP_DIR/extracted" + extract_archive "$archive" "$TMP_DIR/extracted" + SOURCE_DIR="$(find "$TMP_DIR/extracted" -type f -name AUTORUN.INF -printf '%h\n' | head -n 1 || true)" +fi + +[[ -n "$SOURCE_DIR" ]] || { echo "one of --source-dir or --archive-url is required" >&2; exit 1; } [[ -d "$SOURCE_DIR" ]] || { echo "source directory does not exist: $SOURCE_DIR" >&2; exit 1; } [[ -f "$SOURCE_DIR/AUTORUN.INF" ]] || { echo "missing AUTORUN.INF in source directory" >&2; exit 1; } [[ -d "$SOURCE_DIR/MICROD" ]] || { echo "missing MICROD/ in source directory" >&2; exit 1; }