diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 8f01474..f719705 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -207,7 +207,22 @@ jobs: - name: Build package if: matrix.python-version == '3.11' run: | + # Remove old build artifacts if any exist + rm -rf dist build *.egg-info + + # Explicitly set the version for the build tool + if [ -n "$PACKAGE_VERSION" ]; then + echo "Building package with version: $PACKAGE_VERSION" + else + echo "WARNING: PACKAGE_VERSION not set! Using git-based version." + fi + + # Build wheel and sdist with isolated environment python -m build + + # Verify the wheel metadata + pip install twine + twine check dist/* - name: Publish package if: matrix.python-version == '3.11' @@ -282,4 +297,4 @@ jobs: PYTHON_VERSION=${{ matrix.python-version }} VERSION=${{ steps.get_version.outputs.VERSION }} cache-from: type=gha - cache-to: type=gha,mode=max + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 30834d5..7a20e6e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,30 +1,31 @@ ARG PYTHON_VERSION=3.11 FROM python:${PYTHON_VERSION}-slim -# Accept version as build arg ARG VERSION="0.1.0" -# Set as environment variable for setup.py to use -ENV PACKAGE_VERSION=${VERSION} +# ENV PACKAGE_VERSION=${VERSION} # Correctly removed + +# Keep PYTHONPATH env var if needed, might be optional after install ENV PYTHONPATH=/app WORKDIR /app -# Install git for versioning -RUN apt-get update && apt-get install -y git && apt-get clean && rm -rf /var/lib/apt/lists/* +# Install git - NEEDED for setuptools_scm to read .git directory +RUN apt-get update && apt-get install -y --no-install-recommends git && \ + apt-get clean && rm -rf /var/lib/apt/lists/* # Copy requirements and install dependencies first COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Copy source code +# Copy the rest of the application code INCLUDING .git COPY . . -# Create a simple wrapper script -RUN echo '#!/bin/bash\npython -m python_gpt_po.main "$@"' > /usr/local/bin/gpt-po-translator && \ - chmod +x /usr/local/bin/gpt-po-translator +# Install the package itself. This triggers setuptools_scm inside the container. +RUN pip install . --no-cache-dir -# Create a wrapper script to allow more flexibility +# Keep your custom entrypoint script COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh +# Use your custom entrypoint ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/man/gpt-po-translator.1 b/man/gpt-po-translator.1 deleted file mode 100644 index fd914c0..0000000 --- a/man/gpt-po-translator.1 +++ /dev/null @@ -1,71 +0,0 @@ -.TH GPT-PO-TRANSLATOR 1 "March 2025" "Version 1.0" "User Commands" - -.SH NAME -gpt-po-translator \- CLI tool for translating .po files using AI models - -.SH SYNOPSIS -.B gpt-po-translator -[\fB--folder\fR \fIpath\fR] [\fB--lang\fR \fIcodes\fR] [\fIoptions\fR] - -.SH DESCRIPTION -gpt-po-translator is a command-line tool designed to translate gettext (.po) files -using AI-powered translation models from OpenAI, Anthropic, and DeepSeek. - -.SH OPTIONS -.TP -\fB--folder\fR \fIpath\fR -Path to the directory containing .po files (required). -.TP -\fB--lang\fR \fIcodes\fR -Comma-separated target language codes (e.g., de, fr) (required). -.TP -\fB--detail-lang\fR \fInames\fR -Full language names corresponding to language codes (e.g., "German,French"). -.TP -\fB--fuzzy\fR -Remove fuzzy entries before processing. -.TP -\fB--bulk\fR -Enable bulk translation mode. -.TP -\fB--bulksize\fR \fIsize\fR -Specify the number of entries per batch in bulk mode (default: 50). -.TP -\fB--api_key\fR \fIkey\fR -API key for translation (can also be provided via an environment variable). -.TP -\fB--provider\fR \fIname\fR -Choose an AI provider: openai, anthropic, deepseek. -.TP -\fB--model\fR \fIname\fR -Specify the translation model (default varies by provider). -.TP -\fB--list-models\fR -List available models for the selected provider and exit. -.TP -\fB--folder-language\fR -Infer the language from the folder structure. -.TP -\fB--version\fR -Show program version and exit. -.TP -\fB-h, --help\fR -Show this help message and exit. - -.SH EXAMPLES -Translate .po files from the "locales" directory into German and French using bulk mode: - -.B gpt-po-translator --folder ./locales --lang de,fr --bulk --bulksize 40 --folder-language - -List available models for OpenAI: - -.B gpt-po-translator --provider openai --list-models - -.SH AUTHOR -Bram Mittendorff - -.SH LICENSE -MIT License - -.SH SEE ALSO -gettext(1) diff --git a/setup.py b/setup.py index 2a63804..e3d69e0 100644 --- a/setup.py +++ b/setup.py @@ -1,123 +1,15 @@ """ -Setup script for the gpt-po-translator package. -This script is used to install the package, dependencies, and the man page. +Setup script shim for the gpt-po-translator package. +Metadata is defined in pyproject.toml. +This script enables setuptools_scm and handles custom data_files installation. """ -import os -import subprocess -from typing import Optional - -from setuptools import find_packages, setup - -with open('README.md', encoding='utf-8') as f: - long_description = f.read() - -with open('requirements.txt', encoding='utf-8') as f: - install_requires = [line.strip() for line in f if line.strip() and not line.startswith('#')] - - -def get_pep440_version() -> Optional[str]: - """ - Get version from environment or git, ensuring it's PEP 440 compliant. - - Returns: - Optional[str]: PEP 440 compliant version string or None to defer to setuptools_scm - """ - - # First check environment variable (highest priority for containers) - if 'PACKAGE_VERSION' in os.environ: - raw_version = os.environ.get('PACKAGE_VERSION') - # Make version PEP 440 compliant - if '-' in raw_version and '+' not in raw_version: - # Convert something like "1.2.3-test" to "1.2.3+test" for PEP 440 - version = raw_version.replace('-', '+', 1) - else: - version = raw_version - print(f"Using version from environment: {version}") - return version - - # Then try getting from git - try: - # Get version from git describe, but normalize it to be PEP 440 compliant - version = subprocess.check_output( - ['git', 'describe', '--tags', '--always'], - stderr=subprocess.STDOUT, - text=True - ).strip() - - # Handle version format from git describe - if '-' in version: - # Format like v0.3.5-5-gd9775d7, convert to 0.3.5.dev5+gd9775d7 - tag, commits, commit_hash = version.lstrip('v').split('-') - version = f"{tag}.dev{commits}+{commit_hash}" - elif version.startswith('v'): - # Just a tagged version like v0.3.5 - version = version[1:] - - print(f"Using git version: {version}") - return version - except (subprocess.SubprocessError, FileNotFoundError): - # Defer to setuptools_scm - print("Deferring to setuptools_scm for version") - return None - - -# Get version using our custom function -package_version = get_pep440_version() - - -def install_man_pages(): - """ - Locate the man page and include it in the installation if it exists. - - Returns: - list: A list containing the path to the man page for installation. - """ - man_page = "man/gpt-po-translator.1" - if os.path.exists(man_page): - return [("share/man/man1", [man_page])] - return [] - +from setuptools import setup +# Most metadata is defined in pyproject.toml. +# This file primarily enables setuptools_scm and handles non-declarative steps. setup( - name='gpt-po-translator', - version=package_version, # Will be None if PACKAGE_VERSION is not set, triggering setuptools_scm - author='Bram Mittendorff', - author_email='bram@pescheck.io', - description='A CLI tool for translating .po files using GPT models.', - long_description=long_description, - long_description_content_type='text/markdown', - url='https://github.com/pescheckit/python-gpt-po', - license='MIT', - packages=find_packages(exclude=["*.tests", "*.tests.*", "*.__pycache__", "*.__pycache__.*"]), - include_package_data=True, - install_requires=install_requires, - entry_points={ - 'console_scripts': [ - 'gpt-po-translator=python_gpt_po.main:main', - ], - }, - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'Topic :: Software Development :: Internationalization', - 'Topic :: Software Development :: Localization', - 'Topic :: Text Processing :: Linguistic', - 'Operating System :: OS Independent', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3 :: Only', - 'Natural Language :: English', - 'Natural Language :: Dutch', - 'Environment :: Console', - 'Typing :: Typed' - ], - python_requires='>=3.8', - data_files=install_man_pages(), + setup_requires=['setuptools_scm'], + use_scm_version=True, + # include_package_data=True, # Keep this if needed and not configured elsewhere )