From c974687e66c5277e1a0d314e252a6b14e468697b Mon Sep 17 00:00:00 2001 From: Paul Sanders Date: Fri, 19 Jun 2026 10:06:03 -0400 Subject: [PATCH 1/4] Drop support for Poetry --- README.md | 1 - src/dev_dependency_installer.rs | 59 --- src/fastapi/docker_files.rs | 96 +--- src/fastapi/fastapi_installer.rs | 35 -- src/github_actions.rs | 417 +----------------- src/licenses.rs | 2 +- src/main.rs | 5 +- src/package_version.rs | 2 - src/project_generator.rs | 243 +--------- src/project_info.rs | 11 +- src/python_files.rs | 140 +----- ..._actions__tests__save_dependabot_file.snap | 2 +- ...ns__tests__save_dependabot_file_daily.snap | 2 +- ...__tests__save_dependabot_file_monthly.snap | 2 +- ...s__save_dependabot_file_weekly_no_day.snap | 2 +- ...__save_dependabot_file_weekly_tuesday.snap | 2 +- ...__create_pyproject_toml_async_project.snap | 2 +- src/utils.rs | 1 - 18 files changed, 27 insertions(+), 997 deletions(-) diff --git a/README.md b/README.md index ed3e1933..a779a43a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ created. Additionally FastAPI projects can be generated. For package management choose between: -- [poetry](https://python-poetry.org/) - [setuptools](https://github.com/pypa/setuptools) - [uv](https://docs.astral.sh/uv/) diff --git a/src/dev_dependency_installer.rs b/src/dev_dependency_installer.rs index 835d26e8..70af2e01 100644 --- a/src/dev_dependency_installer.rs +++ b/src/dev_dependency_installer.rs @@ -1,7 +1,6 @@ use anyhow::{bail, Result}; use crate::{ - package_version::PythonPackage, project_generator::{determine_dev_packages, format_package_with_extras}, project_info::{ProjectInfo, ProjectManager, Pyo3PythonManager}, }; @@ -9,7 +8,6 @@ use crate::{ pub fn install_dev_dependencies(project_info: &ProjectInfo) -> Result<()> { match project_info.project_manager { ProjectManager::Uv => uv_dev_dependency_installer(project_info)?, - ProjectManager::Poetry => poetry_dev_dependency_installer(project_info)?, ProjectManager::Setuptools => setuptools_dev_dependency_installer(project_info)?, ProjectManager::Maturin => maturin_dev_dependency_installer(project_info)?, }; @@ -38,33 +36,6 @@ fn uv_dev_dependency_installer(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn poetry_dev_dependency_installer(project_info: &ProjectInfo) -> Result<()> { - let packages = determine_dev_packages(project_info)?; - - for package in packages { - let package_spec = format_package_with_extras(&package); - let mut args = vec!["add", "--group=dev"]; - - if package == PythonPackage::Tomli { - args.extend(&[&package_spec, "--python", "<3.11"]); - } else { - args.push(&package_spec); - } - - let output = std::process::Command::new("poetry") - .args(args) - .current_dir(project_info.base_dir()) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - bail!("Failed to install {}: {stderr}", package); - } - } - - Ok(()) -} - fn setuptools_dev_dependency_installer(project_info: &ProjectInfo) -> Result<()> { let base_dir = project_info.base_dir().canonicalize()?; let venv_path = base_dir.join(".venv"); @@ -133,7 +104,6 @@ fn maturin_dev_dependency_installer(project_info: &ProjectInfo) -> Result<()> { pub fn update_prek_hooks(project_info: &ProjectInfo) -> Result<()> { match project_info.project_manager { ProjectManager::Uv => uv_prek_autoupdate(project_info)?, - ProjectManager::Poetry => poetry_prek_autoupdate(project_info)?, ProjectManager::Setuptools => setuptools_prek_autoupdate(project_info)?, ProjectManager::Maturin => maturin_prek_autoupdate(project_info)?, }; @@ -155,20 +125,6 @@ fn uv_prek_autoupdate(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn poetry_prek_autoupdate(project_info: &ProjectInfo) -> Result<()> { - let output = std::process::Command::new("poetry") - .args(["run", "prek", "autoupdate"]) - .current_dir(project_info.base_dir()) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - bail!("Failed to update prek hooks: {stderr}"); - } - - Ok(()) -} - fn setuptools_prek_autoupdate(project_info: &ProjectInfo) -> Result<()> { let base_dir = project_info.base_dir().canonicalize()?; let venv_path = base_dir.join(".venv"); @@ -210,7 +166,6 @@ fn maturin_prek_autoupdate(project_info: &ProjectInfo) -> Result<()> { pub fn install_prek_hooks(project_info: &ProjectInfo) -> Result<()> { match project_info.project_manager { ProjectManager::Uv => uv_prek_install(project_info)?, - ProjectManager::Poetry => poetry_prek_install(project_info)?, ProjectManager::Setuptools => setuptools_prek_install(project_info)?, ProjectManager::Maturin => maturin_prek_install(project_info)?, }; @@ -232,20 +187,6 @@ fn uv_prek_install(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn poetry_prek_install(project_info: &ProjectInfo) -> Result<()> { - let output = std::process::Command::new("poetry") - .args(["run", "prek", "install"]) - .current_dir(project_info.base_dir()) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - bail!("Failed to install prek hooks: {stderr}"); - } - - Ok(()) -} - fn setuptools_prek_install(project_info: &ProjectInfo) -> Result<()> { let base_dir = project_info.base_dir().canonicalize()?; let venv_path = base_dir.join(".venv"); diff --git a/src/fastapi/docker_files.rs b/src/fastapi/docker_files.rs index e2e0a577..d7e80dd4 100644 --- a/src/fastapi/docker_files.rs +++ b/src/fastapi/docker_files.rs @@ -455,84 +455,6 @@ USER appuser ENTRYPOINT ["./entrypoint.sh"] "#, - )), - ProjectManager::Poetry => Ok(format!( - r#"# syntax=docker/dockerfile:1 - -FROM ubuntu:26.04 AS builder - -WORKDIR /app - -ENV \ - PYTHONUNBUFFERED=true \ - POETRY_NO_INTERACTION=true \ - POETRY_VIRTUALENVS_IN_PROJECT=true \ - POETRY_CACHE_DIR=/tmp/poetry_cache - -RUN : \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - curl \ - ca-certificates \ - software-properties-common \ - && add-apt-repository ppa:deadsnakes/ppa \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - python{python_version} \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Install Poetry -RUN curl -sSL https://install.python-poetry.org | python{python_version} - - -ENV PATH="/root/.local/bin:$PATH" - -COPY pyproject.toml poetry.lock ./ - -COPY . ./ - -RUN --mount=type=cache,target=$POETRY_CACHE_DIR \ - poetry config virtualenvs.in-project true \ - && poetry install --only=main - - -# Build production stage -FROM ubuntu:26.04 AS prod - -RUN useradd appuser - -WORKDIR /app - -RUN chown appuser:appuser /app - -ENV \ - PYTHONUNBUFFERED=true \ - PATH="/app/.venv/bin:$PATH" \ - PORT="8000" - -RUN : \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - software-properties-common \ - && add-apt-repository ppa:deadsnakes/ppa \ - && apt-get update \ - && apt-get install -y --no-install-recommends python{python_version} \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -COPY --from=builder /app/.venv /app/.venv -COPY --from=builder /app/{source_dir} /app/{source_dir} -COPY ./scripts/entrypoint.sh /app - -RUN chmod +x /app/entrypoint.sh - -EXPOSE 8000 - -USER appuser - -ENTRYPOINT ["./entrypoint.sh"] -"# )), ProjectManager::Setuptools => Ok(format!( r#"# syntax=docker/dockerfile:1 @@ -897,7 +819,7 @@ mod tests { version: "0.1.0".to_string(), python_version: "3.11".to_string(), min_python_version: "3.10".to_string(), - project_manager: ProjectManager::Poetry, + project_manager: ProjectManager::Uv, pyo3_python_manager: Some(Pyo3PythonManager::Uv), is_application: true, is_async_project: false, @@ -939,22 +861,6 @@ mod tests { assert_yaml_snapshot!(content); } - #[test] - fn test_save_dockerfile_poetry() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - let base = project_info.base_dir(); - create_dir_all(&base).unwrap(); - let expected_file = base.join("Dockerfile"); - save_dockerfile(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - #[test] fn test_save_dockerfile_setuptools() { let mut project_info = project_info_dummy(); diff --git a/src/fastapi/fastapi_installer.rs b/src/fastapi/fastapi_installer.rs index f90ac60b..5d2e3c90 100644 --- a/src/fastapi/fastapi_installer.rs +++ b/src/fastapi/fastapi_installer.rs @@ -24,7 +24,6 @@ const FASTAPI_BASE_DEV_DEPENDENCIES: &[&str] = &["httpx2", "pytest-xdist"]; pub fn install_fastapi_dependencies(project_info: &ProjectInfo) -> Result<()> { match project_info.project_manager { ProjectManager::Uv => uv_fastapi_dependency_installer(project_info)?, - ProjectManager::Poetry => poetry_fastapi_dependency_installer(project_info)?, ProjectManager::Setuptools => setuptools_fastapi_dependency_installer(project_info)?, ProjectManager::Maturin => maturin_fastapi_dependency_installer(project_info)?, }; @@ -66,40 +65,6 @@ fn uv_fastapi_dependency_installer(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn poetry_fastapi_dependency_installer(project_info: &ProjectInfo) -> Result<()> { - let dependencies = FASTAPI_BASE_DEPENDENCIES.to_vec(); - /* if project_info.database_manager == Some(DatabaseManager::SqlAlchemy) { - dependencies.push("sqlalchemy"); - dependencies.push("alembic"); - } */ - let mut args = vec!["add"]; - args.extend(dependencies); - let output = std::process::Command::new("poetry") - .args(args) - .current_dir(project_info.base_dir()) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - bail!("Failed to install FastAPI dependencies: {stderr}"); - } - - let dev_dependencies = FASTAPI_BASE_DEV_DEPENDENCIES.to_vec(); - let mut dev_args = vec!["add", "--group=dev"]; - dev_args.extend(dev_dependencies); - let output = std::process::Command::new("poetry") - .args(dev_args) - .current_dir(project_info.base_dir()) - .output()?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - bail!("Failed to install FastAPI dependencies: {stderr}"); - } - - Ok(()) -} - fn setuptools_fastapi_dependency_installer(project_info: &ProjectInfo) -> Result<()> { let venv_path = project_info.base_dir().join(".venv"); if !venv_path.exists() { diff --git a/src/github_actions.rs b/src/github_actions.rs index a0f338bc..a639ee42 100644 --- a/src/github_actions.rs +++ b/src/github_actions.rs @@ -13,169 +13,6 @@ fn build_actions_python_test_versions(github_action_python_test_versions: &[Stri .join(", ") } -fn create_poetry_ci_testing_linux_only_file( - source_dir: &str, - min_python_version: &str, - github_action_python_test_versions: &[String], -) -> String { - let python_versions = build_actions_python_test_versions(github_action_python_test_versions); - - format!( - r#"name: Testing - -on: - push: - branches: - - main - pull_request: -env: - PYTHON_VERSION: "{min_python_version}" -jobs: - linting: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: ${{{{ env.PYTHON_VERSION }}}} - cache: "poetry" - - name: Install Dependencies - run: poetry install - - name: Ruff format check - run: poetry run ruff format {source_dir} tests --check - - name: Lint with ruff - run: poetry run ruff check . - - name: mypy check - run: poetry run mypy . - testing: - strategy: - fail-fast: false - matrix: - python-version: [{python_versions}] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python ${{{{ matrix.python-version }}}} - uses: actions/setup-python@v6 - with: - python-version: ${{{{ matrix.python-version }}}} - cache: "poetry" - - name: Install Dependencies - run: poetry install - - name: Test with pytest - run: poetry run pytest -"# - ) -} - -#[cfg(feature = "fastapi")] -fn create_poetry_ci_testing_fastapi_file( - source_dir: &str, - min_python_version: &str, - github_action_python_test_versions: &[String], -) -> String { - let python_versions = build_actions_python_test_versions(github_action_python_test_versions); - - format!( - r#"name: Testing - -on: - push: - branches: - - main - pull_request: -env: - PYTHON_VERSION: "{min_python_version}" - SECRET_KEY: "someKey" - PRODUCTION_MODE: false - FIRST_SUPERUSER_EMAIL: "some@email.com" - FIRST_SUPERUSER_PASSWORD: "somePassword1!" - FIRST_SUPERUSER_NAME: "Super User" - POSTGRES_HOST: "127.0.0.1" - POSTGRES_USER: "postgres" - POSTGRES_PASSWORD: "test_password" - POSTGRES_DB: "test_db" - VALKEY_HOST: "127.0.0.1" - VALKEY_PASSWORD: "test_password" - MEILISEARCH_HOST: http://127.0.0.1 - STACK_NAME: "test-stack" - DOMAIN: "127.0.0.1" - LOG_LEVEL: "DEBUG" - CI: true -jobs: - linting: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - - name: Cache dependencies - uses: Swatinem/rust-cache@v2 - - name: Install sqlx-cli - run: cargo install sqlx-cli --no-default-features -F native-tls -F postgres - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: ${{{{ env.PYTHON_VERSION }}}} - cache: "poetry" - - name: Install Dependencies - run: poetry install - - name: Ruff format check - run: poetry run ruff format {source_dir} tests --check - - name: Lint with ruff - run: poetry run ruff check . - - name: mypy check - run: poetry run mypy . - testing: - strategy: - fail-fast: false - matrix: - python-version: [{python_versions}] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python ${{{{ matrix.python-version }}}} - uses: actions/setup-python@v6 - with: - python-version: ${{{{ matrix.python-version }}}} - cache: "poetry" - - name: Install Dependencies - run: poetry install - - name: make .env - run: touch .env - - name: Start docker containers - run: docker compose up db valkey migrations -d - - name: Test with pytest - run: poetry run pytest -n auto -"# - ) -} - fn create_setuptools_ci_testing_linux_only_file( source_dir: &str, min_python_version: &str, @@ -924,29 +761,6 @@ pub fn save_ci_testing_linux_only_file(project_info: &ProjectInfo) -> Result<()> bail!("A PyO3 Python manager is required for maturin"); } } - ProjectManager::Poetry => { - #[cfg(feature = "fastapi")] - if project_info.is_fastapi_project { - create_poetry_ci_testing_fastapi_file( - &project_info.source_dir, - &project_info.min_python_version, - &project_info.github_actions_python_test_versions, - ) - } else { - create_poetry_ci_testing_linux_only_file( - &project_info.source_dir, - &project_info.min_python_version, - &project_info.github_actions_python_test_versions, - ) - } - - #[cfg(not(feature = "fastapi"))] - create_poetry_ci_testing_linux_only_file( - &project_info.source_dir, - &project_info.min_python_version, - &project_info.github_actions_python_test_versions, - ) - } ProjectManager::Setuptools => { #[cfg(feature = "fastapi")] if project_info.is_fastapi_project { @@ -1000,75 +814,6 @@ pub fn save_ci_testing_linux_only_file(project_info: &ProjectInfo) -> Result<()> Ok(()) } -fn create_poetry_ci_testing_multi_os_file( - source_dir: &str, - min_python_version: &str, - github_action_python_test_versions: &[String], -) -> String { - let python_versions = build_actions_python_test_versions(github_action_python_test_versions); - - format!( - r#"name: Testing - -on: - push: - branches: - - main - pull_request: -env: - PYTHON_VERSION: "{min_python_version}" -jobs: - linting: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: ${{{{ env.PYTHON_VERSION }}}} - cache: "poetry" - - name: Install Dependencies - run: poetry install - - name: Ruff format check - run: poetry run ruff format {source_dir} tests --check - - name: Lint with ruff - run: poetry run ruff check . - - name: mypy check - run: poetry run mypy . - testing: - strategy: - fail-fast: false - matrix: - python-version: [{python_versions}] - os: [ubuntu-latest, windows-latest, macos-latest] - runs-on: ${{{{ matrix.os }}}} - steps: - - uses: actions/checkout@v6 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python ${{{{ matrix.python-version }}}} - uses: actions/setup-python@v6 - with: - python-version: ${{{{ matrix.python-version }}}} - cache: "poetry" - - name: Install Dependencies - run: poetry install - - name: Test with pytest - run: poetry run pytest -"# - ) -} - fn create_setuptools_ci_testing_multi_os_file( source_dir: &str, min_python_version: &str, @@ -1394,11 +1139,6 @@ pub fn save_ci_testing_multi_os_file(project_info: &ProjectInfo) -> Result<()> { bail!("A PyO3 Python Manager is required for maturin"); } } - ProjectManager::Poetry => create_poetry_ci_testing_multi_os_file( - &project_info.source_dir, - &project_info.min_python_version, - &project_info.github_actions_python_test_versions, - ), ProjectManager::Setuptools => create_setuptools_ci_testing_multi_os_file( &project_info.source_dir, &project_info.min_python_version, @@ -1569,34 +1309,6 @@ pub fn save_dependabot_file(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn create_poetry_pypi_publish_file(python_version: &str) -> String { - format!( - r#"name: PyPi Publish -on: - release: - types: - - published -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install Poetry - run: pipx install poetry - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: "{python_version}" - cache: "poetry" - - name: Install Dependencies - run: | - poetry install - - name: Publish package - run: poetry publish --build -"# - ) -} - fn create_pyo3_pypi_publish_file(python_version: &str) -> String { format!( r#"name: PyPi Publish @@ -1941,7 +1653,6 @@ pub fn save_pypi_publish_file(project_info: &ProjectInfo) -> Result<()> { .join(".github/workflows/pypi_publish.yml"); let content = match &project_info.project_manager { ProjectManager::Maturin => create_pyo3_pypi_publish_file(&project_info.python_version), - ProjectManager::Poetry => create_poetry_pypi_publish_file(&project_info.python_version), ProjectManager::Setuptools => { create_setuptools_pypi_publish_file(&project_info.python_version) } @@ -1953,34 +1664,6 @@ pub fn save_pypi_publish_file(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn create_poetry_docs_publish_file(python_version: &str) -> String { - format!( - r#"name: Docs Publish -on: - release: - types: - - published -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - name: Install Poetry - run: pipx install poetry - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: "{python_version}" - cache: "poetry" - - name: Install Dependencies - run: | - poetry install - - name: Publish package - run: poetry run mkdocs gh-deploy --force -"# - ) -} - fn create_setuptools_docs_publish_file(python_version: &str) -> String { format!( r#"name: Docs Publish @@ -2055,7 +1738,6 @@ pub fn save_docs_publish_file(project_info: &ProjectInfo) -> Result<()> { bail!("No PyO3 Python project manager specified"); } } - ProjectManager::Poetry => create_poetry_docs_publish_file(&project_info.python_version), ProjectManager::Setuptools => { create_setuptools_docs_publish_file(&project_info.python_version) } @@ -2218,42 +1900,6 @@ mod tests { ); } - #[test] - fn test_save_poetry_ci_testing_linux_only_file() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - project_info.use_multi_os_ci = true; - let base = project_info.base_dir(); - create_dir_all(base.join(".github/workflows")).unwrap(); - let expected_file = base.join(".github/workflows/testing.yml"); - save_ci_testing_linux_only_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - - #[cfg(feature = "fastapi")] - #[test] - fn test_save_poetry_ci_testing_fastapi_file() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - project_info.is_fastapi_project = true; - project_info.database_manager = Some(DatabaseManager::AsyncPg); - let base = project_info.base_dir(); - create_dir_all(base.join(".github/workflows")).unwrap(); - let expected_file = base.join(".github/workflows/testing.yml"); - save_ci_testing_linux_only_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - #[test] fn test_save_ci_testing_linux_only_file_pyo3() { let mut project_info = project_info_dummy(); @@ -2361,23 +2007,6 @@ mod tests { assert_yaml_snapshot!(content); } - #[test] - fn test_save_poetry_ci_testing_multi_os_file() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - project_info.use_multi_os_ci = true; - let base = project_info.base_dir(); - create_dir_all(base.join(".github/workflows")).unwrap(); - let expected_file = base.join(".github/workflows/testing.yml"); - save_ci_testing_multi_os_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - #[test] fn test_save_setuptools_ci_testing_multi_os_file() { let mut project_info = project_info_dummy(); @@ -2432,7 +2061,7 @@ mod tests { #[test] fn test_save_dependabot_file() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.use_dependabot = true; project_info.dependabot_schedule = None; project_info.dependabot_day = None; @@ -2452,7 +2081,7 @@ mod tests { #[test] fn test_save_dependabot_file_daily() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.use_dependabot = true; project_info.dependabot_schedule = Some(DependabotSchedule::Daily); project_info.dependabot_day = None; @@ -2472,7 +2101,7 @@ mod tests { #[test] fn test_save_dependabot_file_weekly_no_day() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.use_dependabot = true; project_info.dependabot_schedule = Some(DependabotSchedule::Weekly); project_info.dependabot_day = None; @@ -2492,7 +2121,7 @@ mod tests { #[test] fn test_save_dependabot_file_weekly_tuesday() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.use_dependabot = true; project_info.dependabot_schedule = Some(DependabotSchedule::Weekly); project_info.dependabot_day = Some(Day::Tuesday); @@ -2512,7 +2141,7 @@ mod tests { #[test] fn test_save_dependabot_file_monthly() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.use_dependabot = true; project_info.dependabot_schedule = Some(DependabotSchedule::Monthly); project_info.dependabot_day = None; @@ -2624,40 +2253,6 @@ mod tests { assert_yaml_snapshot!(content); } - #[test] - fn test_save_pypi_publish_file_poetry() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - let base = project_info.base_dir(); - create_dir_all(base.join(".github/workflows")).unwrap(); - let expected_file = base.join(".github/workflows/pypi_publish.yml"); - save_pypi_publish_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - - #[test] - fn test_save_docs_publish_file_poetry() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - project_info.include_docs = true; - project_info.docs_info = Some(docs_info_dummy()); - let base = project_info.base_dir(); - create_dir_all(base.join(".github/workflows")).unwrap(); - let expected_file = base.join(".github/workflows/docs_publish.yml"); - save_docs_publish_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - #[test] fn test_save_pypi_publish_file_pyo3() { let mut project_info = project_info_dummy(); @@ -2785,7 +2380,7 @@ mod tests { #[test] fn test_save_release_drafter_file() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; let base = project_info.base_dir(); create_dir_all(base.join(".github/workflows")).unwrap(); let expected_release_drafter_file = base.join(".github/workflows/release_drafter.yml"); diff --git a/src/licenses.rs b/src/licenses.rs index a4add554..5be85739 100644 --- a/src/licenses.rs +++ b/src/licenses.rs @@ -274,7 +274,7 @@ mod tests { version: "0.1.0".to_string(), python_version: "3.11".to_string(), min_python_version: "3.10".to_string(), - project_manager: ProjectManager::Poetry, + project_manager: ProjectManager::Uv, pyo3_python_manager: None, is_application: true, is_async_project: false, diff --git a/src/main.rs b/src/main.rs index 796a0530..d7816c1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,10 +9,11 @@ mod project_generator; mod project_info; mod python_files; mod rust_files; -mod utils; #[cfg(feature = "fastapi")] mod fastapi; +#[cfg(feature = "fastapi")] +mod utils; use std::{fs::remove_dir_all, process::exit, time::Duration}; @@ -482,7 +483,7 @@ mod tests { version: "0.1.0".to_string(), python_version: "3.12".to_string(), min_python_version: "3.10".to_string(), - project_manager: ProjectManager::Poetry, + project_manager: ProjectManager::Uv, pyo3_python_manager: None, is_application: true, is_async_project: false, diff --git a/src/package_version.rs b/src/package_version.rs index e6c43290..bd2aa936 100644 --- a/src/package_version.rs +++ b/src/package_version.rs @@ -12,7 +12,6 @@ pub enum PythonPackage { PytestAsyncio, PytestCov, Ruff, - Tomli, } impl fmt::Display for PythonPackage { @@ -28,7 +27,6 @@ impl fmt::Display for PythonPackage { PythonPackage::PytestAsyncio => write!(f, "pytest-asyncio"), PythonPackage::PytestCov => write!(f, "pytest-cov"), PythonPackage::Ruff => write!(f, "ruff"), - PythonPackage::Tomli => write!(f, "tomli"), } } } diff --git a/src/project_generator.rs b/src/project_generator.rs index bf5094ad..6a4a572c 100644 --- a/src/project_generator.rs +++ b/src/project_generator.rs @@ -13,7 +13,6 @@ use crate::{ project_info::{LicenseType, ProjectInfo, ProjectManager, Pyo3PythonManager}, python_files::generate_python_files, rust_files::{save_cargo_toml_file, save_lib_file}, - utils::is_python_version_or_greater, }; #[cfg(feature = "fastapi")] @@ -229,12 +228,6 @@ pub fn determine_dev_packages(project_info: &ProjectInfo) -> Result Result { let project_description = &project_info.project_description; let creator = &project_info.creator; let creator_email = &project_info.creator_email; - let version = &project_info.version; let license = &project_info.license; let license_text = license_str(&project_info.license); let max_line_length = &project_info.max_line_length; @@ -388,39 +380,6 @@ features = ["pyo3/extension-module"] bail!("A PyO3 Python manager is required for maturin projects"); } } - ProjectManager::Poetry => { - let mut pyproject = format!( - r#"[tool.poetry] -name = "{project_name}" -version = "{version}" -description = "{project_description}" -authors = ["{creator} <{creator_email}>"] -"# - ); - - if license != &LicenseType::NoLicense { - pyproject.push_str(&format!( - "license = \"{license_text}\" -" - )); - } - - pyproject.push_str(&format!( - r#"readme = "README.md" - -[tool.poetry.dependencies] -python = "^{min_python_version}" - -[tool.poetry.group.dev.dependencies] - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" - -"# - )); - pyproject - } ProjectManager::Setuptools => { let mut pyproject = format!( r#"[build-system] @@ -733,85 +692,6 @@ fn save_docs_css(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn create_poetry_justfile(project_info: &ProjectInfo) -> String { - let module = project_info.module_name(); - - #[cfg_attr(not(feature = "fastapi"), allow(unused_mut))] - let mut justfile = format!( - r#"@_default: - just --list - -@lint: - echo mypy - just --justfile {{{{justfile()}}}} mypy - echo ruff-check - just --justfile {{{{justfile()}}}} ruff-check - echo ruff-format - just --justfile {{{{justfile()}}}} ruff-format - -@mypy: - poetry run mypy {module} tests - -@ruff-check: - poetry run ruff check {module} tests - -@ruff-format: - poetry run ruff format {module} tests - -@install: - poetry install - -@test *args="": - poetry run pytest {{{{args}}}} -"# - ); - - #[cfg(feature = "fastapi")] - if project_info.is_fastapi_project { - justfile.push_str( - r#" -granian_cmd := if os() != "windows" { - "poetry run granian app.main:app --host 127.0.0.1 --port 8000 --interface asgi --no-ws --runtime-mode st --loop uvloop --reload" -} else { - "poetry run granian app.main:app --host 127.0.0.1 --port 8000 --interface asgi --no-ws --runtime-mode st --reload" -} - -@backend-server: - {{granian_cmd}} - -@test-parallel *args="": - poetry run pytest -n auto {{args}} - -@docker-up: - docker compose up --build - -@docker-up-detached: - docker compose up --build -d - -@docker-up-services: - docker compose up db valkey migrations - -@docker-up-services-detached: - docker compose up db valkey migrations -d - -@docker-down: - docker compose down - -@docker-down-volumes: - docker compose down --volumes - -@docker-pull: - docker compose pull db valkey migrations - -@docker-build: - docker compose build -"#, - ) - } - - justfile -} - fn create_pyo3_justfile(project_info: &ProjectInfo) -> Result { let module = project_info.module_name(); let pyo3_python_manager = if let Some(manager) = &project_info.pyo3_python_manager { @@ -1185,7 +1065,6 @@ granian_cmd := if os() != "windows" { fn save_justfile(project_info: &ProjectInfo) -> Result<()> { let file_path = project_info.base_dir().join("justfile"); let content = match &project_info.project_manager { - ProjectManager::Poetry => create_poetry_justfile(project_info), ProjectManager::Maturin => create_pyo3_justfile(project_info)?, ProjectManager::Setuptools => create_setuptools_justfile(project_info), ProjectManager::Uv => create_uv_justfile(project_info), @@ -1348,7 +1227,7 @@ mod tests { version: "0.1.0".to_string(), python_version: "3.11".to_string(), min_python_version: "3.10".to_string(), - project_manager: ProjectManager::Poetry, + project_manager: ProjectManager::Uv, pyo3_python_manager: Some(Pyo3PythonManager::Uv), is_application: true, is_async_project: false, @@ -1392,7 +1271,7 @@ mod tests { #[test] fn test_save_gitigngore_file() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; let base = project_info.base_dir(); create_dir_all(&base).unwrap(); let expected_file = base.join(".gitignore"); @@ -1438,89 +1317,6 @@ mod tests { ]}, { assert_yaml_snapshot!(content)}); } - #[test] - fn test_save_poetry_pyproject_toml_file_mit_application() { - let mut project_info = project_info_dummy(); - project_info.license = LicenseType::Mit; - project_info.project_manager = ProjectManager::Poetry; - project_info.is_application = true; - let base = project_info.base_dir(); - create_dir_all(&base).unwrap(); - let expected_file = base.join("pyproject.toml"); - save_pyproject_toml_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - insta::with_settings!({filters => vec![ - (r#""\d+\.\d+\.\d+"#, "\"1.0.0"), - ]}, { assert_yaml_snapshot!(content)}); - } - - #[test] - fn test_save_poetry_pyproject_toml_file_apache_application() { - let mut project_info = project_info_dummy(); - project_info.license = LicenseType::Apache2; - project_info.project_manager = ProjectManager::Poetry; - project_info.is_application = true; - let base = project_info.base_dir(); - create_dir_all(&base).unwrap(); - let expected_file = base.join("pyproject.toml"); - save_pyproject_toml_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - insta::with_settings!({filters => vec![ - (r#""\d+\.\d+\.\d+"#, "\"1.0.0"), - (r#"">=\d+\.\d+\.\d+"#, "\">=1.0.0"), - ]}, { assert_yaml_snapshot!(content)}); - } - - #[test] - fn test_save_poetry_pyproject_toml_file_no_license_application() { - let mut project_info = project_info_dummy(); - project_info.license = LicenseType::NoLicense; - project_info.project_manager = ProjectManager::Poetry; - project_info.is_application = true; - let base = project_info.base_dir(); - create_dir_all(&base).unwrap(); - let expected_file = base.join("pyproject.toml"); - save_pyproject_toml_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - insta::with_settings!({filters => vec![ - (r#""\d+\.\d+\.\d+"#, "\"1.0.0"), - (r#"">=\d+\.\d+\.\d+"#, "\">=1.0.0"), - ]}, { assert_yaml_snapshot!(content)}); - } - - #[test] - fn test_create_poetry_pyproject_toml_mit_lib() { - let mut project_info = project_info_dummy(); - project_info.license = LicenseType::Mit; - project_info.project_manager = ProjectManager::Poetry; - project_info.is_application = false; - let base = project_info.base_dir(); - create_dir_all(&base).unwrap(); - let expected_file = base.join("pyproject.toml"); - save_pyproject_toml_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - insta::with_settings!({filters => vec![ - (r#""\d+\.\d+\.\d+"#, "\"1.0.0"), - (r#"">=\d+\.\d+\.\d+"#, "\">=1.0.0"), - ]}, { assert_yaml_snapshot!(content)}); - } - #[test] fn test_save_pyproject_toml_file_mit_pyo3() { let mut project_info = project_info_dummy(); @@ -1834,41 +1630,6 @@ mod tests { assert_yaml_snapshot!(content); } - #[test] - fn test_save_justfile_poetry() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - let base = project_info.base_dir(); - create_dir_all(&base).unwrap(); - let expected_file = base.join("justfile"); - save_justfile(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - - #[cfg(feature = "fastapi")] - #[test] - fn test_save_justfile_poetry_fastapi_project() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - project_info.is_fastapi_project = true; - project_info.database_manager = Some(DatabaseManager::AsyncPg); - let base = project_info.base_dir(); - create_dir_all(&base).unwrap(); - let expected_file = base.join("justfile"); - save_justfile(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - #[test] fn test_save_justfile_uv() { let mut project_info = project_info_dummy(); diff --git a/src/project_info.rs b/src/project_info.rs index 9efc9dc1..cd6ca7c1 100644 --- a/src/project_info.rs +++ b/src/project_info.rs @@ -95,7 +95,6 @@ impl fmt::Display for Pyo3PythonManager { #[derive(Clone, Debug, Default, Deserialize, Serialize, ValueEnum, PartialEq, Eq)] pub enum ProjectManager { Maturin, - Poetry, Setuptools, #[default] Uv, @@ -105,7 +104,6 @@ impl fmt::Display for ProjectManager { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Self::Maturin => write!(f, "Maturin"), - Self::Poetry => write!(f, "Poetry"), Self::Setuptools => write!(f, "Setuptools"), Self::Uv => write!(f, "uv"), } @@ -398,14 +396,13 @@ fn project_manager_prompt(default: Option) -> Result match d { ProjectManager::Uv => "1".to_string(), - ProjectManager::Poetry => "2".to_string(), ProjectManager::Maturin => "3".to_string(), ProjectManager::Setuptools => "4".to_string(), }, - None => "poetry".to_string(), + None => "uv".to_string(), }; let prompt_text = - "Project Manager\n 1 - uv\n 2 - Poetry\n 3 - Maturin\n 4 - setuptools\n Choose from [1, 2, 3, 4]" + "Project Manager\n 1 - uv\n 2 - Maturin\n 3 - setuptools\n Choose from [1, 2, 3]" .to_string(); let prompt = Prompt { prompt_text, @@ -416,10 +413,8 @@ fn project_manager_prompt(default: Option) -> Result String { @@ -216,74 +215,6 @@ fn save_version_file(project_info: &ProjectInfo) -> Result<()> { Ok(()) } -fn create_version_test_file( - module: &str, - project_manager: &ProjectManager, - min_python_version: &str, -) -> Result> { - let version_test: Option<&str> = match project_manager { - ProjectManager::Poetry => Some( - r#"def test_versions_match(): - pyproject = Path().absolute() / "pyproject.toml" - with open(pyproject, "rb") as f: - data = tomllib.load(f) - pyproject_version = data["tool"]["poetry"]["version"] - - assert VERSION == pyproject_version"#, - ), - _ => None, - }; - - if let Some(v) = version_test { - if is_python_version_or_greater(min_python_version, 11)? { - Ok(Some(format!( - r#"import tomllib -from pathlib import Path - -from {module}._version import VERSION - - -{v} -"# - ))) - } else { - Ok(Some(format!( - r#"import sys -from pathlib import Path - -from {module}._version import VERSION - -if sys.version_info < (3, 11): - import tomli as tomllib -else: - import tomllib - - -{v} -"# - ))) - } - } else { - Ok(None) - } -} - -fn save_version_test_file(project_info: &ProjectInfo) -> Result<()> { - let module = project_info.module_name(); - let file_path = project_info.base_dir().join("tests/test_version.py"); - let content = create_version_test_file( - &module, - &project_info.project_manager, - &project_info.min_python_version, - )?; - - if let Some(c) = content { - save_file_with_content(&file_path, &c)?; - } - - Ok(()) -} - pub fn generate_python_files(project_info: &ProjectInfo) -> Result<()> { if save_project_init_file(project_info).is_err() { bail!("Error creating __init__.py file"); @@ -321,10 +252,6 @@ pub fn generate_python_files(project_info: &ProjectInfo) -> Result<()> { bail!("Error creating version file"); } - if save_version_test_file(project_info).is_err() { - bail!("Error creating version test file") - } - if let ProjectManager::Maturin = project_info.project_manager { if save_pyi_file(project_info).is_err() { bail!("Error creating pyi file"); @@ -393,7 +320,7 @@ mod tests { #[test] fn test_save_project_init_file() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; let base = project_info.base_dir(); create_dir_all(base.join(&project_info.source_dir)).unwrap(); let expected_file = base.join(format!("{}/__init__.py", &project_info.source_dir)); @@ -443,7 +370,7 @@ mod tests { #[test] fn test_save_main_files() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.is_application = true; let base = project_info.base_dir(); create_dir_all(base.join(&project_info.source_dir)).unwrap(); @@ -467,7 +394,7 @@ mod tests { #[test] fn test_save_main_files_is_async_project() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.is_application = true; project_info.is_async_project = true; let base = project_info.base_dir(); @@ -492,7 +419,7 @@ mod tests { #[test] fn test_save_main_test_file() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.is_application = true; let base = project_info.base_dir(); create_dir_all(base.join("tests")).unwrap(); @@ -509,7 +436,7 @@ mod tests { #[test] fn test_save_main_test_file_is_async_project() { let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; + project_info.project_manager = ProjectManager::Uv; project_info.is_application = true; project_info.is_async_project = true; let base = project_info.base_dir(); @@ -576,61 +503,4 @@ mod tests { assert_yaml_snapshot!(content); } - - #[test] - fn test_save_version_test_file_poetry_tomli() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - let base = project_info.base_dir(); - create_dir_all(base.join("tests")).unwrap(); - let expected_file = base.join("tests/test_version.py"); - save_version_test_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - - #[test] - fn test_save_version_test_file_poetry_no_tomli() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Poetry; - project_info.min_python_version = "3.12".to_string(); - let base = project_info.base_dir(); - create_dir_all(base.join("tests")).unwrap(); - let expected_file = base.join("tests/test_version.py"); - save_version_test_file(&project_info).unwrap(); - - assert!(expected_file.is_file()); - - let content = std::fs::read_to_string(expected_file).unwrap(); - - assert_yaml_snapshot!(content); - } - - #[test] - fn test_save_version_test_file_setuptools() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Setuptools; - let base = project_info.base_dir(); - create_dir_all(base.join("tests")).unwrap(); - let expected_file = base.join("tests/test_version.py"); - save_version_test_file(&project_info).unwrap(); - - assert!(!expected_file.is_file()); - } - - #[test] - fn test_save_version_test_file_uv() { - let mut project_info = project_info_dummy(); - project_info.project_manager = ProjectManager::Uv; - let base = project_info.base_dir(); - create_dir_all(base.join("tests")).unwrap(); - let expected_file = base.join("tests/test_version.py"); - save_version_test_file(&project_info).unwrap(); - - assert!(!expected_file.is_file()); - } } diff --git a/src/snapshots/python_project__github_actions__tests__save_dependabot_file.snap b/src/snapshots/python_project__github_actions__tests__save_dependabot_file.snap index 79377fe5..624347b2 100644 --- a/src/snapshots/python_project__github_actions__tests__save_dependabot_file.snap +++ b/src/snapshots/python_project__github_actions__tests__save_dependabot_file.snap @@ -2,4 +2,4 @@ source: src/github_actions.rs expression: content --- -"version: 2\nupdates:\n - package-ecosystem: \"pip\"\n directory: \"/\"\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n" +"version: 2\nupdates:\n - package-ecosystem: \"uv\"\n directory: \"/\"\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n" diff --git a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_daily.snap b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_daily.snap index 79377fe5..624347b2 100644 --- a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_daily.snap +++ b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_daily.snap @@ -2,4 +2,4 @@ source: src/github_actions.rs expression: content --- -"version: 2\nupdates:\n - package-ecosystem: \"pip\"\n directory: \"/\"\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n" +"version: 2\nupdates:\n - package-ecosystem: \"uv\"\n directory: \"/\"\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: daily\n labels:\n - skip-changelog\n - dependencies\n" diff --git a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_monthly.snap b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_monthly.snap index 8dfbf51e..68343159 100644 --- a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_monthly.snap +++ b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_monthly.snap @@ -2,4 +2,4 @@ source: src/github_actions.rs expression: content --- -"version: 2\nupdates:\n - package-ecosystem: \"pip\"\n directory: \"/\"\n schedule:\n interval: monthly\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: monthly\n labels:\n - skip-changelog\n - dependencies\n" +"version: 2\nupdates:\n - package-ecosystem: \"uv\"\n directory: \"/\"\n schedule:\n interval: monthly\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: monthly\n labels:\n - skip-changelog\n - dependencies\n" diff --git a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_no_day.snap b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_no_day.snap index 5f5b9383..09ce8810 100644 --- a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_no_day.snap +++ b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_no_day.snap @@ -2,4 +2,4 @@ source: src/github_actions.rs expression: content --- -"version: 2\nupdates:\n - package-ecosystem: \"pip\"\n directory: \"/\"\n schedule:\n interval: weekly\n day: monday\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: weekly\n day: monday\n labels:\n - skip-changelog\n - dependencies\n" +"version: 2\nupdates:\n - package-ecosystem: \"uv\"\n directory: \"/\"\n schedule:\n interval: weekly\n day: monday\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: weekly\n day: monday\n labels:\n - skip-changelog\n - dependencies\n" diff --git a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_tuesday.snap b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_tuesday.snap index b7ace20a..df86bd59 100644 --- a/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_tuesday.snap +++ b/src/snapshots/python_project__github_actions__tests__save_dependabot_file_weekly_tuesday.snap @@ -2,4 +2,4 @@ source: src/github_actions.rs expression: content --- -"version: 2\nupdates:\n - package-ecosystem: \"pip\"\n directory: \"/\"\n schedule:\n interval: weekly\n day: tuesday\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: weekly\n day: tuesday\n labels:\n - skip-changelog\n - dependencies\n" +"version: 2\nupdates:\n - package-ecosystem: \"uv\"\n directory: \"/\"\n schedule:\n interval: weekly\n day: tuesday\n labels:\n - skip-changelog\n - dependencies\n - package-ecosystem: \"github-actions\"\n directory: '/'\n schedule:\n interval: weekly\n day: tuesday\n labels:\n - skip-changelog\n - dependencies\n" diff --git a/src/snapshots/python_project__project_generator__tests__create_pyproject_toml_async_project.snap b/src/snapshots/python_project__project_generator__tests__create_pyproject_toml_async_project.snap index a73344df..338525be 100644 --- a/src/snapshots/python_project__project_generator__tests__create_pyproject_toml_async_project.snap +++ b/src/snapshots/python_project__project_generator__tests__create_pyproject_toml_async_project.snap @@ -2,4 +2,4 @@ source: src/project_generator.rs expression: content --- -"[tool.poetry]\nname = \"my-project\"\nversion = \"1.0.0\"\ndescription = \"This is a test\"\nauthors = [\"Arthur Dent \"]\nlicense = \"MIT\"\nreadme = \"README.md\"\n\n[tool.poetry.dependencies]\npython = \"^3.10\"\n\n[tool.poetry.group.dev.dependencies]\n\n[build-system]\nrequires = [\"poetry-core>=1.0.0\"]\nbuild-backend = \"poetry.core.masonry.api\"\n\n[tool.mypy]\ncheck_untyped_defs = true\ndisallow_untyped_defs = true\n\n[[tool.mypy.overrides]]\nmodule = [\"tests.*\"]\ndisallow_untyped_defs = false\n\n[tool.pytest.ini_options]\nminversion = \"6.0\"\naddopts = \"--cov=my_project --cov-report term-missing --no-cov-on-fail\"\nasyncio_mode = \"auto\"\nasyncio_default_fixture_loop_scope = \"function\"\nasyncio_default_test_loop_scope = \"function\"\n\n[tool.coverage.report]\nexclude_lines = [\n \"if __name__ == .__main__.:\",\n \"if TYPE_CHECKING:\",\n \"pragma: no cover\",\n]\n\n[tool.ruff]\nline-length = 100\ntarget-version = \"py310\"\nfix = true\n\n[tool.ruff.lint]\nselect = [\n \"E\", # pycodestyle\n \"B\", # flake8-bugbear\n \"W\", # Warning\n \"F\", # pyflakes\n \"UP\", # pyupgrade\n \"I001\", # unsorted-imports\n \"T201\", # print found\n \"T203\", # pprint found\n \"RUF022\", # Unsorted __all__\n \"RUF023\", # Unforted __slots__\n \"ASYNC\", # flake8-async\n]\nignore=[\n # Recommended ignores by ruff when using formatter\n \"E501\",\n \"W191\",\n \"E111\",\n \"E114\",\n \"E117\",\n \"D206\",\n \"D300\",\n \"Q000\",\n \"Q001\",\n \"Q002\",\n \"Q003\",\n \"COM812\",\n \"COM819\",\n \"ISC001\",\n \"ISC002\",\n]\n" +"[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n\n[project]\nname = \"my-project\"\ndescription = \"This is a test\"\nauthors = [\n { name = \"Arthur Dent\", email = \"authur@heartofgold.com\" }\n]\nlicense = { file = \"LICENSE\" }\nreadme = \"README.md\"\nrequires-python = \">=3.10\"\ndynamic = [\"version\"]\ndependencies = []\n\n[dependency-groups]\ndev = []\n\n[tool.hatch.version]\npath = \"my_project/_version.py\"\n\n[tool.mypy]\ncheck_untyped_defs = true\ndisallow_untyped_defs = true\n\n[[tool.mypy.overrides]]\nmodule = [\"tests.*\"]\ndisallow_untyped_defs = false\n\n[tool.pytest.ini_options]\nminversion = \"6.0\"\naddopts = \"--cov=my_project --cov-report term-missing --no-cov-on-fail\"\nasyncio_mode = \"auto\"\nasyncio_default_fixture_loop_scope = \"function\"\nasyncio_default_test_loop_scope = \"function\"\n\n[tool.coverage.report]\nexclude_lines = [\n \"if __name__ == .__main__.:\",\n \"if TYPE_CHECKING:\",\n \"pragma: no cover\",\n]\n\n[tool.ruff]\nline-length = 100\ntarget-version = \"py310\"\nfix = true\n\n[tool.ruff.lint]\nselect = [\n \"E\", # pycodestyle\n \"B\", # flake8-bugbear\n \"W\", # Warning\n \"F\", # pyflakes\n \"UP\", # pyupgrade\n \"I001\", # unsorted-imports\n \"T201\", # print found\n \"T203\", # pprint found\n \"RUF022\", # Unsorted __all__\n \"RUF023\", # Unforted __slots__\n \"ASYNC\", # flake8-async\n]\nignore=[\n # Recommended ignores by ruff when using formatter\n \"E501\",\n \"W191\",\n \"E111\",\n \"E114\",\n \"E117\",\n \"D206\",\n \"D300\",\n \"Q000\",\n \"Q001\",\n \"Q002\",\n \"Q003\",\n \"COM812\",\n \"COM819\",\n \"ISC001\",\n \"ISC002\",\n]\n\n[tool.uv]\nadd-bounds = \"exact\"\n" diff --git a/src/utils.rs b/src/utils.rs index 8c3a111a..ee6fa369 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -10,7 +10,6 @@ pub fn is_python_version_or_greater(version: &str, min_minor_version: i32) -> Re } } -#[cfg(feature = "fastapi")] pub fn is_allowed_fastapi_python_version(version: &str) -> Result { let version_parts = split_version(version)?; From 363ecdc889415d7b6bea7abd0b61ebf7b5cdbceb Mon Sep 17 00:00:00 2001 From: Paul Sanders Date: Fri, 19 Jun 2026 10:06:44 -0400 Subject: [PATCH 2/4] Remove poetry from CI --- .github/workflows/testing.yml | 71 ----------------------------------- 1 file changed, 71 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 5a3797cb..808634f8 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -154,77 +154,6 @@ jobs: working-directory: ${{ env.WORKING_DIR }} if: matrix.project_type == 'application' run: uv run pytest - poetry-linting: - strategy: - fail-fast: false - matrix: - project_type: ["application", "lib"] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - name: install Rust - uses: dtolnay/rust-toolchain@stable - - name: Cache Rust dependencies - uses: Swatinem/rust-cache@v2.9.1 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: "${{ env.MIN_PYTHON_VERSION }}" - - name: Build package - run: cargo build --release - - name: Run creation - run: ./scripts/ci_run.sh ${{ matrix.project_type }} 2 - - name: MyPy - working-directory: ${{ env.WORKING_DIR }} - run: poetry run mypy . - - name: ruff check - working-directory: ${{ env.WORKING_DIR }} - run: poetry run ruff check . - - name: ruff format - working-directory: ${{ env.WORKING_DIR }} - run: poetry run ruff format --check . - poetry-test: - strategy: - fail-fast: false - matrix: - project_type: ["application", "lib"] - os: [ubuntu-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v7 - - name: install Rust - uses: dtolnay/rust-toolchain@stable - - name: Cache Rust dependencies - uses: Swatinem/rust-cache@v2.9.1 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: "3.11" - - name: Build package - run: cargo build --release - - name: Run creation - run: ./scripts/ci_run.sh ${{ matrix.project_type }} 2 - shell: bash - - name: prek check - working-directory: ${{ env.WORKING_DIR }} - run: | - git add . - poetry run prek run --all-files - - name: Test with pytest - working-directory: ${{ env.WORKING_DIR }} - run: poetry run pytest pyo3-linting: strategy: fail-fast: false From 02f677cfa11cafe75ba13845c877573f3483f674 Mon Sep 17 00:00:00 2001 From: Paul Sanders Date: Fri, 19 Jun 2026 10:08:56 -0400 Subject: [PATCH 3/4] Remove Poetry testing from fastapi CI --- .github/workflows/testing_fastapi.yml | 79 --------------------------- 1 file changed, 79 deletions(-) diff --git a/.github/workflows/testing_fastapi.yml b/.github/workflows/testing_fastapi.yml index eefc4ff4..23296d5c 100644 --- a/.github/workflows/testing_fastapi.yml +++ b/.github/workflows/testing_fastapi.yml @@ -97,85 +97,6 @@ jobs: working-directory: ${{ env.WORKING_DIR }} if: matrix.project_type == 'application' run: uv run pytest - test-poetry-fastapi-project: - name: test-fastapi-poetry-setup-fastapi - strategy: - fail-fast: false - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - name: install Rust - uses: dtolnay/rust-toolchain@stable - - name: Cache dependencies - uses: Swatinem/rust-cache@v2.9.1 - - name: Install sqlx-cli - run: cargo install sqlx-cli --no-default-features -F native-tls -F postgres - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: ${{ env.MIN_PYTHON_VERSION }} - - name: Build package - run: cargo build --release -F fastapi - - name: Run creation - run: ./scripts/ci_run_fastapi.sh "fastapi" 2 - shell: bash - - name: prek check - working-directory: ${{ env.WORKING_DIR }} - run: | - git add . - poetry run prek run --all-files - - name: make .env - working-directory: ${{ env.WORKING_DIR }} - run: touch .env - - name: Build and start Docker containers - working-directory: ${{ env.WORKING_DIR }} - run: docker compose up -d - - name: Test with pytest - working-directory: ${{ env.WORKING_DIR }} - run: poetry run pytest -n auto - test-poetry-non-fastapi-project: - name: test-fastapi-poetry-setup-non-fastapi - strategy: - fail-fast: false - matrix: - project_type: ["application", "lib"] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - name: install Rust - uses: dtolnay/rust-toolchain@stable - - name: Cache dependencies - uses: Swatinem/rust-cache@v2.9.1 - - name: Install Poetry - run: pipx install poetry - - name: Configure poetry - run: | - poetry config virtualenvs.create true - poetry config virtualenvs.in-project true - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: ${{ env.MIN_PYTHON_VERSION }} - - name: Build package - run: cargo build --release -F fastapi - - name: Run creation - run: ./scripts/ci_run_fastapi.sh ${{ matrix.project_type }} 2 - shell: bash - - name: prek check - working-directory: ${{ env.WORKING_DIR }} - run: | - git add . - poetry run prek run --all-files - - name: Test with pytest - working-directory: ${{ env.WORKING_DIR }} - if: matrix.project_type == 'application' - run: poetry run pytest test-setuptools-fastapi-project: name: test-fastapi-setuptools-setup-fastapi strategy: From 5736520f5277783817f2a9f7ecacaf1d2d581dd8 Mon Sep 17 00:00:00 2001 From: Paul Sanders Date: Fri, 19 Jun 2026 10:25:26 -0400 Subject: [PATCH 4/4] Update test scripts and workflows --- .github/workflows/testing.yml | 8 ++++---- .github/workflows/testing_fastapi.yml | 12 ++++++------ scripts/ci_run.sh | 4 ++-- scripts/ci_run_fastapi.sh | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 808634f8..833c3071 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -183,7 +183,7 @@ jobs: - name: Build package run: cargo build --release - name: Run creation - run: ./scripts/ci_run.sh ${{ matrix.project_type }} 3 + run: ./scripts/ci_run.sh ${{ matrix.project_type }} 2 - name: MyPy working-directory: ${{ env.WORKING_DIR }} run: just mypy @@ -225,7 +225,7 @@ jobs: - name: Build package run: cargo build --release - name: Run creation - run: ./scripts/ci_run.sh ${{ matrix.project_type }} 3 + run: ./scripts/ci_run.sh ${{ matrix.project_type }} 2 shell: bash - name: Compile Rust working-directory: ${{ env.WORKING_DIR }} @@ -259,7 +259,7 @@ jobs: run: cargo build --release - name: Run creation run: | - ./scripts/ci_run.sh ${{ matrix.project_type }} 4 + ./scripts/ci_run.sh ${{ matrix.project_type }} 3 - name: MyPy working-directory: ${{ env.WORKING_DIR }} run: $PYTHON -m mypy . @@ -298,7 +298,7 @@ jobs: - name: Build package run: cargo build --release - name: Run creation - run: ./scripts/ci_run.sh ${{ matrix.project_type }} 4 + run: ./scripts/ci_run.sh ${{ matrix.project_type }} 3 shell: bash - name: prek check working-directory: ${{ env.WORKING_DIR }} diff --git a/.github/workflows/testing_fastapi.yml b/.github/workflows/testing_fastapi.yml index 23296d5c..67b9b9ad 100644 --- a/.github/workflows/testing_fastapi.yml +++ b/.github/workflows/testing_fastapi.yml @@ -117,7 +117,7 @@ jobs: - name: Build package run: cargo build --release -F fastapi - name: Run creation - run: ./scripts/ci_run_fastapi.sh "fastapi" 4 + run: ./scripts/ci_run_fastapi.sh "fastapi" 3 shell: bash - name: prek check working-directory: ${{ env.WORKING_DIR }} @@ -153,7 +153,7 @@ jobs: - name: Build package run: cargo build --release -F fastapi - name: Run creation - run: ./scripts/ci_run_fastapi.sh ${{ matrix.project_type }} 4 + run: ./scripts/ci_run_fastapi.sh ${{ matrix.project_type }} 3 shell: bash - name: prek check working-directory: ${{ env.WORKING_DIR }} @@ -186,7 +186,7 @@ jobs: - name: Build package run: cargo build --release -F fastapi - name: Run creation - run: ./scripts/ci_run_fastapi.sh "fastapi" 3 + run: ./scripts/ci_run_fastapi.sh "fastapi" 2 shell: bash - name: prek check working-directory: ${{ env.WORKING_DIR }} @@ -224,7 +224,7 @@ jobs: - name: Build package run: cargo build --release -F fastapi - name: Run creation - run: ./scripts/ci_run_fastapi.sh ${{ matrix.project_type }} 3 + run: ./scripts/ci_run_fastapi.sh ${{ matrix.project_type }} 2 shell: bash - name: Compile Rust working-directory: ${{ env.WORKING_DIR }} @@ -259,7 +259,7 @@ jobs: - name: Build package run: cargo build --release -F fastapi - name: Run creation - run: ./scripts/ci_run_fastapi.sh "fastapi" 3 2 + run: ./scripts/ci_run_fastapi.sh "fastapi" 2 2 shell: bash - name: Compile Rust working-directory: ${{ env.WORKING_DIR }} @@ -299,7 +299,7 @@ jobs: - name: Build package run: cargo build --release -F fastapi - name: Run creation - run: ./scripts/ci_run_fastapi.sh ${{ matrix.project_type }} 3 2 + run: ./scripts/ci_run_fastapi.sh ${{ matrix.project_type }} 2 2 shell: bash - name: Compile Rust working-directory: ${{ env.WORKING_DIR }} diff --git a/scripts/ci_run.sh b/scripts/ci_run.sh index 9d3afbed..e643dd6d 100755 --- a/scripts/ci_run.sh +++ b/scripts/ci_run.sh @@ -17,7 +17,7 @@ project_manager="1" # Check for user provided project manager input if [ $# -gt 1 ]; then - if [ $2 -lt 1 ] || [ $2 -gt 5 ]; then + if [ $2 -lt 1 ] || [ $2 -gt 3 ]; then echo "Invalid project_manager value" exit 1 else @@ -44,7 +44,7 @@ use_release_drafter="" use_multi_os_ci="" pyo3_python_manager="" -if [[ project_manager -eq 3 ]]; then +if [[ project_manager -eq 2 ]]; then ./target/release/python-project create << EOF $project_name $project_slug diff --git a/scripts/ci_run_fastapi.sh b/scripts/ci_run_fastapi.sh index 92ad7c9e..6fa1d8d6 100755 --- a/scripts/ci_run_fastapi.sh +++ b/scripts/ci_run_fastapi.sh @@ -18,7 +18,7 @@ project_manager="1" # Check for user provided project manager input if [ $# -gt 1 ]; then - if [ $2 -lt 1 ] || [ $2 -gt 5 ]; then + if [ $2 -lt 1 ] || [ $2 -gt 3 ]; then echo "Invalid project_manager value" exit 1 else @@ -60,7 +60,7 @@ if [ $# -gt 2 ]; then fi fi -if [[ $project_manager -eq 3 ]]; then +if [[ $project_manager -eq 2 ]]; then if [ "$fastapi_project" = "1" ]; then ./target/release/python-project create << EOF $project_name