diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..ac2768b --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,258 @@ +# This CI setup provides a largely homogeneous configuration across all +# major platforms (Windows, MacOS, and Linux). The aim of this test setup is +# to create a "native" platform experience, using as few cross-platform +# helper tools as possible. +# +# On all platforms `hatch` is used for testing, and managing the test +# environment. This yields a near-identical environment/behavior across +# platforms and Python versions. The main difference between running tests +# on Appveyor and locally should be the service setup (e.g., SSH, HTTPBIN). +# +# All workers support remote login. Login details are shown at the top of each +# CI run log. +# +# - Linux/Mac workers (via SSH): +# +# - A permitted SSH key must be defined in an APPVEYOR_SSH_KEY environment +# variable (via the appveyor project settings) +# +# - SSH login info is given in the form of: 'appveyor@67.225.164.xx -p 22xxx' +# +# - Login with: +# +# ssh -o StrictHostKeyChecking=no +# +# - to prevent the CI run from exiting, `touch` a file named `BLOCK` in the +# user HOME directory (current directory directly after login). The session +# will run until the file is removed (or 60 min have passed) +# +# - Windows workers (via RDP): +# +# - An RDP password should be defined in an APPVEYOR_RDP_PASSWORD environment +# variable (via the appveyor project settings), or a random password is used +# every time +# +# - RDP login info is given in the form of IP:PORT +# +# - Login with: +# +# xfreerdp /cert:ignore /dynamic-resolution /u:appveyor /p: /v: +# +# - to prevent the CI run from exiting, create a textfile named `BLOCK` on the +# Desktop (a required .txt extension will be added automatically). The session +# will run until the file is removed (or 60 min have passed) +# + +# do not make repository clone cheap: interfers with VCS-based version determination +shallow_clone: false + +# turn of support for MS project build support (not needed) +build: off + +environment: + # place coverage files to a known location regardless of where a test run + # is happening + COVERAGE_ROOT: /home/appveyor/DLTMP + # we pin hatch's data file to make it easy to cache it + HATCH_DATA_DIR: /home/appveyor/hatch-data-dir + # same for pip + PIP_CACHE: /home/appveyor/.cache/pip + # Do not use `image` as a matrix dimension, to have fine-grained control over + # what tests run on which platform + # The ID variable had no impact, but sorts first in the CI run overview + # an intelligible name can help to locate a specific test run + matrix: + # List a CI run for each platform first, to have immediate access when there + # is a need for debugging + + # Ubuntu core tests + - job_name: test-linux + APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 + PY: 3.9 + INSTALL_GITANNEX: git-annex -m snapshot + + # same as 'test-linux', but TMPDIR is on a crippled filesystem, causing + # most, if not all test datasets to be created on that filesystem + - job_name: test-linux-crippled + APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204 + PY: 3.9 + # datalad-annex git remote needs something after git-annex_8.20211x + INSTALL_GITANNEX: git-annex -m snapshot + + # Windows core tests + - job_name: test-win + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 + # Python version specification is non-standard on windows + PY: 3.12 + INSTALL_GITANNEX: git-annex -m datalad/packages + COVERAGE_ROOT: C:\DLTMP + HATCH_DATA_DIR: C:\hatch-data-dir + PIP_CACHE: C:\Users\appveyor\AppData\Local\pip\Cache + + # MacOS core tests + - job_name: test-mac + APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma + PY: 3.12 + INSTALL_GITANNEX: git-annex + COVERAGE_ROOT: /Users/appveyor/DLTMP + HATCH_DATA_DIR: /Users/appveyor/hatch-data-dir + PIP_CACHE: /Users/appveyor/.cache/pip + + +# only run the CI if there are code or tooling changes +only_commits: + files: + - datalad_remake/ + - tools/ + - pyproject.toml + - .appveyor.yml + + +## tests need specific hostnames to be available +## note, this is insufficient on MacOS, and needs to be reflected +## in the SSH config too +#hosts: +# datalad-test-sshd: 127.0.0.1 +# # same, but for datalad-remake implementations +# datalad-test: 127.0.0.1 + + +# job-specific configurations +for: + # + # POSIX TEST RUNS + # + - matrix: + only: + - job_name: test-linux + - job_name: test-linux-crippled + - job_name: test-mac + + cache: + # pip cache + - "${PIP_CACHE} -> .appveyor.yml" + # hatch-managed python versions + - "${HATCH_DATA_DIR}/env/virtual/.pythons -> pyproject.toml" + + # init cannot use any components from the repo, because it runs prior to + # cloning it + init: + # enable external SSH access to CI worker + # needs APPVEYOR_SSH_KEY defined in project settings (or environment) + - curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e - + # Scratch space + # we place the "unix" one into the user's HOME to avoid git-annex issues on MacOSX + # gh-5291 + - mkdir ~/DLTMP && export TMPDIR=~/DLTMP + + install: + # verify that a PY variable is declared that identifies the desired Python version + # for this run + - "[ \"x$PY\" != x ]" + # Missing system software + - tools/appveyor/install-syspkgs $INSTALL_SYSPKGS + # activate Python env solely to get `python` to become available consistently + # hatch will manage the actual testing environment + - '. ${HOME}/venv${PY}/bin/activate' + - tools/appveyor/install-git-annex ${INSTALL_GITANNEX} + # enable the git-annex provisioned by the installer + - "[ -f ${HOME}/dlinstaller_env.sh ] && . ${HOME}/dlinstaller_env.sh || true" + test_script: + # store original TMPDIR setting to limit modification to test execution + - export PREV_TMPDIR=$TMPDIR + # make TMPDIR a "crippled filesystem" to test wrong assumptions of POSIX-ness + # on POSIX OSes. The test fixtures will create all test datasets under TMPDIR + - | + set -e + if [ "$APPVEYOR_JOB_NAME" = "test-linux-crippled" ]; then + # 100 MB VFAT FS in a box + sudo dd if=/dev/zero of=/crippledfs.img count=100 bs=1M + sudo mkfs.vfat /crippledfs.img + sudo mkdir /crippledfs + sudo mount -o "uid=$(id -u),gid=$(id -g)" /crippledfs.img /crippledfs + echo "== mount >>" + mount | grep crippled + echo "<< mount ==" + export TMPDIR=/crippledfs + fi + - echo TMPDIR=$TMPDIR + - 'hatch run tests.py${PY}:run-cov --doctest-modules --durations 10' + + after_test: + - 'hatch run tests.py${PY}:cov-combine' + - 'hatch run tests.py${PY}:coverage xml' + - 'codecovcli --auto-load-params-from AppVeyor upload-process -n "appveyor-$APPVEYOR_JOB_NAME" --disable-search -f coverage.xml' + + on_finish: + # conditionally block the exit of a CI run for direct debugging + - while [ -f ~/BLOCK ]; do sleep 5; done + + + # + # WINDOWS TEST RUNS + # + - matrix: + only: + - job_name: test-win + cache: + # pip cache + - "%PIP_CACHE% -> .appveyor.yml" + # hatch-managed python versions + - "%HATCH_DATA_DIR%\\env\\virtual\\.pythons -> pyproject.toml" + + # init cannot use any components from the repo, because it runs prior to + # cloning it + init: + # remove windows 260-char limit on path names + - ps: Set-Itemproperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name LongPathsEnabled -value 1 + # enable developer mode on windows + # this should enable mklink without admin privileges, but it doesn't seem to work + #- ps: tools\ci\appveyor_enable_windevmode.ps1 + # enable RDP access on windows (RDP password is in appveyor project config) + # this is relatively expensive (1-2min), but very convenient to jump into any build at any time + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + # Scratch space + - cmd: md C:\DLTMP + # and use that scratch space to get short paths in test repos + # (avoiding length-limits as much as possible) + - cmd: "set TMP=C:\\DLTMP" + - cmd: "set TEMP=C:\\DLTMP" + + install: + # place a debug setup helper at a convenient location + - cmd: copy tools\appveyor\env_setup.bat C:\\datalad_debug.bat + - cmd: "set PATH=C:\\Python%PY%;C:\\Python%PY%\\Scripts;%PATH%" + # deploy the datalad installer, override version via DATALAD_INSTALLER_VERSION + - cmd: + IF DEFINED DATALAD_INSTALLER_VERSION ( + python -m pip install "datalad-installer%DATALAD_INSTALLER_VERSION%" + ) ELSE ( + python -m pip install datalad-installer + ) + # Install git-annex on windows, otherwise INSTALL_SYSPKGS can be used + # deploy git-annex, if desired + - cmd: IF DEFINED INSTALL_GITANNEX datalad-installer --sudo ok %INSTALL_GITANNEX% + + test_script: + - cmd: 'hatch run tests.py%PY%:run-cov --doctest-modules --durations 10' + + after_test: + - cmd: 'hatch run tests.py%PY%:cov-combine' + - cmd: 'hatch run tests.py%PY%:coverage xml' + - cmd: 'codecovcli --auto-load-params-from AppVeyor upload-process -n "appveyor-%APPVEYOR_JOB_NAME%" --disable-search -f coverage.xml' + + on_finish: + # conditionally block the exit of a CI run for direct debugging + - ps: while ((Test-Path "C:\Users\\appveyor\\Desktop\\BLOCK.txt")) { Start-Sleep 5 } + + +# +# ALL TEST RUNS +# +build_script: + - python -m pip install hatch codecov-cli + +after_build: + # Identity setup + - git config --global user.email "test@appveyor.land" + - git config --global user.name "Appveyor Almighty" diff --git a/.changelog.md.j2 b/.changelog.md.j2 new file mode 100644 index 0000000..8c53229 --- /dev/null +++ b/.changelog.md.j2 @@ -0,0 +1,39 @@ +{% for entry in tree %} + +# {{ entry.version }}{% if entry.date %} ({{ entry.date }}){% endif %} + +{% for change_key, changes in entry.changes.items() %} + +{% set change_key_map = { + 'BREAKING CHANGE': '🪓 Breaking changes', + 'doc': '📝 Documentation', + 'feat': '💫 New features', + 'fix': '🐛 Bug Fixes', + 'test': '🛡 Tests', + 'rf': '🏠 Refactorings', + 'perf': '🚀 Performance improvements', +} %} +{% if change_key %} +## {{ change_key_map.get(change_key, change_key) }} +{% endif %} +{% set scopemap = { + 'changelog': 'Changelog', + 'contributing': 'Contributing guide', + 'helpers': 'Helpers', + 'sphinx': 'Rendered documentation', + 'typeannotation': 'Type annotation', +} %} + +{# no-scope changes #} +{% for change in changes | rejectattr("scope") %} +- {{ change.message }} [[{{ change.sha1 | truncate(8, true, '') }}]](https://github.com/datalad/datalad-remake/commit/{{ change.sha1 | truncate(8, true, '') }}) +{% endfor %} +{# scoped changes #} +{% for scope, scope_changes in changes | selectattr("scope") | groupby("scope") %} +- {{ scopemap.get(scope, scope) }}: +{% for change in scope_changes %} + - {{ change.message }} [[{{ change.sha1 | truncate(8, true, '') }}]](https://github.com/datalad/datalad-remake/commit/{{ change.sha1 | truncate(8, true, '') }}) +{% endfor %} +{% endfor %} +{% endfor %} +{% endfor %} diff --git a/.github/workflows/conventional-commits.yml b/.github/workflows/conventional-commits.yml new file mode 100644 index 0000000..8c86ddc --- /dev/null +++ b/.github/workflows/conventional-commits.yml @@ -0,0 +1,23 @@ +name: Conventional commits + +on: pull_request + +jobs: + check-messages: + runs-on: ubuntu-latest + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: 3.11 + architecture: x64 + - name: Checkout + uses: actions/checkout@v4 + with: + # we need all the history to be able to resolve revision ranges properly + fetch-depth: 0 + - name: Install commitizen + run: python -m pip install commitizen + - name: Run commit message checks + run: | + cz check --rev-range ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/mypy-pr.yml b/.github/workflows/mypy-pr.yml new file mode 100644 index 0000000..a49660d --- /dev/null +++ b/.github/workflows/mypy-pr.yml @@ -0,0 +1,41 @@ +name: Type annotation (PR) + +on: + pull_request: + paths: + - 'datalad_remake/**.py' + - '!**/tests/**.py' + +jobs: + check-types-pr: + runs-on: ubuntu-latest + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + # run on a "fresh" python, but see mypy flag to check for the oldest supported version + python-version: 3.12 + architecture: x64 + - name: Checkout + uses: actions/checkout@v4 + - name: Install hatch (which pull mypy) + run: python -m pip install hatch + - name: Get Python changed files + id: changed-py-files + uses: tj-actions/changed-files@v44 + with: + files: | + *.py + **/*.py + - name: Type check changed files + if: steps.changed-py-files.outputs.any_changed == 'true' + run: | + # get any type stubs that mypy thinks it needs + hatch run types:mypy --install-types --non-interactive --follow-imports skip ${{ steps.changed-py-files.outputs.all_changed_files }} + # run mypy on the modified files only, and do not even follow imports. + # this results is a fairly superficial test, but given the overall + # state of annotations, we strive to become more correct incrementally + # with focused error reports, rather than barfing a huge complaint + # that is unrelated to the changeset someone has been working on. + # run on the oldest supported Python version + hatch run types:mypy --python-version 3.9 --follow-imports skip --pretty --show-error-context ${{ steps.changed-py-files.outputs.all_changed_files }} diff --git a/.github/workflows/mypy-project.yml b/.github/workflows/mypy-project.yml new file mode 100644 index 0000000..3a1bb1b --- /dev/null +++ b/.github/workflows/mypy-project.yml @@ -0,0 +1,29 @@ +name: Type annotation (project) + +on: + push: + paths: + - 'datalad_remake/**.py' + - '!**/tests/**.py' + +jobs: + check-types-project: + runs-on: ubuntu-latest + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + # run on a "fresh" python, but see mypy flag to check for the oldest supported version + python-version: 3.12 + architecture: x64 + - name: Checkout + uses: actions/checkout@v4 + - name: Install hatch (which pull mypy) + run: python -m pip install hatch + - name: Type check project + run: | + # get any type stubs that mypy thinks it needs + hatch run types:mypy --install-types --non-interactive --follow-imports skip datalad_core + # run mypy on the full project. + # run on the oldest supported Python version + hatch run types:mypy --python-version 3.9 --pretty --show-error-context datalad_core diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml new file mode 100644 index 0000000..6112f5a --- /dev/null +++ b/.github/workflows/ruff.yml @@ -0,0 +1,17 @@ +name: Static code check +on: [push, pull_request] +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + # run on a "fresh" python + python-version: 3.12 + - name: Checkout + uses: actions/checkout@v4 + - name: Install hatch + run: python -m pip install hatch + - name: Check code + run: hatch fmt --check diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ff447c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +datalad_remake/_version.py +dist/ +.coverage +docs/generated +docs/_build +*.swp diff --git a/.noannex b/.noannex new file mode 100644 index 0000000..e69de29 diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..9dbc5a3 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,33 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - method: pip + path: . diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ae20bcd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# v0.0.0 + +- Initial package setup without any functionality. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2f797c9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,139 @@ +# Contributing to `datalad-remake` + +- [Developer cheat sheet](#developer-cheat-sheet) +- [Code organization](#code-organization) +- [Style guide](#contribution-style-guide) + + +## Developer cheat sheet + +[Hatch](https://hatch.pypa.io) is used as a convenience solution for packaging and development tasks. +Hatch takes care of managing dependencies and environments, including the Python interpreter itself. +If not installed yet, installing via [pipx](https://github.com/pypa/pipx) is recommended (`pipx install hatch`). + +Below is a list of some provided convenience commands. +An accurate overview of provided convenience scripts can be obtained by running: `hatch env show`. +All command setup can be found in `pyproject.toml`, and given alternatively managed dependencies, all commands can also be used without `hatch`. + +### Run the tests (with coverage reporting) + +``` +hatch test [--cover] +``` + +There is also a setup for matrix test runs, covering all current Python versions: + +``` +hatch run tests:run [] +``` + +### Build the HTML documentation (under `docs/_build/html`) + +``` +hatch run docs:build +# clean with +hatch run docs:clean +``` + +### Check type annotations + +``` +hatch run types:check +``` + +### Check commit messages for compliance with [Conventional Commits](https://www.conventionalcommits.org) + +``` +hatch run cz:check-commits +``` + +### Show would-be auto-generated changelog for the next release + +``` +hatch run cz:show-changelog +``` + +### Create a new release + +``` +hatch run cz:bump-version +``` + +The new version is determined automatically from the nature of the (conventional) commits made since the last release. +A changelog is generated and committed. + +In cases where the generated changelog needs to be edited afterwards (typos, unnecessary complexity, etc.), the created version tag needs to be advanced. + + +### Build a new source package and wheel + +``` +hatch build +``` + +### Publish a new release to PyPi + +``` +hatch publish +``` + +## Contribution style guide + +A contribution must be complete with code, tests, and documentation. + +A high test-coverage is desirable. Contributors should aim for near-complete coverage (or better). +Tests must be dedicated for the code of a particular contribution. +It is not sufficient, if other code happens to also exercise a new feature. + +### Documentation + +Docstrings should be complete with information on parameters, return values, and exception behavior. +Documentation should be added to and rendered with the sphinx-based documentation. + +### Commits + +Commits and commit messages must be [Conventional Commits](https://www.conventionalcommits.org). +Their compliance is checked for each pull request. The following commit types are recognized: + +- `feat`: introduces a new feature +- `fix`: address a problem, fix a bug +- `doc`: update the documentation +- `rf`: refactor code with no change of functionality +- `perf`: enhance performance of existing functionality +- `test`: add/update/modify test implementations +- `ci`: change CI setup +- `style`: beautification +- `chore`: results of routine tasks, such as changelog updates +- `revert`: revert a previous change +- `bump`: version update + +Any breaking change must have at least one line of the format + + BREAKING CHANGE: + +in the body of the commit message that introduces the breakage. +Breaking changes can be introduced in any type of commit. +Any number of breaking changes can be described in a commit message (one per line). +Breaking changes trigger a major version update, and form a dedicated section in the changelog. + +It is recommended to use the `hatch run cz:show-changelog` command to see how a change series will be represented in the changelog -- and tune as necessary to achieve a self-explanatory outcome. + +### Pull requests + +Contributions submitted via a pull-request (PR), are expected to be a clear, self-describing series of commits. +The PR description is largely irrelevant, and could be used for a TODO list, or conversational content. +All essential information concerning the code and changes **must** be contained in the commit messages. + +Commit series should be "linear", with individual commits being self-contained, well-described changes. + +If possible, only loosely related changes should be submitted in separate PRs to simplify reviewing and shorten time-to-merge. + +Long-standing, inactive PRs (draft mode or not) are frowned upon, as they drain attention.i +It is often better to close a PR and open a new one, once work resumes. +Maintainers may close inactive PRs for this reason at any time. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2b19e6e --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +datalad-remake, including all examples, code snippets and attached +documentation is covered by the MIT license. + + The MIT License + + Copyright (c) 2024- DataLad Team + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..18ba105 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# datalad-remake + +[![Documentation Status](https://readthedocs.org/projects/datalad-remake/badge/?version=latest)](https://datalad-remake.readthedocs.io/en/latest/?badge=latest) +[![Build status](https://ci.appveyor.com/api/projects/status/25vbds4nncadopf8/branch/main?svg=true)](https://ci.appveyor.com/project/mih/datalad-remake/branch/main) diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..d86d75c --- /dev/null +++ b/conftest.py @@ -0,0 +1,8 @@ +# we are not using datalad's directly, because we are practically +# requiring whatever setup datalad_next prefers, because we employ +# its tooling +from datalad_next.conftest import setup_package + +pytest_plugins = 'datalad_next.tests.fixtures' + +__all__ = ['setup_package'] diff --git a/datalad_remake/__init__.py b/datalad_remake/__init__.py new file mode 100644 index 0000000..3ac1200 --- /dev/null +++ b/datalad_remake/__init__.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from datalad_remake._version import __version__ + +__all__ = [ + '__version__', +] + +# command_suite = ( +# # description of the command suite, displayed in cmdline help +# "Demo DataLad command suite", +# [ +# # specification of a command, any number of commands can be defined +# ( +# # importable module that contains the command implementation +# 'datalad_remake.commands.compute_cmd', +# # name of the command class implementation in above module +# 'Compute', +# # optional name of the command in the cmdline API +# 'compute', +# # optional name of the command in the Python API +# 'compute' +# ), +# ] +# ) diff --git a/datalad_remake/tests/__init__.py b/datalad_remake/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/datalad_remake/tests/test_dummy.py b/datalad_remake/tests/test_dummy.py new file mode 100644 index 0000000..ebdfde4 --- /dev/null +++ b/datalad_remake/tests/test_dummy.py @@ -0,0 +1,6 @@ +import datalad_remake # noqa: F401 + + +def test_dummy(): + # nothing but a placeholder + pass diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..9719ae4 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +_build +generated 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/_static/.gitkeep b/docs/_static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..bba215a --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,30 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'datalad-remake' +copyright = '2024, DataLad team' +author = 'DataLad team' +release = 'v0.0.1-rc' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx.ext.autosummary', +] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..b5501bc --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,21 @@ +The `datalad-remake` documentation +================================== + +Package overview +---------------- + +Also see the :ref:`modindex`. + +.. currentmodule:: datalad_remake +.. + .. autosummary:: + :toctree: generated + + ... + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..caa7f0f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,206 @@ +[build-system] +requires = [ + "hatchling", + "hatch-vcs", +] +build-backend = "hatchling.build" + +[project] +name = "datalad-remake" +dynamic = ["version"] +description = '' +readme = "README.md" +requires-python = ">=3.9" +license = "MIT" +keywords = [ + "datalad", + "git", + "git-annex", +] +authors = [ +# { name = "Michael Hanke", email = "michael.hanke@gmail.com" }, +] +maintainers = [ +# { name = "Michael Hanke", email = "michael.hanke@gmail.com" }, +] +classifiers = [ + "License :: OSI Approved :: MIT License", + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: End Users/Desktop", + "Natural Language :: English", + "Operating System :: OS Independent", + "Topic :: Software Development", + "Topic :: Software Development :: Version Control", + "Topic :: Software Development :: Version Control :: Git", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dependencies = [ + "datalad_next", +] + +[project.urls] +Homepage = "https://github.com/datalad/datalad-remake" +Documentation = "https://github.com/datalad/datalad-remake#readme" +Issues = "https://github.com/datalad/datalad-remake/issues" +Source = "https://github.com/datalad/datalad-remake" +Changelog = "https://github.com/datalad/datalad-remake/blob/main/CHANGELOG.md" + +[tool.hatch.version] +source = "vcs" + +[tool.hatch.build.hooks.vcs] +version-file = "datalad_remake/_version.py" + +[tool.hatch.envs.hatch-test] +default-args = ["datalad_remake"] +extra-dependencies = [ + "pytest", + # if you come here, because coverage combination crashed for you + # run `hatch test --cover` and/or see + # https://github.com/pypa/hatch/issues/1565#issuecomment-2163773123 + "pytest-cov", +] + + +[tool.hatch.envs.tests] +description = "run tests across Python versions" +template = "hatch-test" + +[[tool.hatch.envs.tests.matrix]] +python = ["3.9", "3.10", "3.11", "3.12"] + +[tool.hatch.envs.tests.scripts] +run = 'python -m pytest {args}' + +[tool.hatch.envs.types] +description = "type checking with MyPy" +extra-dependencies = [ + "mypy>=1.0.0", + "pytest", +] +[tool.hatch.envs.types.scripts] +check = [ + "mypy --install-types --non-interactive --python-version 3.9 --pretty --show-error-context datalad_remake", +] + +[tool.hatch.envs.docs] +description = "build Sphinx-based docs" +extra-dependencies = [ + "sphinx", +] +[tool.hatch.envs.docs.scripts] +build = [ + "make -C docs html", +] +clean = [ + "rm -rf docs/generated", + "make -C docs clean", +] + +[tool.hatch.envs.cz] +description = "commit compliance, changelog, and release generation" +detached = true +extra-dependencies = [ + "commitizen", +] +[tool.hatch.envs.cz.scripts] +check-commits = [ + # check all commit messages since the (before) beginning + "cz check --rev-range 4b825dc642cb6eb9a060e54bf8d69288fbee4904..HEAD", +] +show-changelog = [ + # show the would-be changelog on stdout + "cz changelog --dry-run", +] +bump-version = [ + # bump version (also tags) and update changelog + "cz bump --changelog", +] + +[tool.hatch.envs.codespell] +description = "spell checking" +detached = true +extra-dependencies = [ + "codespell", +] +[tool.hatch.envs.codespell.scripts] +check = "codespell" +fix = "codespell --write-changes" + +[tool.codespell] +skip = ".git,build,.*cache,dist" + +[tool.coverage.run] +source_pkgs = ["datalad_remake", "tests"] +branch = true +parallel = true +omit = [ +# "src/datalad_remake/__about__.py", +] +data_file = "${COVERAGE_ROOT-.}/.coverage" + +[tool.coverage.paths] +datalad_remake = ["src/datalad_remake", "*/datalad_remake/src/datalad_remake"] +tests = ["tests", "*/datalad_remake/tests"] + +[tool.coverage.report] +show_missing = true +exclude_lines = [ + "no cov", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", + "raise NotImplementedError", +] + +[tool.ruff] +exclude = [ + # sphinx + "docs", +] +line-length = 88 +indent-width = 4 +target-version = "py39" +[tool.ruff.format] +# Prefer single quotes over double quotes. +quote-style = "single" +[tool.ruff.lint.per-file-ignores] +"**/test_*" = [ + # permit assert statements in tests + "S101", + # permit relative import in tests + "TID252", + # permit versatile function names in tests + "N802", +] +# permit relative import in subpackage root +"datalad_remake/*/__init__.py" = ["TID252"] + +[tool.commitizen] +name = "cz_customize" +tag_format = "v$version" +version_scheme = "pep440" +version_provider = "scm" +changelog_incremental = true +template = ".changelog.md.j2" +gpg_sign = true + +[tool.commitizen.customize] +commit_parser = "^((?Pfeat|fix|rf|perf|test|doc|BREAKING CHANGE)(?:\\((?P[^()\r\n]*)\\)|\\()?(?P!)?|\\w+!):\\s(?P.*)?(?P.*)?" +change_type_order = ["BREAKING CHANGE", "feat", "fix", "rf", "perf", "doc", "test"] +changelog_pattern = "^((BREAKING[\\-\\ ]CHANGE|\\w+)(\\(.+\\))?!?):" +bump_pattern = "^((BREAKING[\\-\\ ]CHANGE|\\w+)(\\(.+\\))?!?):" +schema_pattern = "(?s)(ci|doc|feat|fix|perf|rf|style|test|chore|revert|bump)(\\(\\S+\\))?!?:( [^\\n\\r]+)((\\n\\n.*)|(\\s*))?$" + +[tool.commitizen.customize.bump_map] +"^\\w+!" = "MAJOR" +"^BREAKING" = "MAJOR" +"^feat" = "MINOR" +"^fix" = "PATCH" diff --git a/tools/appveyor/env_setup.bat b/tools/appveyor/env_setup.bat new file mode 100644 index 0000000..d464901 --- /dev/null +++ b/tools/appveyor/env_setup.bat @@ -0,0 +1,4 @@ +set PY=%1-x64 +set TMP=C:\DLTMP +set TEMP=C:\DLTMP +set PATH=C:\Python%PY%;C:\Python%PY%\Scripts;%PATH% diff --git a/tools/appveyor/install-git-annex b/tools/appveyor/install-git-annex new file mode 100755 index 0000000..6840c39 --- /dev/null +++ b/tools/appveyor/install-git-annex @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Install git-annex. Any environment setup to source would be +# written to ${HOME}/dlinstaller_env.sh +# +set -e -u + +# no install requested -> exit +[ -z "$1" ] && exit 0 || true + +# assumes a virtualenv or equivalent python env +# get the installer for this +python -m pip install datalad-installer${DATALAD_INSTALLER_VERSION:-} +datalad-installer -E ${HOME}/dlinstaller_env.sh --sudo ok $* diff --git a/tools/appveyor/install-syspkgs b/tools/appveyor/install-syspkgs new file mode 100755 index 0000000..bfb84a9 --- /dev/null +++ b/tools/appveyor/install-syspkgs @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# no install requested -> exit +[ -z "$1" ] && exit 0 || true + +if (which apt-get > /dev/null ); then + sudo apt-get update -qq -y --allow-releaseinfo-change + sudo apt-get install -q --no-install-recommends -y eatmydata + sudo eatmydata apt-get install -q --no-install-recommends -y $* +else + brew install -q $* +fi