From 55bc1acf0a7be56d8191228497d81edd0168effc Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 04:22:11 +0000 Subject: [PATCH 1/4] Update Docker configuration with multi-OS support and improved scripts Major changes: - Migrate from EOL CentOS 7 to AlmaLinux 9 (CentOS successor) - Add OS-specific Dockerfiles for multiple distributions - AlmaLinux 9 (RHEL/CentOS compatible) - Ubuntu 22.04 LTS (Debian-based) - Amazon Linux 2023 (AWS optimized) - Alpine Linux (lightweight, musl-based) - Organize Docker files in dedicated docker/ directory - Add build-docker.sh script for easy multi-OS builds - Improve build.sh with better error handling and progress reporting - Enhance bin/ utility scripts (dwg2txt, dxf2txt, dxf2txt.py) - Add comprehensive help messages - Improve error handling - Add input validation - Modernize Python code with better structure - Update README.md with detailed Docker usage instructions - Document all supported OS distributions - Add examples for single and multi-OS builds - Add utility scripts documentation Benefits: - Security: Using actively maintained OS versions - Flexibility: Build binaries for multiple target platforms - Usability: Simplified build process with clear documentation - Maintainability: Better organized Docker configuration --- Dockerfile | 26 +++-- README.md | 127 ++++++++++++++++++++++-- bin/dwg2txt | 61 +++++++++++- bin/dxf2txt | 73 +++++++++++++- bin/dxf2txt.py | 122 +++++++++++++++++------ build.sh | 83 ++++++++++++++-- docker/Dockerfile.almalinux | 22 ++++ docker/Dockerfile.alpine | 24 +++++ docker/Dockerfile.amazonlinux | 23 +++++ docker/Dockerfile.ubuntu | 27 +++++ docker/build-docker.sh | 182 ++++++++++++++++++++++++++++++++++ 11 files changed, 715 insertions(+), 55 deletions(-) create mode 100644 docker/Dockerfile.almalinux create mode 100644 docker/Dockerfile.alpine create mode 100644 docker/Dockerfile.amazonlinux create mode 100644 docker/Dockerfile.ubuntu create mode 100755 docker/build-docker.sh diff --git a/Dockerfile b/Dockerfile index 92c81aa..5b32ab2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,26 @@ -FROM centos:7 +# Default Dockerfile for libdxfrw (AlmaLinux 9) +# For other OS options, see docker/ directory: +# - docker/Dockerfile.ubuntu (Ubuntu 22.04 LTS) +# - docker/Dockerfile.almalinux (AlmaLinux 9) +# - docker/Dockerfile.amazonlinux (Amazon Linux 2023) +# - docker/Dockerfile.alpine (Alpine Linux) -MAINTAINER CodeLibs Project +FROM almalinux:9 -RUN yum -y groupinstall base "Development tools" --setopt=group_package_types=mandatory,default,optional -RUN yum clean all +LABEL maintainer="CodeLibs Project" +LABEL description="Build environment for libdxfrw on AlmaLinux 9 (CentOS successor)" + +# Install build dependencies +RUN dnf -y groupinstall "Development Tools" && \ + dnf -y install \ + autoconf \ + automake \ + libtool \ + pkg-config \ + && dnf clean all -RUN mkdir /work WORKDIR /work -CMD ["sh", "/opt/bin/run.sh"] +# Default command +CMD ["sh", "/work/build.sh"] diff --git a/README.md b/README.md index 221e3ae..3f68f6a 100644 --- a/README.md +++ b/README.md @@ -145,25 +145,85 @@ cmake --build . --config Release --target install ### Docker Build -#### Build Docker Image: +Docker-based builds support multiple OS distributions for creating portable binaries. + +#### Quick Start (AlmaLinux 9 - Default): + +```bash +# Build the library using default OS (AlmaLinux 9) +./docker/build-docker.sh run almalinux +``` + +This creates `dxfrw-almalinux.tar.gz` in the project root. + +#### Available OS Distributions: + +| OS | Tag | Use Case | +|----|-----|----------| +| **AlmaLinux 9** | `almalinux` | RHEL/CentOS compatible binaries (CentOS successor) | +| **Ubuntu 22.04 LTS** | `ubuntu` | Debian/Ubuntu compatible binaries | +| **Amazon Linux 2023** | `amazonlinux` | AWS/Amazon Linux compatible binaries | +| **Alpine Linux** | `alpine` | Lightweight musl-based binaries | + +#### Build for Specific OS: ```bash -docker build --rm -t codelibs/libdxfrw . +# Build for Ubuntu +./docker/build-docker.sh run ubuntu + +# Build for Amazon Linux +./docker/build-docker.sh run amazonlinux + +# Build for Alpine Linux +./docker/build-docker.sh run alpine ``` -#### Build Library Using Docker: +#### Build for All OS Distributions: ```bash -docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:latest /work/build.sh +# Create binaries for all supported OS distributions +./docker/build-docker.sh run all-os ``` -This creates `dxfrw.tar.gz`. Extract it under `/opt` or your preferred location. +This creates multiple tar.gz files: +- `dxfrw-almalinux.tar.gz` +- `dxfrw-ubuntu.tar.gz` +- `dxfrw-amazonlinux.tar.gz` +- `dxfrw-alpine.tar.gz` + +#### Manual Docker Commands: + +If you prefer manual Docker commands: + +```bash +# Build Docker image +docker build --rm -t codelibs/libdxfrw:almalinux . + +# Build library using Docker +docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:almalinux /work/build.sh + +# For other OS, use the respective Dockerfile +docker build --rm -t codelibs/libdxfrw:ubuntu -f docker/Dockerfile.ubuntu . +docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:ubuntu /work/build.sh +``` + +#### Extract and Install: + +```bash +# Extract the archive under /opt +sudo tar xzf dxfrw-almalinux.tar.gz -C /opt + +# The library will be installed in /opt/dxfrw/ +ls /opt/dxfrw/ +``` #### Push Docker Image: ```bash -docker tag codelibs/libdxfrw codelibs/libdxfrw:centos7 -docker push codelibs/libdxfrw:centos7 +# Tag and push image +docker tag codelibs/libdxfrw:almalinux codelibs/libdxfrw:latest +docker push codelibs/libdxfrw:almalinux +docker push codelibs/libdxfrw:latest ``` ## Installation @@ -302,6 +362,59 @@ The source code in `dwg2dxf/` serves as a comprehensive reference implementation Extracts text information from DWG files. +## Utility Scripts + +The library includes utility scripts in the `bin/` directory for extracting text content from DXF/DWG files. + +### dwg2txt - DWG to Text Converter + +Extracts text entities from DWG files: + +```bash +# Usage +./bin/dwg2txt + +# Example +./bin/dwg2txt drawing.dwg output.txt +``` + +**Requirements:** +- `dwg2text` executable (built with the library) + +### dxf2txt - DXF to Text Converter + +Extracts text entities from DXF files: + +```bash +# Usage +./bin/dxf2txt + +# Example +./bin/dxf2txt drawing.dxf output.txt +``` + +**Requirements:** +- Python 3.6 or later +- `ezdxf` Python package: `pip install ezdxf` + +**Features:** +- Supports both TEXT and MTEXT entities +- Handles multiple DXF versions (R12 through 2018+) +- Automatic encoding detection (UTF-8, CP932/Shift-JIS) +- Preserves multi-line text formatting + +### Direct Python Usage + +You can also use the Python script directly: + +```bash +# Install ezdxf if not already installed +pip install ezdxf + +# Run the script +python3 bin/dxf2txt.py input.dxf output.txt +``` + ## Testing The library includes comprehensive tests covering various aspects: diff --git a/bin/dwg2txt b/bin/dwg2txt index 185a022..3403b25 100755 --- a/bin/dwg2txt +++ b/bin/dwg2txt @@ -1,9 +1,60 @@ #!/bin/bash +# +# dwg2txt - Convert DWG files to text format +# Uses dwg2text utility to extract text content from DWG files +# -INPUT_FILE=$1 -OUTPUT_FILE=$2 +set -e -`dirname $0`/dwg2text $INPUT_FILE > $OUTPUT_FILE -if [ $? != 0 ] ; then - echo > $OUTPUT_FILE +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Function to show usage +usage() { + cat << EOF +Usage: $0 + +Convert DWG file to text format by extracting text entities. + +Arguments: + input.dwg Input DWG file path + output.txt Output text file path + +Example: + $0 drawing.dwg output.txt + +EOF + exit 1 +} + +# Check arguments +if [ $# -ne 2 ]; then + echo "Error: Invalid number of arguments" + usage +fi + +INPUT_FILE="$1" +OUTPUT_FILE="$2" + +# Check if input file exists +if [ ! -f "$INPUT_FILE" ]; then + echo "Error: Input file does not exist: $INPUT_FILE" + exit 1 +fi + +# Check if dwg2text exists +DWG2TEXT="${SCRIPT_DIR}/dwg2text" +if [ ! -x "$DWG2TEXT" ]; then + echo "Error: dwg2text utility not found or not executable: $DWG2TEXT" + exit 1 +fi + +# Convert DWG to text +if "$DWG2TEXT" "$INPUT_FILE" > "$OUTPUT_FILE" 2>&1; then + echo "✓ Successfully converted: $OUTPUT_FILE" + exit 0 +else + echo "⚠ Warning: dwg2text failed, creating empty output file" + echo "" > "$OUTPUT_FILE" + exit 1 fi diff --git a/bin/dxf2txt b/bin/dxf2txt index 8db738a..dd7cea5 100755 --- a/bin/dxf2txt +++ b/bin/dxf2txt @@ -1,7 +1,74 @@ #!/bin/bash +# +# dxf2txt - Convert DXF files to text format +# Uses Python script to extract text content from DXF files +# -INPUT_FILE=$1 -OUTPUT_FILE=$2 +set -e -python `dirname $0`/dxf2txt.py $INPUT_FILE $OUTPUT_FILE +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Function to show usage +usage() { + cat << EOF +Usage: $0 + +Convert DXF file to text format by extracting text entities. + +Arguments: + input.dxf Input DXF file path + output.txt Output text file path + +Example: + $0 drawing.dxf output.txt + +Requirements: + - Python 3 + - ezdxf Python package (pip install ezdxf) + +EOF + exit 1 +} + +# Check arguments +if [ $# -ne 2 ]; then + echo "Error: Invalid number of arguments" + usage +fi + +INPUT_FILE="$1" +OUTPUT_FILE="$2" + +# Check if input file exists +if [ ! -f "$INPUT_FILE" ]; then + echo "Error: Input file does not exist: $INPUT_FILE" + exit 1 +fi + +# Find Python interpreter +PYTHON="" +for cmd in python3 python; do + if command -v $cmd >/dev/null 2>&1; then + PYTHON=$cmd + break + fi +done + +if [ -z "$PYTHON" ]; then + echo "Error: Python not found. Please install Python 3." + exit 1 +fi + +# Check if ezdxf is available +if ! $PYTHON -c "import ezdxf" 2>/dev/null; then + echo "Error: ezdxf package not found. Please install it:" + echo " pip install ezdxf" + exit 1 +fi + +# Convert DXF to text +$PYTHON "${SCRIPT_DIR}/dxf2txt.py" "$INPUT_FILE" "$OUTPUT_FILE" + +echo "✓ Successfully converted: $OUTPUT_FILE" diff --git a/bin/dxf2txt.py b/bin/dxf2txt.py index 68db0fe..14e8334 100644 --- a/bin/dxf2txt.py +++ b/bin/dxf2txt.py @@ -1,35 +1,101 @@ +#!/usr/bin/env python3 # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import absolute_import -from __future__ import generators -from __future__ import division +""" +dxf2txt.py - Extract text content from DXF files + +This script reads a DXF file and extracts all text entities (TEXT and MTEXT) +to a text file. It handles different DXF versions and character encodings. + +Usage: + python3 dxf2txt.py + +Requirements: + - Python 3.6+ + - ezdxf package (pip install ezdxf) + +Author: CodeLibs Project +""" import re import sys import ezdxf +from pathlib import Path + + +def show_usage(): + """Display usage information""" + print(__doc__) + sys.exit(1) + + +def extract_text_from_dxf(input_file, output_file): + """ + Extract text entities from DXF file and save to text file + + Args: + input_file: Path to input DXF file + output_file: Path to output text file + """ + # Check if input file exists + if not Path(input_file).exists(): + print(f"Error: Input file not found: {input_file}", file=sys.stderr) + sys.exit(1) + + try: + # Try reading with UTF-8 encoding first + dwg = ezdxf.readfile(input_file, encoding='utf-8') + + # For older DXF versions, try CP932 encoding (Japanese Shift-JIS) + old_enc_versions = ['AC1009', 'AC1015', 'AC1018'] + if dwg.dxfversion in old_enc_versions: + try: + dwg = ezdxf.readfile(input_file, encoding='cp932') + except: + pass # Keep UTF-8 version if CP932 fails + + # Extract text entities + texts = [] + modelspace = dwg.modelspace() + + for entity in modelspace: + if entity.dxftype() == 'TEXT': + # Simple text entity + texts.append(entity.dxf.text) + elif entity.dxftype() == 'MTEXT': + # Multi-line text entity + # Remove formatting codes and convert \P to newlines + text = re.sub(r'\{\\f[^;]+;([^}]+)\}', r'\1', entity.plain_text()) + text = text.replace('\\P', '\n') + texts.append(text) + + # Write extracted text to output file + with open(output_file, 'w', encoding='utf-8') as f: + for text in texts: + f.write(text + '\n') + + print(f"Extracted {len(texts)} text entities from {dwg.dxfversion} format DXF") + + except ezdxf.DXFError as e: + print(f"Error: Failed to read DXF file: {e}", file=sys.stderr) + sys.exit(1) + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + sys.exit(1) + + +def main(): + """Main entry point""" + # Check arguments + if len(sys.argv) != 3: + print(f"Error: Invalid arguments", file=sys.stderr) + show_usage() + + input_file = sys.argv[1] + output_file = sys.argv[2] + + extract_text_from_dxf(input_file, output_file) + -if len(sys.argv) != 3: - print("Invalid arguments: " + str(sys.argv)) - exit(1) - -dwg = ezdxf.readfile(sys.argv[1], encoding='utf-8') - -print(dwg.dxfversion) -old_enc_versions = ['AC1009', 'AC1015', 'AC1018'] -if dwg.dxfversion in old_enc_versions: - dwg = ezdxf.readfile(sys.argv[1], encoding='cp932') - -texts = [] -block_pattern = r'\{\f.*;([^}]+)\}' -modelspace = dwg.modelspace() -for e in modelspace: - if e.dxftype() == 'TEXT': - texts.append(e.dxf.text) - elif e.dxftype() == 'MTEXT': - v = re.sub(r'\{\\f[^;]+;([^}]+)\}', r'\1', e.plain_text()).replace('\\P', '\n') - texts.append(v) - -with open(sys.argv[2], 'w', encoding='utf-8') as f: - f.writelines([(t+'\n') for t in texts]) +if __name__ == '__main__': + main() diff --git a/build.sh b/build.sh index 56243cf..b9be8f7 100755 --- a/build.sh +++ b/build.sh @@ -1,11 +1,82 @@ #!/bin/bash +# +# Build script for libdxfrw +# This script is designed to run inside Docker containers +# and creates a distributable tar.gz archive +# +set -e # Exit on error + +echo "==========================================" +echo "libdxfrw Build Script" +echo "==========================================" + +# Configuration +PREFIX="/opt/dxfrw" +OUTPUT_DIR="/work" +OUTPUT_FILE="dxfrw.tar.gz" + +# Start timer +START_TIME=$(date +%s) + +# Step 1: Generate configure script +echo "" +echo "[1/6] Generating configure script..." autoreconf -vfi -./configure --prefix=/opt/dxfrw -make + +# Step 2: Configure build +echo "" +echo "[2/6] Configuring build..." +./configure --prefix="${PREFIX}" + +# Step 3: Build library +echo "" +echo "[3/6] Building library..." +make -j$(nproc) + +# Step 4: Install to prefix +echo "" +echo "[4/6] Installing to ${PREFIX}..." make install -make clean -cp bin/* /opt/dxfrw/bin + +# Step 5: Copy additional binaries if they exist +echo "" +echo "[5/6] Copying additional binaries..." +if [ -d "bin" ] && [ "$(ls -A bin 2>/dev/null)" ]; then + mkdir -p "${PREFIX}/bin" + cp -v bin/* "${PREFIX}/bin/" || true +else + echo "No additional binaries found in bin/ directory" +fi + +# Step 6: Create distributable archive +echo "" +echo "[6/6] Creating distributable archive..." cd /opt -tar zcvf /work/dxfrw.tar.gz dxfrw -chmod 777 /work/dxfrw.tar.gz +tar czf "${OUTPUT_DIR}/${OUTPUT_FILE}" dxfrw + +# Set permissions +chmod 644 "${OUTPUT_DIR}/${OUTPUT_FILE}" + +# Calculate elapsed time +END_TIME=$(date +%s) +ELAPSED=$((END_TIME - START_TIME)) + +# Show summary +echo "" +echo "==========================================" +echo "✓ Build completed successfully!" +echo "==========================================" +echo "Output file: ${OUTPUT_DIR}/${OUTPUT_FILE}" +echo "File size: $(du -h "${OUTPUT_DIR}/${OUTPUT_FILE}" | cut -f1)" +echo "Build time: ${ELAPSED} seconds" +echo "==========================================" +echo "" +echo "To extract the archive:" +echo " tar xzf ${OUTPUT_FILE} -C /opt" +echo "" + +# Clean up build artifacts +echo "Cleaning up build artifacts..." +cd /work +make clean 2>/dev/null || true diff --git a/docker/Dockerfile.almalinux b/docker/Dockerfile.almalinux new file mode 100644 index 0000000..8b57c6e --- /dev/null +++ b/docker/Dockerfile.almalinux @@ -0,0 +1,22 @@ +# AlmaLinux 9 Dockerfile for libdxfrw +# Use this for building RHEL/CentOS compatible binaries +# AlmaLinux is the successor to CentOS + +FROM almalinux:9 + +LABEL maintainer="CodeLibs Project" +LABEL description="Build environment for libdxfrw on AlmaLinux 9" + +# Install build dependencies +RUN dnf -y groupinstall "Development Tools" && \ + dnf -y install \ + autoconf \ + automake \ + libtool \ + pkg-config \ + && dnf clean all + +WORKDIR /work + +# Default command +CMD ["sh", "/work/build.sh"] diff --git a/docker/Dockerfile.alpine b/docker/Dockerfile.alpine new file mode 100644 index 0000000..091f1a5 --- /dev/null +++ b/docker/Dockerfile.alpine @@ -0,0 +1,24 @@ +# Alpine Linux Dockerfile for libdxfrw +# Use this for building lightweight musl-based binaries + +FROM alpine:3.19 + +LABEL maintainer="CodeLibs Project" +LABEL description="Build environment for libdxfrw on Alpine Linux (musl-based)" + +# Install build dependencies +# Note: Alpine uses musl libc instead of glibc +RUN apk add --no-cache \ + build-base \ + autoconf \ + automake \ + libtool \ + pkgconfig \ + bash \ + tar \ + gzip + +WORKDIR /work + +# Default command +CMD ["sh", "/work/build.sh"] diff --git a/docker/Dockerfile.amazonlinux b/docker/Dockerfile.amazonlinux new file mode 100644 index 0000000..66f9cec --- /dev/null +++ b/docker/Dockerfile.amazonlinux @@ -0,0 +1,23 @@ +# Amazon Linux 2023 Dockerfile for libdxfrw +# Use this for building AWS/Amazon Linux compatible binaries + +FROM amazonlinux:2023 + +LABEL maintainer="CodeLibs Project" +LABEL description="Build environment for libdxfrw on Amazon Linux 2023" + +# Install build dependencies +RUN dnf -y groupinstall "Development Tools" && \ + dnf -y install \ + autoconf \ + automake \ + libtool \ + pkg-config \ + tar \ + gzip \ + && dnf clean all + +WORKDIR /work + +# Default command +CMD ["sh", "/work/build.sh"] diff --git a/docker/Dockerfile.ubuntu b/docker/Dockerfile.ubuntu new file mode 100644 index 0000000..7a3466a --- /dev/null +++ b/docker/Dockerfile.ubuntu @@ -0,0 +1,27 @@ +# Ubuntu 22.04 LTS Dockerfile for libdxfrw +# Use this for building Debian/Ubuntu compatible binaries + +FROM ubuntu:22.04 AS builder + +LABEL maintainer="CodeLibs Project" +LABEL description="Build environment for libdxfrw on Ubuntu 22.04 LTS" + +# Avoid interactive prompts during package installation +ENV DEBIAN_FRONTEND=noninteractive + +# Install build dependencies +RUN apt-get update && \ + apt-get install -y \ + build-essential \ + autoconf \ + automake \ + libtool \ + pkg-config \ + libiconv-hook-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /work + +# Default command +CMD ["sh", "/work/build.sh"] diff --git a/docker/build-docker.sh b/docker/build-docker.sh new file mode 100755 index 0000000..f255df0 --- /dev/null +++ b/docker/build-docker.sh @@ -0,0 +1,182 @@ +#!/bin/bash +# +# Docker build script for libdxfrw +# Supports multiple OS/distributions +# +# Usage: +# ./docker/build-docker.sh [options] [os] +# +# Options: +# build - Build Docker image only +# run - Build library using Docker +# push - Push image to Docker Hub +# all - Build image, run build, and push (default) +# +# OS options: +# ubuntu - Ubuntu 22.04 LTS +# almalinux - AlmaLinux 9 (CentOS successor) +# amazonlinux - Amazon Linux 2023 +# alpine - Alpine Linux (musl-based) +# all-os - Build for all OS distributions +# +# Examples: +# ./docker/build-docker.sh build ubuntu +# ./docker/build-docker.sh run almalinux +# ./docker/build-docker.sh all amazonlinux +# ./docker/build-docker.sh run all-os +# + +set -e + +# Configuration +IMAGE_NAME="codelibs/libdxfrw" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +# Available OS distributions +declare -A OS_LIST=( + ["ubuntu"]="Dockerfile.ubuntu" + ["almalinux"]="Dockerfile.almalinux" + ["amazonlinux"]="Dockerfile.amazonlinux" + ["alpine"]="Dockerfile.alpine" +) + +# Function to print usage +usage() { + cat << EOF +Usage: $0 [action] [os] + +Actions: + build Build Docker image only + run Build library using Docker (creates tar.gz) + push Push image to Docker Hub + all Build image, run build, and push (default) + +OS Distributions: + ubuntu Ubuntu 22.04 LTS (Debian-based) + almalinux AlmaLinux 9 (RHEL-based, CentOS successor) + amazonlinux Amazon Linux 2023 (AWS optimized) + alpine Alpine Linux (lightweight, musl-based) + all-os Build for all distributions + +Examples: + $0 build ubuntu # Build Ubuntu image only + $0 run almalinux # Build library on AlmaLinux + $0 all amazonlinux # Build image, library, and push + $0 run all-os # Build library for all OS distributions + +EOF + exit 1 +} + +# Function to build Docker image +build_image() { + local os=$1 + local dockerfile=$2 + local tag="${IMAGE_NAME}:${os}" + + echo "==========================================" + echo "Building Docker image: ${tag}" + echo "Dockerfile: ${dockerfile}" + echo "==========================================" + + docker build --rm -t "${tag}" -f "${SCRIPT_DIR}/${dockerfile}" "${PROJECT_ROOT}" + + echo "✓ Image built successfully: ${tag}" +} + +# Function to run build inside Docker +run_build() { + local os=$1 + local tag="${IMAGE_NAME}:${os}" + local output_file="dxfrw-${os}.tar.gz" + + echo "==========================================" + echo "Building library using: ${tag}" + echo "Output: ${output_file}" + echo "==========================================" + + docker run -t --rm -v "${PROJECT_ROOT}:/work" "${tag}" /work/build.sh + + # Rename output file to include OS name + if [ -f "${PROJECT_ROOT}/dxfrw.tar.gz" ]; then + mv "${PROJECT_ROOT}/dxfrw.tar.gz" "${PROJECT_ROOT}/${output_file}" + echo "✓ Build completed: ${output_file}" + else + echo "✗ Error: Build output not found" + return 1 + fi +} + +# Function to push Docker image +push_image() { + local os=$1 + local tag="${IMAGE_NAME}:${os}" + + echo "==========================================" + echo "Pushing Docker image: ${tag}" + echo "==========================================" + + docker push "${tag}" + + echo "✓ Image pushed successfully: ${tag}" +} + +# Function to process single OS +process_os() { + local action=$1 + local os=$2 + local dockerfile=${OS_LIST[$os]} + + if [ -z "$dockerfile" ]; then + echo "Error: Unknown OS '${os}'" + echo "Available OS: ${!OS_LIST[@]}" + exit 1 + fi + + case $action in + build) + build_image "$os" "$dockerfile" + ;; + run) + build_image "$os" "$dockerfile" + run_build "$os" + ;; + push) + push_image "$os" + ;; + all) + build_image "$os" "$dockerfile" + run_build "$os" + push_image "$os" + ;; + *) + echo "Error: Unknown action '${action}'" + usage + ;; + esac +} + +# Main script +ACTION=${1:-all} +OS=${2:-almalinux} + +# Handle special case: all-os +if [ "$OS" = "all-os" ]; then + echo "==========================================" + echo "Processing all OS distributions" + echo "==========================================" + + for os in "${!OS_LIST[@]}"; do + echo "" + process_os "$ACTION" "$os" + done + + echo "" + echo "==========================================" + echo "✓ All OS distributions processed" + echo "==========================================" + ls -lh "${PROJECT_ROOT}"/dxfrw-*.tar.gz 2>/dev/null || true +else + process_os "$ACTION" "$OS" +fi From f202580e8e06735421379ef24280c1228c29106b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 04:36:23 +0000 Subject: [PATCH 2/4] Reorganize Docker structure and update Python requirements Changes: - Move root Dockerfile to docker/ directory for better organization - All Docker-related files now in docker/ directory - Maintains backward compatibility with docker/Dockerfile as default - Update Python version requirement from 3.6 to 3.9+ - Python 3.6 reached EOL in December 2021 - Python 3.9 is the minimum version across all supported OS: - Ubuntu 22.04 LTS: Python 3.10 - AlmaLinux 9: Python 3.9 - Amazon Linux 2023: Python 3.9 - Alpine Linux 3.19: Python 3.11 - Update README.md with migration guide - Add note about Docker structure change - Update manual Docker commands to reference docker/ directory - Document Python version requirements per OS - Update .gitignore to exclude Docker build artifacts - Add *.tar.gz pattern - Add dxfrw-*.tar.gz pattern for OS-specific builds Benefits: - Cleaner project structure with all Docker files organized - Up-to-date Python requirements matching supported OS distributions - Better documentation for users migrating from old structure --- .gitignore | 4 ++++ README.md | 14 +++++++++++--- bin/dxf2txt.py | 8 +++++++- Dockerfile => docker/Dockerfile | 12 ++++++------ 4 files changed, 28 insertions(+), 10 deletions(-) rename Dockerfile => docker/Dockerfile (56%) diff --git a/.gitignore b/.gitignore index ccab439..8db1792 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,7 @@ compile CMakeCache.txt cmake_install.cmake src/intern/.dirstamp + +# Docker build outputs +*.tar.gz +dxfrw-*.tar.gz diff --git a/README.md b/README.md index 3f68f6a..436251d 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,10 @@ cmake --build . --config Release --target install Docker-based builds support multiple OS distributions for creating portable binaries. +> **Note:** As of this version, all Dockerfiles have been moved to the `docker/` directory for better organization. +> If you were using the root `Dockerfile`, please use `docker/Dockerfile` or OS-specific files instead. +> The build process has been updated from CentOS 7 (EOL) to AlmaLinux 9. + #### Quick Start (AlmaLinux 9 - Default): ```bash @@ -196,8 +200,8 @@ This creates multiple tar.gz files: If you prefer manual Docker commands: ```bash -# Build Docker image -docker build --rm -t codelibs/libdxfrw:almalinux . +# Build Docker image (using default AlmaLinux) +docker build --rm -t codelibs/libdxfrw:almalinux -f docker/Dockerfile . # Build library using Docker docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:almalinux /work/build.sh @@ -205,6 +209,10 @@ docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:almalinux /work/build.sh # For other OS, use the respective Dockerfile docker build --rm -t codelibs/libdxfrw:ubuntu -f docker/Dockerfile.ubuntu . docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:ubuntu /work/build.sh + +# Or use the OS-specific Dockerfile directly +docker build --rm -t codelibs/libdxfrw:amazonlinux -f docker/Dockerfile.amazonlinux . +docker build --rm -t codelibs/libdxfrw:alpine -f docker/Dockerfile.alpine . ``` #### Extract and Install: @@ -394,7 +402,7 @@ Extracts text entities from DXF files: ``` **Requirements:** -- Python 3.6 or later +- Python 3.9 or later (minimum version across all Docker build environments) - `ezdxf` Python package: `pip install ezdxf` **Features:** diff --git a/bin/dxf2txt.py b/bin/dxf2txt.py index 14e8334..30331fc 100644 --- a/bin/dxf2txt.py +++ b/bin/dxf2txt.py @@ -10,9 +10,15 @@ python3 dxf2txt.py Requirements: - - Python 3.6+ + - Python 3.9+ (minimum version available across all supported OS distributions) - ezdxf package (pip install ezdxf) +Supported OS and their Python versions: + - Ubuntu 22.04 LTS: Python 3.10 + - AlmaLinux 9: Python 3.9 + - Amazon Linux 2023: Python 3.9 + - Alpine Linux 3.19: Python 3.11 + Author: CodeLibs Project """ diff --git a/Dockerfile b/docker/Dockerfile similarity index 56% rename from Dockerfile rename to docker/Dockerfile index 5b32ab2..f42f878 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -1,9 +1,10 @@ # Default Dockerfile for libdxfrw (AlmaLinux 9) -# For other OS options, see docker/ directory: -# - docker/Dockerfile.ubuntu (Ubuntu 22.04 LTS) -# - docker/Dockerfile.almalinux (AlmaLinux 9) -# - docker/Dockerfile.amazonlinux (Amazon Linux 2023) -# - docker/Dockerfile.alpine (Alpine Linux) +# This is a symbolic/default build configuration +# For OS-specific builds, use the corresponding Dockerfile: +# - Dockerfile.ubuntu (Ubuntu 22.04 LTS) +# - Dockerfile.almalinux (AlmaLinux 9 - RHEL/CentOS compatible) +# - Dockerfile.amazonlinux (Amazon Linux 2023) +# - Dockerfile.alpine (Alpine Linux - lightweight) FROM almalinux:9 @@ -23,4 +24,3 @@ WORKDIR /work # Default command CMD ["sh", "/work/build.sh"] - From 682020cdef932350a56d0d31c6d1b5f95c247831 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 04:41:47 +0000 Subject: [PATCH 3/4] Clean up Docker structure and improve documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Remove duplicate docker/Dockerfile (AlmaLinux 9) - Eliminates redundancy with docker/Dockerfile.almalinux - All OS configurations now use consistent Dockerfile.{os} naming - Simplify and reorganize README.md Docker section - Reduce from ~90 lines to ~40 lines (55% reduction) - Focus on build-docker.sh usage as primary method - Remove verbose manual Docker command examples - Keep only essential information and quick reference - Add docker/README.md for directory documentation - Clear explanation of each Dockerfile - Usage examples and OS selection guide - Quick reference for build-docker.sh Structure now: docker/ ├── Dockerfile.almalinux (RHEL/CentOS compatible) ├── Dockerfile.ubuntu (Debian/Ubuntu compatible) ├── Dockerfile.amazonlinux (AWS optimized) ├── Dockerfile.alpine (Lightweight) ├── build-docker.sh (Automated build script) └── README.md (Directory documentation) Benefits: - No duplicate files - cleaner structure - Consistent naming convention (Dockerfile.{os}) - More concise main README - Better organized documentation - Easier to maintain and understand --- README.md | 86 +++++++++++------------------------------------ docker/Dockerfile | 26 -------------- docker/README.md | 55 ++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 93 deletions(-) delete mode 100644 docker/Dockerfile create mode 100644 docker/README.md diff --git a/README.md b/README.md index 436251d..87c2eb2 100644 --- a/README.md +++ b/README.md @@ -145,93 +145,45 @@ cmake --build . --config Release --target install ### Docker Build -Docker-based builds support multiple OS distributions for creating portable binaries. +Build portable binaries for multiple OS distributions using Docker. -> **Note:** As of this version, all Dockerfiles have been moved to the `docker/` directory for better organization. -> If you were using the root `Dockerfile`, please use `docker/Dockerfile` or OS-specific files instead. -> The build process has been updated from CentOS 7 (EOL) to AlmaLinux 9. +> **Note:** Dockerfiles are in `docker/` directory. Build process updated from CentOS 7 (EOL) to AlmaLinux 9. -#### Quick Start (AlmaLinux 9 - Default): - -```bash -# Build the library using default OS (AlmaLinux 9) -./docker/build-docker.sh run almalinux -``` - -This creates `dxfrw-almalinux.tar.gz` in the project root. - -#### Available OS Distributions: +**Available OS Distributions:** | OS | Tag | Use Case | |----|-----|----------| -| **AlmaLinux 9** | `almalinux` | RHEL/CentOS compatible binaries (CentOS successor) | -| **Ubuntu 22.04 LTS** | `ubuntu` | Debian/Ubuntu compatible binaries | -| **Amazon Linux 2023** | `amazonlinux` | AWS/Amazon Linux compatible binaries | -| **Alpine Linux** | `alpine` | Lightweight musl-based binaries | +| AlmaLinux 9 | `almalinux` | RHEL/CentOS compatible (CentOS successor) | +| Ubuntu 22.04 LTS | `ubuntu` | Debian/Ubuntu compatible | +| Amazon Linux 2023 | `amazonlinux` | AWS optimized | +| Alpine Linux | `alpine` | Lightweight musl-based | -#### Build for Specific OS: +**Quick Start:** ```bash -# Build for Ubuntu +# Build for single OS (creates dxfrw-{os}.tar.gz) +./docker/build-docker.sh run almalinux ./docker/build-docker.sh run ubuntu -# Build for Amazon Linux -./docker/build-docker.sh run amazonlinux - -# Build for Alpine Linux -./docker/build-docker.sh run alpine -``` - -#### Build for All OS Distributions: - -```bash -# Create binaries for all supported OS distributions +# Build for all OS distributions ./docker/build-docker.sh run all-os -``` -This creates multiple tar.gz files: -- `dxfrw-almalinux.tar.gz` -- `dxfrw-ubuntu.tar.gz` -- `dxfrw-amazonlinux.tar.gz` -- `dxfrw-alpine.tar.gz` - -#### Manual Docker Commands: - -If you prefer manual Docker commands: - -```bash -# Build Docker image (using default AlmaLinux) -docker build --rm -t codelibs/libdxfrw:almalinux -f docker/Dockerfile . - -# Build library using Docker -docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:almalinux /work/build.sh - -# For other OS, use the respective Dockerfile -docker build --rm -t codelibs/libdxfrw:ubuntu -f docker/Dockerfile.ubuntu . -docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:ubuntu /work/build.sh - -# Or use the OS-specific Dockerfile directly -docker build --rm -t codelibs/libdxfrw:amazonlinux -f docker/Dockerfile.amazonlinux . -docker build --rm -t codelibs/libdxfrw:alpine -f docker/Dockerfile.alpine . +# Extract and install +sudo tar xzf dxfrw-almalinux.tar.gz -C /opt ``` -#### Extract and Install: +**Manual Docker Commands (if needed):** ```bash -# Extract the archive under /opt -sudo tar xzf dxfrw-almalinux.tar.gz -C /opt - -# The library will be installed in /opt/dxfrw/ -ls /opt/dxfrw/ +# Build image and library +docker build -t codelibs/libdxfrw:ubuntu -f docker/Dockerfile.ubuntu . +docker run -t --rm -v `pwd`:/work codelibs/libdxfrw:ubuntu /work/build.sh ``` -#### Push Docker Image: +**Push to Docker Hub:** ```bash -# Tag and push image -docker tag codelibs/libdxfrw:almalinux codelibs/libdxfrw:latest -docker push codelibs/libdxfrw:almalinux -docker push codelibs/libdxfrw:latest +./docker/build-docker.sh push almalinux ``` ## Installation diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index f42f878..0000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -# Default Dockerfile for libdxfrw (AlmaLinux 9) -# This is a symbolic/default build configuration -# For OS-specific builds, use the corresponding Dockerfile: -# - Dockerfile.ubuntu (Ubuntu 22.04 LTS) -# - Dockerfile.almalinux (AlmaLinux 9 - RHEL/CentOS compatible) -# - Dockerfile.amazonlinux (Amazon Linux 2023) -# - Dockerfile.alpine (Alpine Linux - lightweight) - -FROM almalinux:9 - -LABEL maintainer="CodeLibs Project" -LABEL description="Build environment for libdxfrw on AlmaLinux 9 (CentOS successor)" - -# Install build dependencies -RUN dnf -y groupinstall "Development Tools" && \ - dnf -y install \ - autoconf \ - automake \ - libtool \ - pkg-config \ - && dnf clean all - -WORKDIR /work - -# Default command -CMD ["sh", "/work/build.sh"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..671d89b --- /dev/null +++ b/docker/README.md @@ -0,0 +1,55 @@ +# Docker Build Configuration + +This directory contains Docker build configurations for libdxfrw supporting multiple OS distributions. + +## Files + +- **`Dockerfile.ubuntu`** - Ubuntu 22.04 LTS (Debian-based) +- **`Dockerfile.almalinux`** - AlmaLinux 9 (RHEL/CentOS compatible, CentOS successor) +- **`Dockerfile.amazonlinux`** - Amazon Linux 2023 (AWS optimized) +- **`Dockerfile.alpine`** - Alpine Linux (lightweight, musl-based) +- **`build-docker.sh`** - Automated build script for all distributions + +## Quick Usage + +```bash +# Build for single OS +./build-docker.sh run almalinux + +# Build for all OS +./build-docker.sh run all-os + +# See all options +./build-docker.sh +``` + +## Output + +Each build creates a tar.gz archive in the project root: +- `dxfrw-ubuntu.tar.gz` +- `dxfrw-almalinux.tar.gz` +- `dxfrw-amazonlinux.tar.gz` +- `dxfrw-alpine.tar.gz` + +## OS Selection Guide + +| Choose | When you need | +|--------|---------------| +| **AlmaLinux** | RHEL/CentOS/Fedora compatible binaries | +| **Ubuntu** | Debian/Ubuntu compatible binaries | +| **Amazon Linux** | AWS EC2 or AWS environment deployment | +| **Alpine** | Minimal footprint, container-optimized builds | + +## Manual Build + +If you need to customize the build: + +```bash +# Build image +docker build -t codelibs/libdxfrw:ubuntu -f Dockerfile.ubuntu .. + +# Run build +docker run -t --rm -v $(pwd)/..:/work codelibs/libdxfrw:ubuntu /work/build.sh +``` + +Note: Manual builds should be run from the project root, not from this directory. From 7abef5837672b7d3c529773f68c1f6fee8894ccd Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 05:11:57 +0000 Subject: [PATCH 4/4] Improve script robustness and fix file permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: 1. Fix build.sh file permissions (644 → 666) - Issue: Docker container may run as different UID than host user - With 644, host user may not be able to read/modify output file - Solution: Use 666 (rw-rw-rw-) to ensure host accessibility - Still more restrictive than original 777 permissions 2. Add robust error handling to build scripts - build.sh: Add set -euo pipefail - docker/build-docker.sh: Add set -euo pipefail - Benefits: * -e: Exit immediately on any command error * -u: Exit on undefined variable usage * -o pipefail: Catch errors in pipes (e.g., cmd1 | cmd2) - Provides better error detection in critical build operations These changes address code review feedback and improve script reliability for multi-OS Docker builds. --- build.sh | 11 ++++++++--- docker/build-docker.sh | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/build.sh b/build.sh index b9be8f7..099245b 100755 --- a/build.sh +++ b/build.sh @@ -5,7 +5,11 @@ # and creates a distributable tar.gz archive # -set -e # Exit on error +# Robust error handling +# -e: Exit on error +# -u: Exit on undefined variable +# -o pipefail: Fail on pipe errors +set -euo pipefail echo "==========================================" echo "libdxfrw Build Script" @@ -55,8 +59,9 @@ echo "[6/6] Creating distributable archive..." cd /opt tar czf "${OUTPUT_DIR}/${OUTPUT_FILE}" dxfrw -# Set permissions -chmod 644 "${OUTPUT_DIR}/${OUTPUT_FILE}" +# Set permissions to allow host user access when running in Docker +# 666 (rw-rw-rw-) ensures the file can be accessed even if Docker runs as different UID +chmod 666 "${OUTPUT_DIR}/${OUTPUT_FILE}" # Calculate elapsed time END_TIME=$(date +%s) diff --git a/docker/build-docker.sh b/docker/build-docker.sh index f255df0..660d13c 100755 --- a/docker/build-docker.sh +++ b/docker/build-docker.sh @@ -26,7 +26,11 @@ # ./docker/build-docker.sh run all-os # -set -e +# Robust error handling +# -e: Exit on error +# -u: Exit on undefined variable +# -o pipefail: Fail on pipe errors +set -euo pipefail # Configuration IMAGE_NAME="codelibs/libdxfrw"