Skip to content

Commit

Permalink
Merge pull request #31 from MODFLOW-USGS/v0.0.8
Browse files Browse the repository at this point in the history
Release 0.0.8
  • Loading branch information
wpbonelli authored Dec 29, 2022
2 parents 4f922bc + bfb6c92 commit 160348e
Show file tree
Hide file tree
Showing 24 changed files with 532 additions and 333 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ jobs:
# remove this release's changelog so we don't commit it
# the changes have already been prepended to HISTORY.md
rm ${{ steps.update-changelog.outputs.changelog }}
rm -f CHANGELOG.md
# commit and push changes
git config core.sharedRepository true
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,8 @@ modflow_devtools/bin/
modflow_devtools/utilities/temp/

# git-cliff-action likes to add app/ folder to the project root
app
app

# in case developer installs modflow executables in the project root
bin

12 changes: 12 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
sphinx:
configuration: docs/conf.py
formats:
- pdf
python:
version: "3.8"
install:
- method: pip
path: .
extra_requirements:
- docs
7 changes: 0 additions & 7 deletions CHANGELOG.md

This file was deleted.

7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
### Version 0.0.8

#### Bug fixes

* [fix(release)](https://github.com/modflowpy/flopy/commit/b62547bd607f9a0d3a78be61d16976bf406151f5): Exclude intermediate changelog (#28). Committed by w-bonelli on 2022-12-28.
* [fix(fixtures)](https://github.com/modflowpy/flopy/commit/a2d4b9210db532f12cf87ae5d26582d1ed446463): Fix example_scenario fixture loading (#30). Committed by w-bonelli on 2022-12-29.

### Version 0.0.7

#### Refactoring
Expand Down
312 changes: 9 additions & 303 deletions README.md

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -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)
31 changes: 31 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 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 = 'modflow-devtools'
author = 'MODFLOW Team'
release = 0.0.8

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = ['myst_parser']
source_suffix = {
'.rst': 'restructuredtext',
'.md': 'markdown'
}
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 = 'sphinx_rtd_theme'
html_title = 'MODFLOW Devtools'
html_static_path = ['_static']
50 changes: 50 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.. modflow-devtools documentation master file, created by
sphinx-quickstart on Wed Dec 28 16:23:25 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
MODFLOW development tools
================================================

The `modflow-devtools` package provides a set of tools for developing and testing MODFLOW 6, FloPy, and related applications.

.. toctree::
:maxdepth: 2
:caption: Introduction

md/install.md


.. toctree::
:maxdepth: 2
:caption: Test fixtures

md/cases.md
md/executables.md
md/fixtures.md
md/markers.md


.. toctree::
:maxdepth: 2
:caption: Miscellaneous

md/download.md
md/zip.md


.. toctree::
:maxdepth: 2
:caption: External tools

md/act.md
md/doctoc.md



Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
35 changes: 35 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
@@ -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

%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.https://www.sphinx-doc.org/
exit /b 1
)

if "%1" == "" goto help

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd
21 changes: 21 additions & 0 deletions docs/md/act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Local CI testing

The [`act`](https://github.com/nektos/act) tool uses Docker to run containerized CI workflows in a simulated GitHub Actions environment. [Docker Desktop](https://www.docker.com/products/docker-desktop/) is required for Mac or Windows and [Docker Engine](https://docs.docker.com/engine/) on Linux.

With Docker installed and running, run `act -l` from the project root to see available CI workflows. To run all workflows and jobs, just run `act`. To run a particular workflow use `-W`:

```shell
act -W .github/workflows/commit.yml
```

To run a particular job within a workflow, add the `-j` option:

```shell
act -W .github/workflows/commit.yml -j build
```

**Note:** GitHub API rate limits are easy to exceed, especially with job matrices. Authenticated GitHub users have a much higher rate limit: use `-s GITHUB_TOKEN=<your token>` when invoking `act` to provide a personal access token. Note that this will log your token in shell history &mdash; leave the value blank for a prompt to enter it more securely.

The `-n` flag can be used to execute a dry run, which doesn't run anything, just evaluates workflow, job and step definitions. See the [docs](https://github.com/nektos/act#example-commands) for more.

**Note:** `act` can only run Linux-based container definitions, so Mac or Windows workflows or matrix OS entries will be skipped.
64 changes: 64 additions & 0 deletions docs/md/cases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Cases

An alternative approach to testing, rather than loading pre-existing models from a repository, is to construct test models in code. This typically involves defining variables or `pytest` fixtures in the same test script as the test function. While this pattern is effective for manually defined scenarios, it tightly couples test functions to test cases, prevents easy reuse of the test case by other tests, and tends to lead to duplication, as each test script may reproduce similar test functions and data-generation procedures.

This package provides a minimal framework for self-describing test cases which can be defined once and plugged into arbitrary test functions. At its core is the `Case` class, which is just a `SimpleNamespace` with a few defaults and a `copy_update()` method for easy modification. This pairs nicely with [`pytest-cases`](https://smarie.github.io/python-pytest-cases/), which is recommended but not required.

## Overview

A `Case` requires only a `name`, and has a single default attribute, `xfail=False`, indicating whether the test case is expected to succeed. (Test functions may of course choose to use or ignore this.)

## Usage

### Parametrizing with `Case`

`Case` can be used with `@pytest.mark.parametrize()` as usual. For instance:

```python
import pytest
from modflow_devtools.case import Case

template = Case(name="QA")
cases = [
template.copy_update(name=template.name + "1",
question="What's the meaning of life, the universe, and everything?",
answer=42),
template.copy_update(name=template.name + "2",
question="Is a Case immutable?",
answer="No, but it's probably best not to mutate it.")
]


@pytest.mark.parametrize("case", cases)
def test_cases(case):
assert len(cases) == 2
assert cases[0] != cases[1]
```

### Generating cases dynamically

One pattern possible with `pytest-cases` is to programmatically generate test cases by parametrizing a function. This can be a convenient way to produce several similar test cases from a template:

```python
from pytest_cases import parametrize, parametrize_with_cases
from modflow_devtools.case import Case


template = Case(name="QA")
gen_cases = [template.copy_update(name=f"{template.name}{i}", question=f"Q{i}", answer=f"A{i}") for i in range(3)]
info = "cases can be modified further in the generator function,"\
" or the function may construct and return another object"


@parametrize(case=gen_cases, ids=[c.name for c in gen_cases])
def qa_cases(case):
return case.copy_update(info=info)


@parametrize_with_cases("case", cases=".", prefix="qa_")
def test_qa(case):
assert "QA" in case.name
assert info == case.info
print(f"{case.name}:", f"{case.question}? {case.answer}")
print(case.info)
```
11 changes: 11 additions & 0 deletions docs/md/doctoc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Generating TOCs

The [`doctoc`](https://www.npmjs.com/package/doctoc) tool can be used to automatically generate table of contents sections for markdown files. `doctoc` is distributed with the [Node Package Manager](https://docs.npmjs.com/cli/v7/configuring-npm/install). With Node installed use `npm install -g doctoc` to install `doctoc` globally. Then just run `doctoc <file>`, e.g.:

```shell
doctoc DEVELOPER.md
```

This will insert HTML comments surrounding an automatically edited region, scanning for headers and creating an appropriately indented TOC tree. Subsequent runs are idempotent, updating if the file has changed or leaving it untouched if not.

To run `doctoc` for all markdown files in a particular directory (recursive), use `doctoc some/path`.
1 change: 1 addition & 0 deletions docs/md/download.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Downloads
31 changes: 31 additions & 0 deletions docs/md/executables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Executables

The `Executables` class is just a mapping between executable names and paths on the filesystem. This can be useful to test multiple versions of the same program, and is easily injected into test functions as a fixture:

```python
from os import environ
from pathlib import Path
import subprocess
import sys

import pytest

from modflow_devtools.misc import get_suffixes
from modflow_devtools.executables import Executables

_bin_path = Path("~/.local/bin/modflow").expanduser()
_dev_path = Path(environ.get("BIN_PATH")).absolute()
_ext, _ = get_suffixes(sys.platform)

@pytest.fixture
@pytest.mark.skipif(not (_bin_path.is_dir() and _dev_path.is_dir()))
def exes():
return Executables(
mf6_rel=_bin_path / f"mf6{_ext}",
mf6_dev=_dev_path / f"mf6{_ext}"
)

def test_exes(exes):
print(subprocess.check_output([f"{exes.mf6_rel}", "-v"]).decode('utf-8'))
print(subprocess.check_output([f"{exes.mf6_dev}", "-v"]).decode('utf-8'))
```
Loading

0 comments on commit 160348e

Please sign in to comment.