diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..40e811e --- /dev/null +++ b/.flake8 @@ -0,0 +1,15 @@ + +[flake8] +doctests = True +exclude = + **/__init__.py + *build/ + docs/sphinxext/ + docs/tools/ + docs/conf.py + docs/source/conf.py +max-line-length = 88 +select = C,E,F,W,B,B950 +extend-ignore = E203,E501,E129,W503 +per-file-ignores = + __init__.py:F401,F403 diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/ci-cd.yaml similarity index 90% rename from .github/workflows/pythonpackage.yml rename to .github/workflows/ci-cd.yaml index bf2d864..2a7da3b 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/ci-cd.yaml @@ -4,11 +4,7 @@ # For deployment, it will be necessary to create a PyPI API token and store it as a secret # https://docs.github.com/en/actions/reference/encrypted-secrets -name: Python package - -# Set once -env: - SUBPACKAGE: TODO +name: CI/CD on: push: @@ -44,7 +40,7 @@ jobs: - name: Install task package run: | pip install ${{ matrix.pip-flags }} ".[dev]" - python -c "import pydra.tasks.$SUBPACKAGE as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + python -c "import pydra.tasks.CHANGEME as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" test: @@ -65,12 +61,12 @@ jobs: - name: Install task package run: | pip install ".[test]" - python -c "import pydra.tasks.$SUBPACKAGE as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + python -c "import pydra.tasks.CHANGEME as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - name: Test with pytest run: | - pytest -sv --doctest-modules pydra/tasks/$SUBPACKAGE \ - --cov pydra.tasks.$SUBPACKAGE --cov-report xml + pytest -sv --doctest-modules pydra/tasks/CHANGEME \ + --cov pydra.tasks.CHANGEME --cov-report xml - uses: codecov/codecov-action@v3 if: ${{ always() }} diff --git a/.github/workflows/fileformats-ci-cd.yaml b/.github/workflows/fileformats-ci-cd.yaml new file mode 100644 index 0000000..58b80a8 --- /dev/null +++ b/.github/workflows/fileformats-ci-cd.yaml @@ -0,0 +1,132 @@ +name: CI/CD + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + release: + types: [published] + +defaults: + run: + shell: bash + +jobs: + test: + strategy: + matrix: + os: [ubuntu-latest] + python-version: ["3.8", "3.12"] + fail-fast: false + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash -l {0} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Unset header + # checkout@v2 adds a header that makes branch protection report errors + # because the Github action bot is not a collaborator on the repo + run: git config --local --unset http.https://github.com/.extraheader + - name: Fetch tags + run: git fetch --prune --unshallow + - name: Disable etelemetry + run: echo "NO_ET=TRUE" >> $GITHUB_ENV + - name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Update build tools + run: python3 -m pip install --upgrade pip + - name: Install Package + run: python3 -m pip install -e related-packages/fileformats[test] -e related-packages/fileformats-extras[test] + - name: Pytest + run: pytest -vvs --cov fileformats.medimage_CHANGEME --cov-config .coveragerc --cov-report xml . + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v2 + with: + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + + build: + needs: [test] + runs-on: ubuntu-latest + strategy: + matrix: + pkg: + - ["main", "related-packages/fileformats"] + - ["extras", "related-packages/fileformats-extras"] + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - name: Unset header + # checkout@v2 adds a header that makes branch protection report errors + # because the Github action bot is not a collaborator on the repo + run: git config --local --unset http.https://github.com/.extraheader + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + - name: Install build tools + run: python3 -m pip install build twine + - name: Build source and wheel distributions + run: python3 -m build ${{ matrix.pkg[1] }} + - name: Check distributions + run: twine check ${{ matrix.pkg[1] }}/dist/* + - uses: actions/upload-artifact@v3 + with: + name: built-${{ matrix.pkg[0] }} + path: ${{ matrix.pkg[1] }}/dist + + deploy: + needs: [build] + runs-on: ubuntu-latest + steps: + - name: Download build + uses: actions/download-artifact@v3 + with: + name: built-main + path: dist + - name: Check for PyPI token on tag + id: deployable + if: github.event_name == 'release' + env: + PYPI_API_TOKEN: "${{ secrets.FILEFORMATS_PYPI_API_TOKEN }}" + run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI + if: steps.deployable.outputs.DEPLOY + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.FILEFORMATS_PYPI_API_TOKEN }} + + deploy-extras: + needs: [build, deploy] + runs-on: ubuntu-latest + steps: + - name: Download build + uses: actions/download-artifact@v3 + with: + name: built-extras + path: dist + - name: Check for PyPI token on tag + id: deployable + if: github.event_name == 'release' + env: + EXTRAS_PYPI_API_TOKEN: "${{ secrets.FILEFORMATS_EXTRAS_PYPI_API_TOKEN }}" + run: if [ -n "$EXTRAS_PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI + if: steps.deployable.outputs.DEPLOY + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.FILEFORMATS_EXTRAS_PYPI_API_TOKEN }} + +# Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets. +# Secrets are not accessible in the if: condition [0], so set an output variable [1] +# [0] https://github.community/t/16928 +# [1] https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter diff --git a/.gitignore b/.gitignore index 846dc44..de08422 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ __pycache__/ .Python build/ develop-eggs/ +_version.py dist/ downloads/ eggs/ @@ -130,3 +131,12 @@ dmypy.json # Pycharm .idea + +# Vim +.*.sw[op] + +# VS Code +.vscode + +# Mac garbarge +.DS_store diff --git a/README.md b/README.md index ae25a36..e3d17bc 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,25 @@ All tasks will be inserted into the `pydra.tasks.` namespac 1. Click on new repo. 1. Select this template from the repository template drop down list. 1. Give your repo a name. -1. Once the repo is created and cloned, search for TODO (`grep -rn TODO . `) and +1. Once the repo is created and cloned, search for CHANGEME (`grep -rn CHANGEME . `) and replace with appropriate name. -1. One of the folders is called TODO. This should also be renamed to your package - name. -1. Add tasks to the `pydra/tasks/` folder. -1. An example subpackage is found in `pydra/tasks//utils`. - You may wish to add tools to it or delete it. +1. Rename the namespace package root directory to replace `CHANGEME` with the name of the package: + * `src/pydra/tasks/CHANGEME` +1. If you are planning to define [fileformats](https://arcanaframework.github.io/fileformats/) classes specific + to the tools defined in the task package, then rename the base and "extras" packages using a + matching name to the package (if the tool is from in another field other than medical imaging, + also replace the `medimage` part). If you don't need to define and tool-specific fileformats you can delete + these packages and the .github/workflows/fileformats-ci-cd.yaml + * `related-packages/fileformats/fileformats/medimage_CHANGEME` + * `related-packages/fileformats-extras/fileformats/extras/medimage_CHANGEME` +1. Under the newly renamed package (i.e. formerly CHANGEME) there is a directory named "v1", + `src/pydra/tasks//v1`, change this to valid Python package name starting with + 'v' to indicate the version of the tool the Pydra interfaces will be designed for, + e.g. FSL v6.0.2 could be `src/pydra/tasks/fsl/v6` or `src/pydra/tasks/fsl/v6_0` depending on + how stable the CLI of the tool is between minor versions. +1. Edit `src/pydra/tasks//latest.py` to update references to `v1` to the + tool target version +1. Add tasks to the `src/pydra/tasks//v` folder. 1. You may want to initialize a [Sphinx] docs directory. 1. Review the workflow in `.github/workflows/pythonpackage.yml`. Testing editable installations is probably not useful unless you are reconfiguring namespace packages. @@ -35,7 +47,7 @@ python -m build twine upload dist/* ``` -Note that uploading to PyPI is done via [Continuous integration](#continuous-integration)) when +Note that uploading to PyPI is done via [Continuous integration](#continuous-integration) when a tag is pushed to the repository, so only the first step needs to be donne manually. Note also that we assume tags will be version numbers and not be prefixed with `v` or some other diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..c8338f4 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,51 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = "pydra-CHANGEME" +copyright = "2020, Xihe Xie" +author = "Xihe Xie" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "alabaster" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..f9bdc2e --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,15 @@ +Welcome to pydra-CHANGEME's documentation! +========================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..2119f51 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/pydra/tasks/CHANGEME/__init__.py b/pydra/tasks/CHANGEME/__init__.py new file mode 100644 index 0000000..887f1a7 --- /dev/null +++ b/pydra/tasks/CHANGEME/__init__.py @@ -0,0 +1,14 @@ +""" +This is a basic doctest demonstrating that the package and pydra can both be successfully +imported. + +>>> import pydra.engine +>>> import pydra.tasks.CHANGEME +""" +try: + from ._version import __version__ +except ImportError: + raise RuntimeError( + "Pydra package 'CHANGEME' has not been installed, please use " + "`pip install -e ` to install development version" + ) diff --git a/pydra/tasks/CHANGEME/latest.py b/pydra/tasks/CHANGEME/latest.py new file mode 100644 index 0000000..f41e057 --- /dev/null +++ b/pydra/tasks/CHANGEME/latest.py @@ -0,0 +1,3 @@ +PACKAGE_VERSION = "v1" + +from .v1 import * # noqa diff --git a/pydra/tasks/CHANGEME/v1/__init__.py b/pydra/tasks/CHANGEME/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pydra/tasks/TODO/__init__.py b/pydra/tasks/TODO/__init__.py deleted file mode 100644 index 5b9e250..0000000 --- a/pydra/tasks/TODO/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -""" -This is a basic doctest demonstrating that the package and pydra can both be successfully -imported. - ->>> import pydra.engine ->>> import pydra.tasks.TODO -""" -try: - from ._version import __version__ -except ImportError: - pass diff --git a/pydra/tasks/TODO/utils/__init__.py b/pydra/tasks/TODO/utils/__init__.py deleted file mode 100644 index 562c98f..0000000 --- a/pydra/tasks/TODO/utils/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -This is a basic doctest demonstrating that subpackags can also be -imported. - ->>> import pydra.tasks.TODO.utils -""" diff --git a/pyproject.toml b/pyproject.toml index 2d1b65f..a5ea6c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,19 @@ [build-system] -requires = ["flit_scm"] -build-backend = "flit_scm:buildapi" +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" [project] -name = "pydra-tasks-TODO" -description = "Description for pydra-tasks-TODO" +name = "pydra-CHANGEME" +description = "Pydra tasks package for CHANGEME" readme = "README.md" -requires-python = ">=3.7" -dependencies = ["pydra >=0.20"] +requires-python = ">=3.8" +dependencies = [ + "pydra >=0.22", + "fileformats >=0.8.3", + "fileformats-datascience >=0.1", + "fileformats-medimage >=0.4.1", + "fileformats-medimage-CHANGEME" +] license = {file = "LICENSE"} authors = [{name = "Nipype developers", email = "neuroimaging@python.org"}] maintainers = [{name = "Nipype developers", email = "neuroimaging@python.org"}] @@ -44,18 +50,34 @@ test = [ "pytest-xdist", "pytest-rerunfailures", "codecov", + "fileformats-extras", + "fileformats-datascience-extras", + "fileformats-medimage-extras", + "fileformats-medimage-CHANGEME-extras" ] -[tool.flit.module] -name = "pydra.tasks.TODO" +[tool.hatch.version] +source = "vcs" -[tool.flit.sdist] -exclude = [".gitignore"] +[tool.hatch.build.hooks.vcs] +version-file = "pydra/tasks/CHANGEME/_version.py" -[tool.setuptools_scm] -write_to = "pydra/tasks/TODO/_version.py" +[tool.hatch.build.targets.wheel] +packages = ["pydra"] +include-only = ["pydra/tasks/CHANGEME"] [tool.black] -line-length = 99 -target-version = ["py37"] +target-version = ["py38"] exclude = "_version.py" + +[tool.codespell] +ignore-words = ".codespell-ignorewords" + +[tool.flake8] +doctests = true +per-file-ignores = [ + "__init__.py:F401,F403" +] +max-line-length = 88 +select = "C,E,F,W,B,B950" +extend-ignore = ['E203', 'E501', 'E129', 'W503'] diff --git a/related-packages/conftest.py b/related-packages/conftest.py new file mode 100644 index 0000000..2a703c0 --- /dev/null +++ b/related-packages/conftest.py @@ -0,0 +1,37 @@ +import os +import logging +from pathlib import Path +import tempfile +import pytest + +# Set DEBUG logging for unittests + +log_level = logging.WARNING + +logger = logging.getLogger("fileformats") +logger.setLevel(log_level) + +sch = logging.StreamHandler() +sch.setLevel(log_level) +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +sch.setFormatter(formatter) +logger.addHandler(sch) + + +# For debugging in IDE's don't catch raised exceptions and let the IDE +# break at it +if os.getenv("_PYTEST_RAISE", "0") != "0": + + @pytest.hookimpl(tryfirst=True) + def pytest_exception_interact(call): + raise call.excinfo.value + + @pytest.hookimpl(tryfirst=True) + def pytest_internalerror(excinfo): + raise excinfo.value + + +@pytest.fixture +def work_dir(): + work_dir = tempfile.mkdtemp() + return Path(work_dir) diff --git a/related-packages/fileformats-extras/LICENSE b/related-packages/fileformats-extras/LICENSE new file mode 100644 index 0000000..e00bcb3 --- /dev/null +++ b/related-packages/fileformats-extras/LICENSE @@ -0,0 +1,13 @@ + Copyright 2021 Nipype developers + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/related-packages/fileformats-extras/README.rst b/related-packages/fileformats-extras/README.rst new file mode 100644 index 0000000..4e12d62 --- /dev/null +++ b/related-packages/fileformats-extras/README.rst @@ -0,0 +1,29 @@ +FileFormats-CHANGEME Extras +====================================== +.. image:: https://github.com/nipype/pydra-freesurfer/actions/workflows/ci-cd.yaml/badge.svg + :target: https://github.com/nipype/pydra-freesurfer/actions/workflows/ci-cd.yaml + + +This is a extras module for the `fileformats-CHANGEME `__ +fileformats extension package, which provides additional functionality to format classes (i.e. aside +from basic identification and validation), such as conversion tools, metadata parsers, test data generators, etc... + + +Quick Installation +------------------ + +This extension can be installed for Python 3 using *pip*:: + + $ pip3 install fileformats-CHANGEME-extras + +This will install the core package and any other dependencies + +License +------- + +This work is licensed under a +`Creative Commons Attribution 4.0 International License `_ + +.. image:: https://i.creativecommons.org/l/by/4.0/88x31.png + :target: http://creativecommons.org/licenses/by/4.0/ + :alt: Creative Commons Attribution 4.0 International License diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_CHANGEME/__init__.py b/related-packages/fileformats-extras/fileformats/extras/medimage_CHANGEME/__init__.py new file mode 100644 index 0000000..8dee4bf --- /dev/null +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_CHANGEME/__init__.py @@ -0,0 +1 @@ +from ._version import __version__ diff --git a/related-packages/fileformats-extras/pyproject.toml b/related-packages/fileformats-extras/pyproject.toml new file mode 100644 index 0000000..fbb1237 --- /dev/null +++ b/related-packages/fileformats-extras/pyproject.toml @@ -0,0 +1,87 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "fileformats-medimage-CHANGEME-extras" +description = "Extensions to add functionality to tool-specific *fileformats* classes" +readme = "README.rst" +requires-python = ">=3.8" +dependencies = [ + "fileformats", + "fileformats-medimage-CHANGEME", + "pydra >= 0.23.0a" +] +license = {file = "LICENSE"} +authors = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +maintainers = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +keywords = [ + "file formats", + "data", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", +] +dynamic = ["version"] + +[project.optional-dependencies] +dev = [ + "black", + "pre-commit", + "codespell", + "flake8", + "flake8-pyproject", +] +test = [ + "pytest >=6.2.5", + "pytest-env>=0.6.2", + "pytest-cov>=2.12.1", + "codecov", +] + +converters = [ +] + +[project.urls] +repository = "https://github.com/nipype/pydra-CHANGEME" + +[tool.hatch.version] +source = "vcs" +raw-options = { root = "../.." } + +[tool.hatch.build.hooks.vcs] +version-file = "fileformats/extras/medimage_CHANGEME/_version.py" + +[tool.hatch.build.targets.wheel] +packages = ["fileformats"] + +[tool.black] +target-version = ['py38'] +exclude = "fileformats/extras/medimage_CHANGEME/_version.py" + +[tool.codespell] +ignore-words = ".codespell-ignorewords" + +[tool.flake8] +doctests = true +per-file-ignores = [ + "__init__.py:F401" +] +max-line-length = 88 +select = "C,E,F,W,B,B950" +extend-ignore = ['E203', 'E501', 'E129'] diff --git a/related-packages/fileformats/LICENSE b/related-packages/fileformats/LICENSE new file mode 100644 index 0000000..e00bcb3 --- /dev/null +++ b/related-packages/fileformats/LICENSE @@ -0,0 +1,13 @@ + Copyright 2021 Nipype developers + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/related-packages/fileformats/README.rst b/related-packages/fileformats/README.rst new file mode 100644 index 0000000..8e4c9b2 --- /dev/null +++ b/related-packages/fileformats/README.rst @@ -0,0 +1,39 @@ +How to customise this template +============================== + +#. Rename the `related-packages/fileformats/CHANGEME` directory to the name of the fileformats subpackage (e.g. `medimage_fsl`) +#. Search and replace "CHANGEME" with the name of the fileformats subpackage the extras are to be added +#. Replace name + email placeholders in `pyproject.toml` for developers and maintainers +#. Add the extension file-format classes +#. Ensure that all the extension file-format classes are imported into the extras package root, i.e. `fileformats/CHANGEME` +#. Delete these instructions + +... + +FileFormats Extension - CHANGEME +==================================== +.. image:: https://github.com/nipype/pydra-CHANGEME/actions/workflows/ci-cd.yml/badge.svg + :target: https://github.com/nipype/pydra-CHANGEME/actions/workflows/ci-cd.yml + +This is the "CHANGEME" extension module for the +`fileformats `__ package + + +Quick Installation +------------------ + +This extension can be installed for Python 3 using *pip*:: + + $ pip3 install fileformats-CHANGEME + +This will install the core package and any other dependencies + +License +------- + +This work is licensed under a +`Creative Commons Attribution 4.0 International License `_ + +.. image:: https://i.creativecommons.org/l/by/4.0/88x31.png + :target: http://creativecommons.org/licenses/by/4.0/ + :alt: Creative Commons Attribution 4.0 International License diff --git a/related-packages/fileformats/fileformats/medimage_CHANGEME/__init__.py b/related-packages/fileformats/fileformats/medimage_CHANGEME/__init__.py new file mode 100644 index 0000000..8dee4bf --- /dev/null +++ b/related-packages/fileformats/fileformats/medimage_CHANGEME/__init__.py @@ -0,0 +1 @@ +from ._version import __version__ diff --git a/related-packages/fileformats/pyproject.toml b/related-packages/fileformats/pyproject.toml new file mode 100644 index 0000000..b070d1f --- /dev/null +++ b/related-packages/fileformats/pyproject.toml @@ -0,0 +1,84 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "fileformats-medimage-CHANGEME" +description = "Classes for representing different file formats in Python classes for use in type hinting in data workflows" +readme = "README.rst" +requires-python = ">=3.8" +dependencies = [ + "fileformats", + "fileformats-medimage" +] +license = {file = "LICENSE"} +authors = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +maintainers = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +keywords = [ + "file formats", + "data", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", +] +dynamic = ["version"] + +[project.optional-dependencies] +dev = [ + "black", + "pre-commit", + "codespell", + "flake8", + "flake8-pyproject", +] +test = [ + "pytest >=6.2.5", + "pytest-env>=0.6.2", + "pytest-cov>=2.12.1", + "codecov", + "fileformats-medimage-CHANGME-extras", +] + +[project.urls] +repository = "https://github.com/nipype/pydra-CHANGEME" + +[tool.hatch.version] +source = "vcs" +raw-options = { root = "../.." } + +[tool.hatch.build.hooks.vcs] +version-file = "fileformats/medimage_CHANGEME/_version.py" + +[tool.hatch.build.targets.wheel] +packages = ["fileformats"] + +[tool.black] +target-version = ['py38'] +exclude = "fileformats/medimage_CHANGEME/_version.py" + +[tool.codespell] +ignore-words = ".codespell-ignorewords" + +[tool.flake8] +doctests = true +per-file-ignores = [ + "__init__.py:F401" +] +max-line-length = 88 +select = "C,E,F,W,B,B950" +extend-ignore = ['E203', 'E501', 'E129'] diff --git a/tools/rename_template.py b/tools/rename_template.py new file mode 100755 index 0000000..ef1889c --- /dev/null +++ b/tools/rename_template.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +import sys +import os +import re +import fnmatch +import functools +from pathlib import Path + +PACKAGE_ROOT = Path(__file__).absolute().parent.parent + + +@functools.lru_cache() +def load_gitignore(repo): + gitignore = repo / ".gitignore" + ignore = [fnmatch.translate(".git/"), fnmatch.translate(Path(__file__).name)] + if gitignore.exists(): + ignore.extend( + fnmatch.translate(line.strip()) + for line in gitignore.read_text().splitlines() + if line.strip() and not line[0] == "#" + ) + return re.compile("|".join(ignore)) + + +cmd, new_name, *_ = sys.argv + +for root, dirs, files in os.walk(PACKAGE_ROOT): + ignore = load_gitignore(PACKAGE_ROOT).search + for d in [d for d in dirs if ignore(f"{d}/")]: + dirs.remove(d) + for f in [f for f in files if ignore(f)]: + files.remove(f) + + root = Path(root) + for src in list(dirs): + if "CHANGEME" in src: + dst = src.replace("CHANGEME", new_name) + print(f"Renaming: {root / src} -> {root / dst}") + os.rename(root / src, root / dst) + dirs.remove(src) + dirs.append(dst) + for fname in files: + f = root / fname + text = Path.read_text(root / fname) + if "CHANGEME" in text: + print(f"Rewriting: {root / fname}") + Path.write_text(root / fname, text.replace("CHANGEME", new_name))