Holger Frey
1 year ago
commit
ebf2864e61
17 changed files with 688 additions and 0 deletions
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
# ---> Python |
||||
# Byte-compiled / optimized / DLL files |
||||
__pycache__/ |
||||
*.py[cod] |
||||
*$py.class |
||||
|
||||
# C extensions |
||||
*.so |
||||
|
||||
# Distribution / packaging |
||||
.Python |
||||
.venv |
||||
env/ |
||||
build/ |
||||
develop-eggs/ |
||||
dist/ |
||||
downloads/ |
||||
eggs/ |
||||
.eggs/ |
||||
lib/ |
||||
lib64/ |
||||
parts/ |
||||
sdist/ |
||||
var/ |
||||
*.egg-info/ |
||||
.installed.cfg |
||||
*.egg |
||||
|
||||
# PyInstaller |
||||
# Usually these files are written by a python script from a template |
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||
*.manifest |
||||
*.spec |
||||
|
||||
# Installer logs |
||||
pip-log.txt |
||||
pip-delete-this-directory.txt |
||||
|
||||
# Unit test / coverage reports |
||||
htmlcov/ |
||||
.nox/ |
||||
.tox/ |
||||
.coverage |
||||
.coverage.* |
||||
.cache |
||||
nosetests.xml |
||||
coverage.xml |
||||
*,cover |
||||
|
||||
# Translations |
||||
*.mo |
||||
*.pot |
||||
|
||||
# Django stuff: |
||||
*.log |
||||
|
||||
# Sphinx documentation |
||||
docs/_build/ |
||||
|
||||
# PyBuilder |
||||
target/ |
||||
|
||||
# Mac Stuff |
||||
.DS_Store |
||||
|
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
repos: |
||||
- repo: https://github.com/pre-commit/pre-commit-hooks |
||||
rev: v2.4.0 |
||||
hooks: |
||||
- id: check-added-large-files |
||||
- id: check-byte-order-marker |
||||
- id: check-json |
||||
- id: check-merge-conflict |
||||
- id: check-toml |
||||
- id: debug-statements |
||||
- id: detect-private-key |
||||
- repo: local |
||||
hooks: |
||||
- id: black |
||||
name: Auto formatting code with "black" |
||||
entry: black src tests |
||||
language: system |
||||
pass_filenames: false |
||||
- id: ruff |
||||
name: Linting code with "ruff" |
||||
entry: ruff src tests |
||||
language: system |
||||
pass_filenames: false |
||||
- id: pytest |
||||
name: Running tests with "pytest" |
||||
entry: pytest tests |
||||
language: system |
||||
pass_filenames: false |
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
0.0.1 - first version |
||||
---------------------- |
||||
|
||||
- setting up the project |
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
Contributing |
||||
============ |
||||
|
||||
Contributions are welcome, and they are greatly appreciated! Every little bit |
||||
helps, and credit will always be given. |
||||
|
||||
You can contribute in many ways: |
||||
|
||||
Types of Contributions |
||||
---------------------- |
||||
|
||||
### Report Bugs |
||||
|
||||
Report bugs at https://git.cpi.imtek.uni-freiburg.de/holgi/conda_helpers.git/issues. |
||||
|
||||
If you are reporting a bug, please include: |
||||
|
||||
* Your operating system name and version. |
||||
* Any details about your local setup that might be helpful in troubleshooting. |
||||
* Detailed steps to reproduce the bug. |
||||
|
||||
### Fix Bugs |
||||
|
||||
Look through the GitHub issues for bugs. Anything tagged with "bug" and "help |
||||
wanted" is open to whoever wants to implement it. |
||||
|
||||
### Implement Features |
||||
|
||||
Look through the GitHub issues for features. Anything tagged with "enhancement" |
||||
and "help wanted" is open to whoever wants to implement it. |
||||
|
||||
### Write Documentation |
||||
|
||||
conda helpers could always use more documentation, whether as part of the |
||||
official conda helpers docs, in docstrings, or even on the web in blog posts, |
||||
articles, and such. |
||||
|
||||
### Submit Feedback |
||||
|
||||
The best way to send feedback is to file an issue at https://git.cpi.imtek.uni-freiburg.de/holgi/conda_helpers.git/issues. |
||||
|
||||
If you are proposing a feature: |
||||
|
||||
* Explain in detail how it would work. |
||||
* Keep the scope as narrow as possible, to make it easier to implement. |
||||
* Remember that this is a volunteer-driven project, and that contributions |
||||
are welcome :) |
||||
|
||||
Get Started! |
||||
------------ |
||||
|
||||
Ready to contribute? Here's how to set up `conda_helpers` for local development. |
||||
|
||||
1. Fork the `conda_helpers` repo on GitHub. |
||||
2. Clone your fork locally:: |
||||
|
||||
`$ git clone git@github.com:your_name_here/conda_helpers.git` |
||||
|
||||
3. Install your local copy into a virtualenv. |
||||
|
||||
`$ cd conda_helpers/` |
||||
`$ make devenv` |
||||
|
||||
4. Create a branch for local development:: |
||||
|
||||
`$ git checkout -b name-of-your-bugfix-or-feature` |
||||
|
||||
Now you can make your changes locally. |
||||
|
||||
5. When you're done making changes, check that your changes passes the linters and the |
||||
tests, including testing other Python versions with tox:: |
||||
|
||||
``` |
||||
$ make lint |
||||
$ make coverage |
||||
$ make tox |
||||
``` |
||||
|
||||
6. Commit your changes and push your branch to GitHub:: |
||||
|
||||
``` |
||||
$ git add . |
||||
$ git commit -m "Your detailed description of your changes." |
||||
$ git push origin name-of-your-bugfix-or-feature |
||||
``` |
||||
|
||||
7. Submit a pull request through the GitHub website. |
||||
|
||||
Pull Request Guidelines |
||||
----------------------- |
||||
|
||||
Before you submit a pull request, check that it meets these guidelines: |
||||
|
||||
1. The pull request should include tests. |
||||
2. If the pull request adds functionality, the docs should be updated. Put |
||||
your new functionality into a function with a docstring, and add the |
||||
feature to the list in README.md and CHANGES.md |
||||
|
||||
Tips |
||||
---- |
||||
|
||||
To run a quick set of tests without coverage report |
||||
|
||||
$ make test |
||||
|
||||
Deploying |
||||
--------- |
||||
|
||||
A reminder for the maintainers on how to deploy. |
||||
Bump the version in `conda_helpers/__init__.py` and |
||||
make sure all your changes are committed (including an entry in CHANGES.md). |
||||
|
||||
$ git tag <new version> |
||||
$ git push |
||||
$ git push --tags |
||||
$ flit publish |
||||
|
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
/* |
||||
* ---------------------------------------------------------------------------- |
||||
* "THE BEER-WARE LICENSE" (Revision 42): |
||||
* frey@imtek.de wrote this file. As long as you retain this notice you |
||||
* can do whatever you want with this stuff. If we meet some day, and you think |
||||
* this stuff is worth it, you can buy me a beer in return. Holger Frey |
||||
* ---------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
|
@ -0,0 +1,118 @@
@@ -0,0 +1,118 @@
|
||||
.PHONY: clean clean-build clean-docs clean-pyc clean-test coverage coverall devenv docs help install lint nox prepareenv repo serve-docs test testall testfunctional tox venvexists |
||||
.DEFAULT_GOAL := help |
||||
|
||||
define BROWSER_PYSCRIPT |
||||
import os, webbrowser, sys |
||||
|
||||
try: |
||||
from urllib import pathname2url |
||||
except: |
||||
from urllib.request import pathname2url |
||||
|
||||
webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) |
||||
endef |
||||
export BROWSER_PYSCRIPT |
||||
|
||||
define PRINT_HELP_PYSCRIPT |
||||
import re, sys |
||||
|
||||
for line in sys.stdin: |
||||
match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) |
||||
if match: |
||||
target, help = match.groups() |
||||
print("%-20s %s" % (target, help)) |
||||
endef |
||||
export PRINT_HELP_PYSCRIPT |
||||
|
||||
BROWSER := python -c "$$BROWSER_PYSCRIPT" |
||||
|
||||
help: |
||||
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) |
||||
|
||||
|
||||
venvexists: ## helper to check if a virtual environment exists
|
||||
@test -x .venv/bin/python || { echo "No virtual environment found, please run 'make devenv'"; exit 1; } |
||||
|
||||
clean: clean-build clean-docs clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
|
||||
|
||||
clean-build: ## remove build artifacts
|
||||
rm -fr build/ |
||||
rm -fr dist/ |
||||
rm -fr .eggs/ |
||||
find . -name '*.egg-info' -exec rm -fr {} + |
||||
find . -name '*.egg' -exec rm -f {} + |
||||
|
||||
clean-docs: ## remove documentation artifacts
|
||||
rm -fr site/ |
||||
|
||||
clean-pyc: ## remove Python file artifacts
|
||||
find . -name '*.pyc' -exec rm -f {} + |
||||
find . -name '*.pyo' -exec rm -f {} + |
||||
find . -name '*~' -exec rm -f {} + |
||||
find . -name '__pycache__' -exec rm -fr {} + |
||||
|
||||
clean-test: ## remove test and coverage artifacts
|
||||
rm -fr .mypy_cache/ |
||||
rm -fr .pytest_cache/ |
||||
rm -fr .ruff_cache/ |
||||
rm -fr .nox/ |
||||
rm -fr .tox/ |
||||
rm -f .coverage |
||||
rm -fr htmlcov/ |
||||
|
||||
lint: venvexists ## reformat with black and check style with flake8
|
||||
.venv/bin/black src tests noxfile.py |
||||
.venv/bin/ruff src tests noxfile.py |
||||
|
||||
test: lint ## run tests quickly, stop on first error
|
||||
.venv/bin/pytest tests --stepwise --disable-warnings -m "not functional" |
||||
|
||||
testfunctional: lint ## run functional tests, stop on first error
|
||||
.venv/bin/pytest tests --stepwise -m "functional" |
||||
|
||||
testall: lint ## run all tests
|
||||
.venv/bin/pytest tests |
||||
|
||||
coverage: lint ## functional test suite, check code coverage and open coverage report
|
||||
.venv/bin/pytest tests --cov=conda_helpers --cov=tests -m "functional" |
||||
.venv/bin/coverage html |
||||
$(BROWSER) htmlcov/index.html |
||||
|
||||
coverall: lint ## full test suite, check code coverage and open coverage report
|
||||
.venv/bin/pytest tests --cov=conda_helpers --cov=tests |
||||
.venv/bin/coverage html |
||||
$(BROWSER) htmlcov/index.html |
||||
|
||||
nox: venvexists ## run fully isolated tests with nox
|
||||
.venv/bin/nox |
||||
|
||||
tox: venvexists ## old habits die hard: typo-squatting to use nox
|
||||
.venv/bin/nox |
||||
|
||||
docs: venvexists ## build the documentation using mkdocs
|
||||
.venv/bin/mkdocs build |
||||
|
||||
serve-docs: docs ## build the documentation and serve them in a web server
|
||||
.venv/bin/mkdocs serve |
||||
|
||||
install: venvexists ## install updated project.toml
|
||||
.venv/bin/pip3 install -e ".[dev,docs,test]" |
||||
|
||||
prepareenv: ## helper to create virtual environment and install basic packages
|
||||
rm -fr .venv/ |
||||
python3 -m venv --prompt conda_helpers .venv |
||||
.venv/bin/pip3 install --upgrade pip wheel |
||||
.venv/bin/pip3 install -e ".[dev,docs,test]" |
||||
|
||||
devenv: prepareenv ## setup development environment including precommit hooks
|
||||
.venv/bin/pre-commit install --install-hooks |
||||
|
||||
repo: prepareenv ## complete project setup with development environment and git repo
|
||||
git init . |
||||
git add . |
||||
git commit -m "import of project template" |
||||
git branch -m main |
||||
git remote add origin https://git.cpi.imtek.uni-freiburg.de/holgi/conda_helpers.git |
||||
git push -u origin main --no-verify |
||||
|
||||
.venv/bin/pre-commit install --install-hooks |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
conda helpers |
||||
============= |
||||
|
||||
Helpers for working with data frames in a conda environment |
||||
|
||||
## Example: |
||||
|
||||
```python |
||||
|
||||
import conda_helpers |
||||
|
||||
conda_helpers.run() |
||||
``` |
||||
|
||||
|
||||
## Development |
||||
|
||||
To install the development version of conda helpers: |
||||
|
||||
git clone https://git.cpi.imtek.uni-freiburg.de/holgi/conda_helpers.git |
||||
|
||||
# create a virtual environment and install all required dev dependencies |
||||
cd conda_helpers |
||||
make devenv |
||||
|
||||
To run the tests, use `make tests` or `make coverage` for a complete report. |
||||
|
||||
To generate the documentation pages use `make docs` or `make serve-docs` for |
||||
starting a webserver with the generated documentation |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
# Explanation |
||||
|
||||
This part of the project documentation focuses on a |
||||
**learning-oriented** approach. You'll learn how to |
||||
get started with the code in this project. |
||||
|
||||
> **Note:** Expand this section by considering the |
||||
> following points: |
||||
|
||||
- Help newcomers with getting started |
||||
- Teach readers about your library by making them |
||||
write code |
||||
- Inspire confidence through examples that work for |
||||
everyone, repeatably |
||||
- Give readers an immediate sense of achievement |
||||
- Show concrete examples, no abstractions |
||||
- Provide the minimum necessary explanation |
||||
- Avoid any distractions |
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
# How-To Guides |
||||
|
||||
This part of the project documentation focuses on a |
||||
**problem-oriented** approach. You'll tackle common |
||||
tasks that you might have, with the help of the code |
||||
provided in this project. |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
# conda helpers Documentation |
||||
|
||||
This site contains the project documentation for the |
||||
`conda_helpers` project. |
||||
|
||||
|
||||
## Table Of Contents |
||||
|
||||
The documentation follows the best practice for |
||||
project documentation as described by Daniele Procida |
||||
in the [Diátaxis documentation framework](https://diataxis.fr/) |
||||
and consists of four separate parts: |
||||
|
||||
1. [Tutorials](tutorials.md) |
||||
2. [How-To Guides](how-to-guides.md) |
||||
3. [Reference](reference.md) |
||||
4. [Explanation](explanation.md) |
||||
|
||||
Quickly find what you're looking for depending on |
||||
your use case by looking at the different pages. |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
# Reference |
||||
|
||||
This part of the project documentation focuses on |
||||
an **information-oriented** approach. Use it as a |
||||
reference for the technical implementation of the |
||||
` conda_helpers` project code. |
||||
|
||||
|
||||
::: conda_helpers |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
# Tutorials |
||||
|
||||
This part of the project documentation focuses on an |
||||
**understanding-oriented** approach. You'll get a |
||||
chance to read about the background of the project, |
||||
as well as reasoning about how it was implemented. |
||||
|
||||
> **Note:** Expand this section by considering the |
||||
> following points: |
||||
|
||||
- Give context and background on your library |
||||
- Explain why you created it |
||||
- Provide multiple examples and approaches of how |
||||
to work with it |
||||
- Help the reader make connections |
||||
- Avoid writing instructions or technical descriptions |
||||
here |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
site_name: conda helpers Docs |
||||
|
||||
nav: |
||||
- Introduction: index.md |
||||
- Tutorials: tutorials.md |
||||
- How-To Guides: how-to-guides.md |
||||
- Reference: reference.md |
||||
- Explanation: explanation.md |
||||
|
||||
repo_url: https://git.cpi.imtek.uni-freiburg.de/holgi/conda_helpers.git |
||||
|
||||
theme: |
||||
name: readthedocs |
||||
highlightjs: true |
||||
|
||||
plugins: |
||||
- mkdocstrings |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
import pathlib |
||||
import tempfile |
||||
import typing |
||||
|
||||
import nox |
||||
|
||||
|
||||
class RepoCache: |
||||
"""class for caching checkouts of downstream repos |
||||
|
||||
By caching the checkouts for downstream test runs, |
||||
the nox invokation is faster and there is less load |
||||
on the git server and network. |
||||
""" |
||||
|
||||
_checkouts: typing.ClassVar = {} |
||||
|
||||
@classmethod |
||||
def clone(cls, session: nox.Session, repo: str) -> str: |
||||
"""clones a git repo only once |
||||
|
||||
Arguments: |
||||
session: the nox session in use |
||||
repo: a git repo url |
||||
|
||||
Returns: |
||||
path to a temporary directory containing the |
||||
cloned git repo |
||||
""" |
||||
tmpdir = cls._checkouts.get(repo, None) |
||||
|
||||
if tmpdir is None: |
||||
tmpdir = tempfile.TemporaryDirectory() |
||||
session.run("git", "clone", repo, tmpdir.name, external=True) |
||||
cls._checkouts[repo] = tmpdir |
||||
|
||||
return tmpdir.name |
||||
|
||||
|
||||
@nox.session(python=["3.9", "3.10", "3.11"]) |
||||
def tests(session): |
||||
session.install(".[test]") |
||||
|
||||
session.run("pytest", *session.posargs) |
||||
|
||||
|
||||
@nox.session(python=["3.9", "3.10", "3.11"]) |
||||
@nox.parametrize( |
||||
"repo", |
||||
[ |
||||
"https://git.example.com/user/repo", |
||||
], |
||||
) |
||||
def downstream(session, repo): |
||||
tmpdir = RepoCache.clone(session, repo) |
||||
|
||||
session.install(".") |
||||
session.install(f"{tmpdir}[test]") |
||||
|
||||
test_path = pathlib.Path(tmpdir) / "tests" |
||||
session.run("pytest", test_path) |
@ -0,0 +1,118 @@
@@ -0,0 +1,118 @@
|
||||
|
||||
|
||||
[build-system] |
||||
requires = ["flit_core>=3.2,<4"] |
||||
build-backend = "flit_core.buildapi" |
||||
|
||||
[project] |
||||
name = "conda_helpers" |
||||
readme = "README.md" |
||||
license = { file = "LICENSE" } |
||||
requires-python = ">=3.9" |
||||
dynamic = ["version", "description"] |
||||
|
||||
authors = [ |
||||
{name = "Holger Frey", email = "frey@imtek.de"}, |
||||
] |
||||
|
||||
# see https://pypi.org/classifiers/ |
||||
classifiers = [ |
||||
"Development Status :: 2 - Pre-Alpha", |
||||
"Intended Audience :: Developers", |
||||
"Programming Language :: Python :: 3.8", |
||||
"Programming Language :: Python :: 3.9", |
||||
"Programming Language :: Python :: 3.10", |
||||
"Programming Language :: Python :: 3 :: Only", |
||||
"License :: Freely Distributable", |
||||
] |
||||
|
||||
dependencies = [ |
||||
"pandas", |
||||
] |
||||
|
||||
[project.urls] |
||||
Source = "https://git.cpi.imtek.uni-freiburg.de/holgi/conda_helpers.git" |
||||
|
||||
# [project.scripts] |
||||
# script_name = "conda_helpers:function" |
||||
|
||||
[project.optional-dependencies] |
||||
dev = [ |
||||
"black", |
||||
"flit", |
||||
"keyring", |
||||
"pre-commit", |
||||
"ruff", |
||||
] |
||||
docs = [ |
||||
"mkdocs", |
||||
"mkdocstrings[python]", |
||||
] |
||||
test = [ |
||||
"nox", |
||||
"pytest >=4.0.0", |
||||
"pytest-cov", |
||||
"pytest-icdiff", |
||||
"pytest-mock", |
||||
"pytest-randomly", |
||||
] |
||||
|
||||
|
||||
[tool.pytest.ini_options] |
||||
markers = [ |
||||
"functional: marks tests as functional (deselect with '-m \"not functional\"')", |
||||
] |
||||
addopts = [ |
||||
"--strict-markers", |
||||
"--strict-config", |
||||
"--showlocals", |
||||
"-ra", |
||||
] |
||||
|
||||
|
||||
[tool.black] |
||||
line-length = 79 |
||||
target-version = ['py39', 'py310'] |
||||
include = '\.pyi?$' |
||||
extend-exclude = ''' |
||||
# A regex preceded with ^/ will apply only to files and directories |
||||
# in the root of the project. |
||||
^/.git |
||||
^/.tox |
||||
^/.venv |
||||
^/.build |
||||
^/.dist |
||||
''' |
||||
|
||||
|
||||
[tool.ruff] |
||||
# see https://github.com/charliermarsh/ruff |
||||
select = ["ALL"] |
||||
ignore = [ |
||||
# ignored for now, should be activated in the future |
||||
# docstrings |
||||
"D", |
||||
# flake8-annotations |
||||
"ANN", |
||||
# flake8-type-checking |
||||
"TCH", |
||||
|
||||
# ignored, "black" will handle this |
||||
# flake8-commas |
||||
"COM", |
||||
|
||||
# ignored, due to Windows / WSL2 setup |
||||
# flake8-executable |
||||
"EXE", |
||||
] |
||||
fixable = ["I"] |
||||
fix = true |
||||
line-length=79 |
||||
target-version = "py38" |
||||
|
||||
[tool.ruff.per-file-ignores] |
||||
# see https://github.com/charliermarsh/ruff |
||||
"tests/*" = ["FBT003", "INP001", "PLR2004", "S101", "SLF001"] |
||||
|
||||
[tool.ruff.pydocstyle] |
||||
convention = "pep257" # Accepts: "google", "numpy", or "pep257". |
@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
|
||||
""" conda helpers |
||||
|
||||
Helpers for working with data frames in a conda environment |
||||
""" |
||||
|
||||
__version__ = "0.0.1" |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
""" Stub file for testing the project |
||||
|
||||
There are three predefined ways to run tests: |
||||
|
||||
make test: |
||||
runs only unit tests, that are not marked with "fun" (for functional test) |
||||
in a random order. If a test failed before, only the failed tests will be |
||||
run. This is intended to be the default testing method while developing. |
||||
|
||||
make testall: |
||||
runs unit tests and functional tests in random order. Will give a complete |
||||
overview of the test suite. |
||||
|
||||
make coverage: |
||||
runs only tests marked with "fun" (for functional tests) and generates a |
||||
coverage report for the test run. The idea is to check the test coverage |
||||
only on functinal tests to see if a) everything is as much covered as |
||||
possible and b) to find dead code that is not called in end-to-end tests. |
||||
|
||||
all three test strategies will run "make lint" before to catch easily made |
||||
mistakes. |
||||
""" |
||||
|
||||
import pytest |
||||
|
||||
|
||||
def test_example_unittest(): |
||||
"""example unittest - try importing the project |
||||
|
||||
will be run by 'make test' and 'make testall' but not 'make coverage' |
||||
""" |
||||
import conda_helpers # noqa: F401 |
||||
|
||||
assert True |
||||
|
||||
|
||||
@pytest.mark.functional() |
||||
def test_example_functional_test(): |
||||
"""example unittest |
||||
|
||||
will be by 'make coverage' and 'make testall' but not 'make test' |
||||
""" |
||||
import conda_helpers # noqa: F401 |
||||
|
||||
assert True |
Loading…
Reference in new issue