diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9136e6a..27b98a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: cache: true - name: Building - run: pixi run build-single + run: pixi run build-specific test: runs-on: ubuntu-latest diff --git a/README.md b/README.md index d3713dd..30bd679 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,34 @@ # snakemake-plugin-catalog -An automatically updated catalog of Snakemake plugins and their documentation +An automatically updated catalog of +[Snakemake plugins](https://snakemake.readthedocs.io/en/stable/project_info/codebase.html#plugins) +and their documentation. See + (generated from +[this template](/source/_templates/index.rst.j2)) for a general overview of the +catalog. + +## Contributing + +> WARNING: The `build` task is designed to run on a GitHub runner and will +> install essentially arbitrary code on the machine it is run on. Don't run it +> unless you understand the risk involved! The same goes for `build-specific` if +> you don't understand the plugin you run it on. + +### Software environment + +Like the rest of the Snakemake ecosystem, the plugin catalog uses +[Pixi](https://pixi.prefix.dev/latest/) to manage software environments and +common development and deployment tasks. See their docs for detailed information +on setup and task running. + +### Development + +After making changes to the code, ensure the code is consistently formatted by +doing `pixi run style`. If you make changes to the Jinja templates used to build +the catalog, ensure the underlying rst files follow the general Snakemake +[documentation guidelines](https://snakemake.readthedocs.io/en/stable/project_info/contributing.html#documentation-guidelines). + +### Testing + +Currently there are no unit-tests. Checking whether the code works as expected +is done by building individual plugin docs via the `build-specific` Pixi task. diff --git a/pixi.toml b/pixi.toml index 18fc3a6..5a36ef9 100644 --- a/pixi.toml +++ b/pixi.toml @@ -7,10 +7,19 @@ version = "0.1.0" [tasks] build = "sphinx-build source build" -build-single = { cmd = "sphinx-build source build", env = { TEST_PACKAGES = "snakemake-executor-plugin-cluster-generic" } } apply-qc = [{ task = "style", environment = "style" }] qc = [{ task = "lint", environment = "style" }] +[tasks.build-specific] +description = "Build docs for individual plugins. Separate `package`s with ',' to specify multiple plugins." +cmd = """ +export TEST_PACKAGES="{{ packages }}" && \ +sphinx-build source build +""" +args = [ + { "arg" = "packages", "default" = "snakemake-executor-plugin-cluster-generic,snakemake-executor-plugin-slurm" } +] + [dependencies] sphinx = ">=8.2.3,<9" python = ">=3.11.0,<4" diff --git a/source/_templates/index.rst.j2 b/source/_templates/index.rst.j2 index 989b021..37783ea 100644 --- a/source/_templates/index.rst.j2 +++ b/source/_templates/index.rst.j2 @@ -11,6 +11,8 @@ The following illustration depicts the general architecture of Snakemake and its .. image:: _static/snakemake-architecture.svg :alt: Snakemake plugin architecture +See the corresponding `section `__ in the Snakemake architecture docs for more details. + Contributing ------------ diff --git a/source/collect_plugins.py b/source/collect_plugins.py index eda915f..5be302d 100644 --- a/source/collect_plugins.py +++ b/source/collect_plugins.py @@ -20,7 +20,11 @@ TEST_PACKAGES = ( - os.environ.get("TEST_PACKAGES").split(",") + [ + package.strip() + for package in os.environ.get("TEST_PACKAGES").split(",") + if package.strip() + ] if "TEST_PACKAGES" in os.environ else None ) @@ -50,6 +54,11 @@ def log(self, package: str) -> None: class MetadataCollector: + """ + Collect metadata on a plugin `package` of a specific `plugin_type` by installing it + in a temporary working directory specific to each class instance. + """ + def __init__(self, package: str, plugin_type: str, version: str): self.envname = uuid.uuid4().hex self.package = package @@ -93,6 +102,10 @@ def __enter__(self): ) def pixi_add(args=None): + """ + Add the package for which metadata is to be parsed to the temporary + workspace. + """ args = args or [] self._run(["pixi", "add", f"{self.package}=={self.version}"] + args) @@ -154,6 +167,13 @@ def aux_info(self, metadata_collector) -> Dict[str, Any]: return {} def collect_plugins(self, plugins, packages, templates): + """ + Collect plugins of the type of the corresponding plugin type collector class. + Plugins are selected from the set of ALL pypi packages by matching names to the + expected prefix of 'snakemake-{plugin_type}-plugin-'. For each matching package + metadata is then extracted, the provided `templates` are rendered using this + information, and the plugin name is appended to `plugins`. + """ plugin_type = self.plugin_type() plugin_dir = Path("plugins") / plugin_type if plugin_dir.exists():