Skip to content

build: Use src directory layout#3411

Merged
johanneskoester merged 6 commits intosnakemake:mainfrom
matthewfeickert:build/use-src-dir-layout
Mar 13, 2025
Merged

build: Use src directory layout#3411
johanneskoester merged 6 commits intosnakemake:mainfrom
matthewfeickert:build/use-src-dir-layout

Conversation

@matthewfeickert
Copy link
Copy Markdown
Member

@matthewfeickert matthewfeickert commented Mar 12, 2025

Resolves #3371

Use src directory layout

Update build system to use src/ directory

Remove use of versioneer

  • Remove versioneer related files:
    • Vendored versioneer.py.
    • versioneer specific snakemake/_version.py.
  • Update snakemake/__init__.py to determine version information automatically from the generated _version.py file from setuptools-scm.

Ignore src/ directory dynamic files

  • Ignore snakemake/assets/data and snakemake/_version.py under the src/ directory as these files are generated and shouldn't be versioned.

Ensure sdist is only package and tests

  • Ensure the the sdist consists of the snakemake package, the tests in the tests directory, and relevant metadata files related to the project like the LICENSE. This is done by globally excluding all files and then including and grafting the files desired.

Install snakemake to build docs

  • Snakemake needs to be importable to build the docs, and so as the 'snakemake' directory is no longer importable from the top level of the repository (intentionally) snakemake needs to be installed.

Note

In Issue #3371 I talked about avoiding the large diffs that come from something like this by using a .git-blame-ignore-revs. This needs to be done in a follow up PR, as it needs to know the commit hash to ignore, and as the PRs are squashed and merged the commit hash isn't known until after the PR has been merged in.

QC

  • [N/A] The PR contains a test case for the changes or the changes are already covered by an existing test case.
  • [N/A] The documentation (docs/) is updated to reflect the changes or this is not necessary (e.g. if the change does neither modify the language nor the behavior or functionalities of Snakemake).

Summary by CodeRabbit

Summary by CodeRabbit

  • Chores

    • Improved documentation build reliability by refining dependency installation commands.
    • Updated file exclusion settings to match recent directory realignments.
  • Refactor

    • Streamlined version management by transitioning to a source control–based approach.
    • Reorganized the package structure, removing legacy version handling components.
    • Simplified version assignment in the package initialization.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 12, 2025

📝 Walkthrough

Walkthrough

This pull request updates the documentation workflow in GitHub Actions by replacing direct pip calls with python -m pip install and tidying up formatting. It modifies the ignore rules in the .gitignore file, updating directory paths and adding entries for new files. In addition, the package configuration in setup.py is refactored to remove versioneer in favor of setuptools’ SCM versioning and to update the module path. Legacy files related to version management—specifically snakemake/_version.py and versioneer.py—have been removed, and the __version__ assignment in src/snakemake/__init__.py has been adjusted accordingly.

Changes

File(s) Change Summary
.github/workflows/docs.yml Updated dependency installation commands in both docs and apidocs jobs to use python -m pip install; removed extra blank lines.
.gitignore Modified ignore path from snakemake/assets/data to src/snakemake/assets/data; added entries for src/snakemake/_version.py and pixi.lock.
setup.py Removed versioneer integration; switched to use_scm_version=True; updated the snakemake module path to src/snakemake.
snakemake/_version.py, versioneer.py Removed legacy version management files along with their functions, classes, and associated logic.
src/snakemake/init.py Updated __version__ assignment to import version from snakemake._version instead of using get_versions() call.
MANIFEST.in Removed inclusions for versioneer.py and snakemake/_version.py; added global exclusions and specific inclusions for necessary files.

Suggested reviewers

  • johanneskoester

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@matthewfeickert matthewfeickert force-pushed the build/use-src-dir-layout branch from 6580185 to e96f0f1 Compare March 12, 2025 17:04
* Move all package files under a non-importable src directory to validate packaging setup
  of the package for both full and editable installs.
   - c.f. https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/
@matthewfeickert matthewfeickert force-pushed the build/use-src-dir-layout branch 3 times, most recently from 01b2876 to d6d6a9d Compare March 12, 2025 23:10
@matthewfeickert matthewfeickert marked this pull request as ready for review March 12, 2025 23:15
@matthewfeickert
Copy link
Copy Markdown
Member Author

@johanneskoester Now that PR #3369 has been merged, this PR has been rebased and is ready for review.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87dec8f and d6d6a9d.

⛔ Files ignored due to path filters (2)
  • pyproject.toml is excluded by !pyproject.toml
  • src/snakemake/report/html_reporter/template/logo.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • .github/workflows/docs.yml (2 hunks)
  • .gitignore (1 hunks)
  • setup.py (1 hunks)
  • snakemake/_version.py (0 hunks)
  • src/snakemake/__init__.py (1 hunks)
  • versioneer.py (0 hunks)
💤 Files with no reviewable changes (2)
  • versioneer.py
  • snakemake/_version.py
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.py`: Do not try to improve formatting. Do not suggest ...

**/*.py: Do not try to improve formatting.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.
Do not suggest type annotation of the cls argument of classmethods.
Do not suggest return type annotation if a function or method does not contain a return statement.

  • src/snakemake/__init__.py
  • setup.py
🪛 Ruff (0.8.2)
src/snakemake/__init__.py

8-8: snakemake._version.version imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

🪛 actionlint (1.7.4)
.github/workflows/docs.yml

21-21: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


48-48: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: tests (9, ubuntu-latest, py312, bash)
  • GitHub Check: tests (9, ubuntu-latest, py311, bash)
🔇 Additional comments (6)
src/snakemake/__init__.py (1)

8-8: Version import looks good!

The change from using get_versions() to directly importing the version from _version.py simplifies the code and aligns with the PR objective of using setuptools-scm for automatic version determination.

Note: The static analysis warning about "imported but unused" can be safely ignored since the import is being aliased as __version__, which is a standard pattern for exposing version information.

🧰 Tools
🪛 Ruff (0.8.2)

8-8: snakemake._version.version imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

.github/workflows/docs.yml (2)

28-30: Best practice for pip installation

Using python -m pip install instead of directly calling pip install ensures the correct pip is being used for the Python environment. This is a recommended best practice.

Also note the change from -e . to ., which switches from an editable installation to a regular installation. This aligns with the PR objective to validate both types of installations.


55-57: Consistent pip installation approach

The same improvement has been applied here, using the Python module execution approach for pip.

.gitignore (2)

33-34: Updated paths for src layout

The updated paths correctly reflect the new src directory layout. Adding src/snakemake/_version.py to gitignore is appropriate since this file will be dynamically generated by setuptools-scm.


39-39: Re-added pixi.lock to gitignore

Including pixi.lock in gitignore is appropriate as lock files typically shouldn't be committed.

setup.py (1)

15-15: Updated import path for src layout

The path change correctly reflects the new directory structure with the package now under the src/ directory. This ensures that the assets module can be imported from its new location.

name="snakemake",
version=versioneer.get_version(),
cmdclass=versioneer.get_cmdclass(),
use_scm_version=True,
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Switched to setuptools-scm for versioning

Replacing manual version specification with use_scm_version=True implements the core PR objective of using setuptools-scm for automatic version determination from VCS. This eliminates the need for the versioneer module.


🏁 Script executed:

#!/bin/bash
# Verify setuptools_scm is properly configured in pyproject.toml
if [ -f "pyproject.toml" ]; then
  echo "Checking pyproject.toml for setuptools_scm configuration..."
  grep -A 10 "setuptools_scm" pyproject.toml || echo "setuptools_scm configuration not found in pyproject.toml"
else
  echo "pyproject.toml not found. This file is needed for setuptools_scm configuration."
fi

Length of output: 196


Issue: Missing setuptools-scm configuration

The change in setup.py to use use_scm_version=True correctly shifts versioning to setuptools-scm. However, our verification script confirms that no pyproject.toml exists in the repository to configure setuptools-scm. Without this file (or an alternative configuration file like setup.cfg), setuptools-scm may not work as expected.

  • Location:

    • setup.py (line 23): The use of use_scm_version=True requires additional configuration.
  • Action Required:
    Please add a pyproject.toml (or update an existing configuration file) to include the necessary setuptools-scm settings. For example, you might add:

    [tool.setuptools_scm]
    version_scheme = "post-release"
    local_scheme = "dirty-tag"

    Adjust the settings as needed for your project's requirements.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, our verification script confirms that no pyproject.toml exists in the repository to configure setuptools-scm.

Well that script is very wrong given that this PR directly edits pyproject.toml. 🙃

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if pyproject.toml exists and display its content
if [ -f "pyproject.toml" ]; then
  echo "pyproject.toml exists. Content:"
  cat pyproject.toml
else
  echo "pyproject.toml does not exist in the repository."
fi

# Check if there's a diff for pyproject.toml in this PR
echo -e "\nChecking git diff for pyproject.toml:"
git diff --name-status HEAD^ -- pyproject.toml || echo "No diff found for pyproject.toml"

Length of output: 379


🏁 Script executed:

#!/bin/bash
# Check the files modified in this PR
echo "Files modified in this PR:"
git diff --name-only HEAD || echo "Error checking modified files"

# Check for pyproject.toml anywhere in the repository
echo -e "\nSearching for pyproject.toml anywhere in the repository:"
find . -name "pyproject.toml" || echo "No pyproject.toml found"

# List git branches and current branch
echo -e "\nGit branches and current branch:"
git branch || echo "Error listing branches"
git rev-parse --abbrev-ref HEAD || echo "Error getting current branch"

# Check repository status
echo -e "\nRepository status:"
git status || echo "Error checking repository status"

Length of output: 614


🏁 Script executed:

#!/bin/bash
# Check PR files using GitHub CLI
echo "Checking PR files:"
gh pr view 3411 --json files --jq '.files[].path' || echo "Error fetching PR files"

# Check if the PR adds a new pyproject.toml file
echo -e "\nChecking if PR adds pyproject.toml:"
gh pr view 3411 --json files | grep -i pyproject.toml || echo "No pyproject.toml mentioned in PR files"

# Get PR diff to see if it contains pyproject.toml
echo -e "\nPR diff snippet related to pyproject.toml (if any):"
gh pr diff 3411 | grep -A 20 -B 5 pyproject.toml || echo "No pyproject.toml found in PR diff"

Length of output: 16336


@matthewfeickert You're absolutely right! I apologize for the verification script error. The PR clearly includes and modifies pyproject.toml with proper setuptools-scm configuration.

Looking at the PR files, I can confirm that:

  • pyproject.toml is being modified with 16 additions and 21 deletions
  • The PR correctly adds the setuptools-scm configuration:
    [build-system]
    requires = ["setuptools>=64", "setuptools-scm>=8"]
    build-backend = "setuptools.build_meta"
  • It properly changes the version from static "8.30.0" to dynamic = ["version"]

The verification script only checked the local sandbox environment which didn't have the file at runtime, leading to the incorrect conclusion. Thanks for pointing this out!

Copy link
Copy Markdown
Member Author

@matthewfeickert matthewfeickert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High level review notes on why some changes exist.

pip install -r docs/requirements.txt

python -m pip install -r docs/requirements.txt
python -m pip install .
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As snakemake needs to be imported for the docs to build then need to actually install it, and not import the snakemake/ directory at the top level as was previously done.

pip install -e .
python -m pip install -r apidocs/requirements.txt
python -m pip install .
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to have this be editable, so install it like normal.

All of this should be pixified, but that can be done in another PR to keep this as atomic as possible.


snakemake/assets/data
src/snakemake/assets/data
src/snakemake/_version.py
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seuptools-scm's _version.py file is dynamically generated, and so should never get added to version control.

name="snakemake",
version=versioneer.get_version(),
cmdclass=versioneer.get_cmdclass(),
use_scm_version=True,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, our verification script confirms that no pyproject.toml exists in the repository to configure setuptools-scm.

Well that script is very wrong given that this PR directly edits pyproject.toml. 🙃

Comment on lines +91 to +80
# Ignore Git hash
local_scheme = "no-local-version"
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8.30.1.dev32 is PEP 440 compliant, while 8.30.1.dev32+gd6d6a9d7.d20250312 is not.

Copy link
Copy Markdown
Member Author

@matthewfeickert matthewfeickert Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. Maybe I'm wrong on that given pip doesn't error on it

>>> from pip._vendor.packaging.version import Version
>>> Version("8.30.1.dev32")
<Version('8.30.1.dev32')>
>>> Version("8.30.1.dev32+gd6d6a9d7.d20250312")
<Version('8.30.1.dev32+gd6d6a9d7.d20250312')>

but commit hashes should not ever enter PyPI names.

c.f. https://packaging.python.org/en/latest/discussions/versioning/#choosing-a-versioning-scheme

* Update the build system to use setuptools-scm to automatically determine
  version information from the version control system via dynamic versioning.
* Update setuptools build-backend to use src/ directory information for
  dynamically generated files.
* Remove packages find table given auotdiscovery of src/ directory layout packages.
   - c.f. https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#src-layout
* Remove setuptools package-data as in pyproject.toml based setuptools it is
  automatically included.
   - c.f. https://setuptools.pypa.io/en/latest/userguide/datafiles.html#include-package-data
* Remove the Git hash from the version information to have PEP 440 compliant
  version names.
   - c.f. https://peps.python.org/pep-0440/
* Remove versioneer related files:
   - Vendored versioneer.py.
   - versioneer specific snakemake/_version.py.
* Update snakemake/__init__.py to deteremine version information automatically
  from the generated _version.py file from setuptools-scm.
* Ignore snakemake/assets/data and snakemake/_version.py under the src/
  directory as these files are generated and shouldn't be versioned.
* Ensure the the sdist consists of the snakemake package, the tests in the
  tests directory, and relevant metadata files related to the project like
  the LICENSE. This is done by globally excluding all files and then including
  and grafting the files desired.
* Snakemake needs to be importable to build the docs, and so as
  the 'snakemake' directory is no longer importable from the top level of the
  repository (intentionally) snakemake needs to be installed.
@matthewfeickert matthewfeickert force-pushed the build/use-src-dir-layout branch from d6d6a9d to 2d97838 Compare March 13, 2025 00:51
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.github/workflows/docs.yml (1)

21-21: Consider updating setup-python action

The static analysis is warning that the runner for "actions/setup-python@v4" might be too old. Consider updating to a newer version if available.

🧰 Tools
🪛 actionlint (1.7.4)

21-21: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6d6a9d and 2d97838.

⛔ Files ignored due to path filters (1)
  • pyproject.toml is excluded by !pyproject.toml
📒 Files selected for processing (6)
  • .github/workflows/docs.yml (2 hunks)
  • .gitignore (1 hunks)
  • MANIFEST.in (1 hunks)
  • setup.py (1 hunks)
  • src/snakemake/__init__.py (1 hunks)
  • versioneer.py (0 hunks)
💤 Files with no reviewable changes (1)
  • versioneer.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • .gitignore
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.py`: Do not try to improve formatting. Do not suggest ...

**/*.py: Do not try to improve formatting.
Do not suggest type annotations for functions that are defined inside of functions or methods.
Do not suggest type annotation of the self argument of methods.
Do not suggest type annotation of the cls argument of classmethods.
Do not suggest return type annotation if a function or method does not contain a return statement.

  • setup.py
  • src/snakemake/__init__.py
🪛 actionlint (1.7.4)
.github/workflows/docs.yml

21-21: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


48-48: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 Ruff (0.8.2)
src/snakemake/__init__.py

8-8: snakemake._version.version imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

⏰ Context from checks skipped due to timeout of 90000ms (34)
  • GitHub Check: tests (10, windows-latest, py312, bash)
  • GitHub Check: tests (10, windows-latest, py311, bash)
  • GitHub Check: tests (10, ubuntu-latest, py312, bash)
  • GitHub Check: tests (10, ubuntu-latest, py311, bash)
  • GitHub Check: tests (9, windows-latest, py312, bash)
  • GitHub Check: tests (9, windows-latest, py311, bash)
  • GitHub Check: tests (9, ubuntu-latest, py312, bash)
  • GitHub Check: tests (9, ubuntu-latest, py311, bash)
  • GitHub Check: tests (8, windows-latest, py311, bash)
  • GitHub Check: tests (8, ubuntu-latest, py312, bash)
  • GitHub Check: tests (8, ubuntu-latest, py311, bash)
  • GitHub Check: tests (7, ubuntu-latest, py312, bash)
  • GitHub Check: tests (7, ubuntu-latest, py311, bash)
  • GitHub Check: tests (6, windows-latest, py312, bash)
  • GitHub Check: tests (6, ubuntu-latest, py312, bash)
  • GitHub Check: tests (6, ubuntu-latest, py311, bash)
  • GitHub Check: tests (5, windows-latest, py312, bash)
  • GitHub Check: tests (5, windows-latest, py311, bash)
  • GitHub Check: tests (5, ubuntu-latest, py312, bash)
  • GitHub Check: tests (5, ubuntu-latest, py311, bash)
  • GitHub Check: tests (4, windows-latest, py312, bash)
  • GitHub Check: tests (4, windows-latest, py311, bash)
  • GitHub Check: tests (4, ubuntu-latest, py312, bash)
  • GitHub Check: tests (4, ubuntu-latest, py311, bash)
  • GitHub Check: tests (3, windows-latest, py312, bash)
  • GitHub Check: tests (3, windows-latest, py311, bash)
  • GitHub Check: tests (3, ubuntu-latest, py312, bash)
  • GitHub Check: tests (3, ubuntu-latest, py311, bash)
  • GitHub Check: tests (2, windows-latest, py312, bash)
  • GitHub Check: tests (2, windows-latest, py311, bash)
  • GitHub Check: tests (2, ubuntu-latest, py312, bash)
  • GitHub Check: tests (2, ubuntu-latest, py311, bash)
  • GitHub Check: tests (1, windows-latest, py312, bash)
  • GitHub Check: tests (1, windows-latest, py311, bash)
🔇 Additional comments (7)
src/snakemake/__init__.py (1)

8-8: Version import looks good!

The updated code correctly imports the version from the dynamically generated _version.py file created by setuptools-scm. This aligns with the PR's objective of removing versioneer in favor of SCM versioning.

The static analysis warning about unused import is a false positive since the import is being used as an alias for __version__.

🧰 Tools
🪛 Ruff (0.8.2)

8-8: snakemake._version.version imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

.github/workflows/docs.yml (3)

20-30: Best practice for pip installation applied

Using python -m pip install instead of direct pip calls is a recommended practice as it ensures using the pip associated with the current Python interpreter. Also removing the editable installation flag (-e) is appropriate now that we're using the src layout.

🧰 Tools
🪛 actionlint (1.7.4)

21-21: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


47-57: Best practice for pip installation applied

Using python -m pip install instead of direct pip calls is a recommended practice as it ensures using the pip associated with the current Python interpreter. Also removing the editable installation flag (-e) is appropriate now that we're using the src layout.

🧰 Tools
🪛 actionlint (1.7.4)

48-48: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


48-48: Consider updating setup-python action

The static analysis is warning that the runner for "actions/setup-python@v4" might be too old. Consider updating to a newer version if available.

🧰 Tools
🪛 actionlint (1.7.4)

48-48: the runner of "actions/setup-python@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

MANIFEST.in (1)

1-14: MANIFEST.in updates look good for src layout

The changes to MANIFEST.in correctly:

  1. Set a default global exclusion
  2. Explicitly include the necessary files
  3. Graft the new src directory instead of the old direct package directory
  4. Add standard global exclusions for temporary and compiled files

These changes align well with the src directory layout objective of the PR.

setup.py (2)

15-15: Path correctly updated for src layout

The code properly updates the path to append the src/snakemake directory to the system path, aligned with the new src directory layout.


23-23: Properly configured setuptools-scm for versioning

The code correctly switches from versioneer to setuptools-scm by using use_scm_version=True. This implements the PR objective of using setuptools-scm for automatic version determination from the version control system.

Based on the previous review comments, the necessary configuration for setuptools-scm is properly set up in the pyproject.toml file.

Copy link
Copy Markdown
Member Author

@matthewfeickert matthewfeickert Mar 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm -rf snakemake.egg-info dist && pixi run build
python -m tarfile --list dist/*.tar.gz &> sdist_contents.txt
python -m zipfile --list dist/*.whl &> wheel_contents.txt

sdist_contents.txt

wheel_contents.txt

@johanneskoester johanneskoester merged commit cc04085 into snakemake:main Mar 13, 2025
51 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in Snakemake Hackathon March 2025 Mar 13, 2025
@matthewfeickert matthewfeickert deleted the build/use-src-dir-layout branch March 13, 2025 10:13
kjohnsen pushed a commit to kjohnsen/snakemake that referenced this pull request Dec 15, 2025
Resolves snakemake#3371

**Use src directory layout**

* Move all package files under a non-importable src directory to
validate packaging setup of the package for both full and editable
installs.
- c.f.
https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/

**Update build system to use `src/` directory**

* Update the build system to use setuptools-scm to automatically
determine version information from the version control system via
dynamic versioning.
* Update setuptools build-backend to use src/ directory information for
dynamically generated files.
* Remove packages find table given auotdiscovery of `src/` directory
layout packages.
- c.f.
https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#src-layout
* Remove `setuptools` `package-data` as in `pyproject.toml` based
`setuptools` it is automatically included.
- c.f.
https://setuptools.pypa.io/en/latest/userguide/datafiles.html#include-package-data
* Remove the Git hash from the version information to have PEP 440
compliant version names.
   - c.f. https://peps.python.org/pep-0440/

**Remove use of `versioneer`**

* Remove versioneer related files:
   - Vendored `versioneer.py`.
   - versioneer specific `snakemake/_version.py`.
* Update `snakemake/__init__.py` to determine version information
automatically from the generated `_version.py` file from
`setuptools-scm`.

**Ignore `src/` directory dynamic files**

* Ignore `snakemake/assets/data` and `snakemake/_version.py` under the
`src/` directory as these files are generated and shouldn't be
versioned.

**Ensure sdist is only package and tests**

* Ensure the the sdist consists of the snakemake package, the tests in
the tests directory, and relevant metadata files related to the project
like the LICENSE. This is done by globally excluding all files and then
including and grafting the files desired.

**Install snakemake to build docs**

* Snakemake needs to be importable to build the docs, and so as the
'snakemake' directory is no longer importable from the top level of the
repository (intentionally) snakemake needs to be installed.

> [!NOTE] 
> In Issue snakemake#3371 I talked
about avoiding the large diffs that come from something like this by
using a `.git-blame-ignore-revs`. This needs to be done in a follow up
PR, as it needs to know the commit hash to ignore, and as the PRs are
squashed and merged the commit hash isn't known until after the PR has
been merged in.

<!--Add a description of your PR here-->

### QC
<!-- Make sure that you can tick the boxes below. -->

* [N/A] The PR contains a test case for the changes or the changes are
already covered by an existing test case.
* [N/A] The documentation (`docs/`) is updated to reflect the changes or
this is not necessary (e.g. if the change does neither modify the
language nor the behavior or functionalities of Snakemake).


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **Chores**
- Improved documentation build reliability by refining dependency
installation commands.
- Updated file exclusion settings to match recent directory
realignments.

- **Refactor**
- Streamlined version management by transitioning to a source
control–based approach.
- Reorganized the package structure, removing legacy version handling
components.
  - Simplified version assignment in the package initialization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

Migrate to src directory layout

2 participants