From 29e0f7198d8494c7f176c64c2e6056101370453f Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Thu, 29 Jun 2023 13:38:19 -0400 Subject: [PATCH 01/11] ci(release): update release notes, refactor dist scripts * reinit release notes for next development cycle * add --repo-owner option to build_docs.py * use .mf6minsim model for sample mf6 output in docs * refactor update_version.py to use packaging.version * convert version.txt to plain text * convert dev version to v6.4.3.dev0 * sub version into release notes folder structure --- .github/workflows/ci.yml | 18 +-- .github/workflows/release.yml | 28 ++-- CITATION.cff | 2 +- README.md | 2 +- autotest/test_cli.py | 12 +- code.json | 2 +- distribution/build_docs.py | 89 ++++------- distribution/conftest.py | 4 +- distribution/update_version.py | 174 ++++----------------- doc/ReleaseNotes/ReleaseNotes.tex | 12 +- doc/ReleaseNotes/appendixA.tex | 1 + doc/ReleaseNotes/develop.tex | 61 ++++++++ doc/ReleaseNotes/folder_struct.tex | 2 +- doc/ReleaseNotes/{ => previous}/v6.4.2.tex | 2 +- doc/version.py | 11 +- doc/version.tex | 2 +- meson.build | 2 +- src/Utilities/version.f90 | 2 +- version.txt | 11 +- 19 files changed, 158 insertions(+), 279 deletions(-) create mode 100644 doc/ReleaseNotes/develop.tex rename doc/ReleaseNotes/{ => previous}/v6.4.2.tex (99%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75c7b43d4b6..4a0eef2e97b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -230,23 +230,7 @@ jobs: if: runner.os == 'Linux' working-directory: usgslatex/usgsLaTeX run: sudo ./install.sh --all-users - - - name: Install dependencies for ex-gwf-twri example model - if: runner.os == 'Linux' - working-directory: modflow6-examples/etc - run: | - # install extra Python packages - pip install -r requirements.pip.txt - - # the example model needs executables to be on the path - echo "${{ github.workspace }}/modflow6/bin" >> $GITHUB_PATH - echo "${{ github.workspace }}/modflow6/bin/downloaded" >> $GITHUB_PATH - - - name: Build ex-gwf-twri example model - if: runner.os == 'Linux' - working-directory: modflow6-examples/scripts - run: python ex-gwf-twri.py - + - name: Test distribution scripts working-directory: modflow6/distribution env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1973766a474..4f386f06fbb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -212,21 +212,16 @@ jobs: working-directory: usgslatex/usgsLaTeX run: sudo ./install.sh --all-users - - name: Install dependencies for ex-gwf-twri example model - if: ${{ runner.os == 'Linux' && inputs.run_tests == true }} - working-directory: modflow6-examples/etc - run: | - # install extra Python packages - pip install -r requirements.pip.txt + # - name: Install dependencies for ex-gwf-twri example model + # if: ${{ runner.os == 'Linux' && inputs.run_tests == true }} + # working-directory: modflow6-examples/etc + # run: | + # # install extra Python packages + # pip install -r requirements.pip.txt - # the example model needs executables to be on the path - echo "${{ github.workspace }}/modflow6/bin" >> $GITHUB_PATH - echo "${{ github.workspace }}/modflow6/bin/downloaded" >> $GITHUB_PATH - - - name: Build ex-gwf-twri example model - if: ${{ runner.os == 'Linux' && inputs.run_tests == true }} - working-directory: modflow6-examples/scripts - run: python ex-gwf-twri.py + # # the example model needs executables to be on the path + # echo "${{ github.workspace }}/modflow6/bin" >> $GITHUB_PATH + # echo "${{ github.workspace }}/modflow6/bin/downloaded" >> $GITHUB_PATH - name: Test distribution scripts if: ${{ inputs.run_tests == true }} @@ -329,11 +324,6 @@ jobs: working-directory: modflow6/autotest run: python update_flopy.py - - name: Build ex-gwf-twri example model - if: inputs.full != true - working-directory: modflow6-examples/scripts - run: python ex-gwf-twri.py - - name: Build example models if: inputs.full == true working-directory: modflow6-examples/etc diff --git a/CITATION.cff b/CITATION.cff index 184ea7a5b8f..6bcd160f534 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,7 +2,7 @@ cff-version: 1.2.0 message: If you use this software, please cite the software itself. type: software title: MODFLOW 6 Modular Hydrologic Model -version: 6.4.2+ +version: 6.4.3.dev0 date-released: '2023-06-29' doi: 10.5066/F76Q1VQV abstract: MODFLOW 6 is an object-oriented program and framework developed to provide diff --git a/README.md b/README.md index 54452bc60ab..53a6d46378d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is the development repository for the USGS MODFLOW 6 Hydrologic Model. The official USGS distribution is available at [USGS Release Page](https://water.usgs.gov/ogw/modflow/MODFLOW.html). -### Version 6.4.2+ (preliminary) +### Version 6.4.3.dev0 (preliminary) [![GitHub release](https://img.shields.io/github/release/MODFLOW-USGS/modflow6.svg)](https://github.com/MODFLOW-USGS/modflow6/releases/latest) [![MODFLOW 6 continuous integration](https://github.com/MODFLOW-USGS/modflow6/actions/workflows/ci.yml/badge.svg)](https://github.com/MODFLOW-USGS/modflow6/actions/workflows/ci.yml) diff --git a/autotest/test_cli.py b/autotest/test_cli.py index aa9185ceb46..6aa73052988 100644 --- a/autotest/test_cli.py +++ b/autotest/test_cli.py @@ -1,4 +1,3 @@ -import re import subprocess from conftest import project_root_path @@ -6,11 +5,6 @@ bin_path = project_root_path / "bin" -def split_nonnumeric(s): - match = re.compile("[^0-9]").search(s) - return [s[:match.start()], s[match.start():]] if match else s - - def test_cli_version(): output = " ".join( subprocess.check_output([str(bin_path / "mf6"), "-v"]).decode().split() @@ -23,7 +17,5 @@ def test_cli_version(): ) print(version) v_split = version.split(".") - assert len(v_split) == 3 - assert all(s.isdigit() for s in v_split[:2]) - sol = split_nonnumeric(v_split[2]) - assert sol[0].isdigit() + assert len(v_split) >= 2 + assert all(s[-1].isdigit() for s in v_split[:2]) diff --git a/code.json b/code.json index ed1b27fb668..74b70f48377 100644 --- a/code.json +++ b/code.json @@ -18,7 +18,7 @@ "email": "langevin@usgs.gov" }, "laborHours": -1, - "version": "6.4.2+", + "version": "6.4.3.dev0", "date": { "metadataLastUpdated": "2023-06-29" }, diff --git a/distribution/build_docs.py b/distribution/build_docs.py index efc4c8bbc0c..86a4f0879c3 100644 --- a/distribution/build_docs.py +++ b/distribution/build_docs.py @@ -5,7 +5,7 @@ import sys import textwrap from datetime import datetime -from os import PathLike +from os import environ, PathLike from pathlib import Path from pprint import pprint from tempfile import TemporaryDirectory @@ -103,10 +103,10 @@ def clean_tex_files(): assert not os.path.isfile(str(pth) + ".pdf") -def download_benchmarks(output_path: PathLike, verbose: bool = False) -> Optional[Path]: +def download_benchmarks(output_path: PathLike, verbose: bool = False, repo_owner: str = "MODFLOW-USGS") -> Optional[Path]: output_path = Path(output_path).expanduser().absolute() name = "run-time-comparison" # todo make configurable - repo = "MODFLOW-USGS/modflow6" # todo make configurable, add pytest/cli args + repo = f"{repo_owner}/modflow6" # todo make configurable, add pytest/cli args artifacts = list_artifacts(repo, name=name, verbose=verbose) artifacts = sorted( artifacts, @@ -127,21 +127,26 @@ def download_benchmarks(output_path: PathLike, verbose: bool = False) -> Optiona return None +@pytest.fixture +def github_user() -> Optional[str]: + return environ.get("GITHUB_USER", None) + + @flaky @requires_github -def test_download_benchmarks(tmp_path): - path = download_benchmarks(tmp_path, verbose=True) +def test_download_benchmarks(tmp_path, github_user): + path = download_benchmarks(tmp_path, verbose=True, repo_owner=github_user if github_user else "MODFLOW-USGS") if path: assert path.name == "run-time-comparison.md" -def build_benchmark_tex(output_path: PathLike, overwrite: bool = False): +def build_benchmark_tex(output_path: PathLike, overwrite: bool = False, repo_owner: str = "MODFLOW-USGS"): _benchmarks_path.mkdir(parents=True, exist_ok=True) benchmarks_path = _benchmarks_path / "run-time-comparison.md" # download benchmark artifacts if any exist on GitHub if not benchmarks_path.is_file(): - benchmarks_path = download_benchmarks(_benchmarks_path) + benchmarks_path = download_benchmarks(_benchmarks_path, repo_owner=repo_owner) # run benchmarks again if no benchmarks found on GitHub or overwrite requested if overwrite or not benchmarks_path.is_file(): @@ -426,33 +431,29 @@ def test_build_pdfs_from_tex(tmp_path): def build_documentation( bin_path: PathLike, - output_path: PathLike, - examples_repo_path: PathLike, - # Example to use to render sample mf6 output in the docs. - # Must be a valid directory in modflow6-examples/examples - example_for_sample: str = "ex-gwf-twri01", full: bool = False, + output_path: Optional[PathLike] = None, overwrite: bool = False, + repo_owner: str = "MODFLOW-USGS" ): print(f"Building {'full' if full else 'full'} documentation") bin_path = Path(bin_path).expanduser().absolute() output_path = Path(output_path).expanduser().absolute() - examples_repo_path = Path(examples_repo_path).expanduser().absolute() # make sure output directory exists output_path.mkdir(parents=True, exist_ok=True) # build LaTex input/output docs from DFN files build_mf6io_tex_from_dfn(overwrite=True) - + # build LaTeX input/output example model docs with TemporaryDirectory() as temp: - temp_path = Path(temp) + example_path = _project_root_path / ".mf6minsim" build_mf6io_tex_example( - workspace_path=temp_path, + workspace_path=Path(temp), bin_path=bin_path, - example_model_path=examples_repo_path / "examples" / example_for_sample, + example_model_path=example_path, ) # build LaTeX file describing distribution folder structure @@ -463,10 +464,10 @@ def build_documentation( build_pdfs_from_tex(tex_paths=_dev_dist_tex_paths, output_path=output_path) else: # convert benchmarks to LaTex, running them first if necessary - build_benchmark_tex(output_path=output_path, overwrite=overwrite) + build_benchmark_tex(output_path=output_path, overwrite=overwrite, repo_owner=repo_owner) # download example docs - latest = get_release("MODFLOW-USGS/modflow6-examples", "latest") + latest = get_release(f"{repo_owner}/modflow6-examples", "latest") assets = latest["assets"] asset = next(iter([a for a in assets if a["name"] == "mf6examples.pdf"]), None) download_and_unzip(asset["browser_download_url"], output_path, verbose=True) @@ -529,13 +530,6 @@ def test_build_documentation(tmp_path): """ ), ) - parser.add_argument( - "-t", - "--tex-path", - action="append", - required=False, - help="Extra LaTeX files to include", - ) parser.add_argument( "-b", "--bin-path", @@ -544,18 +538,19 @@ def test_build_documentation(tmp_path): help="Location of modflow6 executables", ) parser.add_argument( - "-e", - "--examples-repo-path", + "-f", + "--force", required=False, - default=str(_examples_repo_path), - help="Path to directory containing modflow6 example models", + default=False, + action="store_true", + help="Recreate and overwrite existing artifacts", ) parser.add_argument( - "-s", - "--example-for-sample", + "--full", required=False, - default="ex-gwf-twri01", - help="Name of example model to use for sample mf6 output", + default=False, + action="store_true", + help="Build docs for a full rather than minimal distribution", ) parser.add_argument( "-o", @@ -565,35 +560,19 @@ def test_build_documentation(tmp_path): help="Location to create documentation artifacts", ) parser.add_argument( - "--full", - required=False, - default=False, - action="store_true", - help="Build docs for a full rather than minimal distribution", - ) - parser.add_argument( - "-f", - "--force", + "--repo-owner", required=False, - default=False, - action="store_true", - help="Recreate and overwrite existing artifacts", + default="MODFLOW-USGS", + help="Repository owner (substitute your own for a fork)" ) args = parser.parse_args() - tex_paths = _full_dist_tex_paths + ( - [Path(p) for p in args.tex_path] if args.tex_path else [] - ) output_path = Path(args.output_path).expanduser().absolute() output_path.mkdir(parents=True, exist_ok=True) bin_path = Path(args.bin_path).expanduser().absolute() - examples_repo_path = Path(args.examples_repo_path).expanduser().absolute() - example_for_sample = args.example_for_sample - build_documentation( bin_path=bin_path, - output_path=output_path, - examples_repo_path=examples_repo_path, - example_for_sample=example_for_sample, full=args.full, + output_path=output_path, overwrite=args.force, + repo_owner=args.repo_owner ) diff --git a/distribution/conftest.py b/distribution/conftest.py index 860ef1d585b..df18401b2a4 100644 --- a/distribution/conftest.py +++ b/distribution/conftest.py @@ -1,11 +1,11 @@ from pathlib import Path -from update_version import Version +from packaging.version import Version _project_root_path = Path(__file__).resolve().parent.parent _dist_dir_path = ( _project_root_path.parent - / f"mf{str(Version.from_file(_project_root_path / 'version.txt'))}" + / f"mf{str(Version((_project_root_path / 'version.txt').read_text().strip()))}" ) diff --git a/distribution/update_version.py b/distribution/update_version.py index f1112c58761..8caf812a174 100755 --- a/distribution/update_version.py +++ b/distribution/update_version.py @@ -31,20 +31,18 @@ import argparse import json import os -import re -import shutil import textwrap from collections import OrderedDict from datetime import datetime -from os import PathLike +from packaging.version import Version from pathlib import Path -from typing import NamedTuple, Optional +from typing import Optional import pytest from filelock import FileLock import yaml -from utils import get_modified_time, split_nonnumeric +from utils import get_modified_time project_name = "MODFLOW 6" project_root_path = Path(__file__).resolve().parent.parent @@ -62,56 +60,6 @@ ] -class Version(NamedTuple): - """Semantic version number, optionally with a short label (e.g, 'rc'). - The label may contain numbers but must begin with a letter.""" - - major: int = 0 - minor: int = 0 - patch: int = 0 - label: Optional[str] = None - - def __repr__(self): - s = f"{self.major}.{self.minor}.{self.patch}" - if self.label is not None and self.label != "": - s += self.label - return s - - @classmethod - def from_string(cls, version: str) -> "Version": - t = version.split(".") - assert len(t) > 2 - vmajor = int(t[0]) - vminor = int(t[1]) - tt = split_nonnumeric(t[2]) - vpatch = int(tt[0]) - vlabel = tt[1] if len(tt) > 1 else None - return cls(major=vmajor, minor=vminor, patch=vpatch, label=vlabel) - - @classmethod - def from_file(cls, path: PathLike) -> "Version": - path = Path(path).expanduser().absolute() - lines = [line.rstrip("\n") for line in open(Path(path), "r")] - vmajor = vminor = vpatch = vlabel = None - for line in lines: - t = line.split() - if "major =" in line: - vmajor = int(t[2]) - elif "minor =" in line: - vminor = int(t[2]) - elif "micro =" in line: - vpatch = int(t[2]) - elif "label =" in line: - vlabel = t[2].replace("'", "") - - msg = "version string must follow semantic version format, with optional label: major.minor.patch[label]" - missing = lambda v: f"Missing {v} number, {msg}" - assert vmajor is not None, missing("major") - assert vminor is not None, missing("minor") - assert vpatch is not None, missing("patch") - return cls(major=vmajor, minor=vminor, patch=vpatch, label=vlabel) - - _approved_fmtdisclaimer = ''' character(len=*), parameter :: FMTDISCLAIMER = & "(/,& &'This software has been approved for release by the U.S. Geological ',/,& @@ -181,25 +129,17 @@ def log_update(path, version: Version): def update_version_txt_and_py(version: Version, timestamp: datetime): with open(version_file_path, "w") as f: + f.write(str(version)) + log_update(version_file_path, version) + + py_path = project_root_path / "doc" / version_file_path.name.replace(".txt", ".py") + with open(py_path, "w") as f: f.write( f"# {project_name} version file automatically " + f"created using...{os.path.basename(__file__)}\n" ) f.write("# created on..." + f"{timestamp.strftime('%B %d, %Y %H:%M:%S')}\n") - f.write("\n") - f.write(f"major = {version.major}\n") - f.write(f"minor = {version.minor}\n") - f.write(f"micro = {version.patch}\n") - f.write( - "label = " + (("'" + version.label + "'") if version.label else "''") + "\n" - ) - f.write("__version__ = '{:d}.{:d}.{:d}'.format(major, minor, micro)\n") - f.write("if label:\n") - f.write("\t__version__ += '{}{}'.format(__version__, label)") - f.close() - log_update(version_file_path, version) - py_path = project_root_path / "doc" / version_file_path.name.replace(".txt", ".py") - shutil.copyfile(version_file_path, py_path) + f.write(f'__version__ = "{version}"\n') log_update(py_path, version) @@ -209,7 +149,7 @@ def update_meson_build(version: Version): with open(path, "w") as f: for line in lines: if "version:" in line and "meson_version:" not in line: - line = f" version: '{version.major}.{version.minor}.{version.patch}{version.label if version.label else ''}'," + line = f" version: '{version}'," f.write(f"{line}\n") log_update(path, version) @@ -351,11 +291,11 @@ def update_version( lock_path = Path(version_file_path.name + ".lock") try: lock = FileLock(lock_path) - previous = Version.from_file(version_file_path) + previous = Version(version_file_path.read_text().strip()) version = ( version if version - else Version(previous.major, previous.minor, previous.patch) + else previous ) with lock: @@ -370,8 +310,8 @@ def update_version( lock_path.unlink(missing_ok=True) -_initial_version = Version(0, 0, 1) -_current_version = Version.from_file(version_file_path) +_initial_version = Version("0.0.1") +_current_version = Version(version_file_path.read_text().strip()) @pytest.mark.skip(reason="reverts repo files on cleanup, tread carefully") @@ -379,17 +319,8 @@ def update_version( "version", [ None, - Version( - major=_initial_version.major, - minor=_initial_version.minor, - patch=_initial_version.patch, - ), - Version( - major=_initial_version.major, - minor=_initial_version.minor, - patch=_initial_version.patch, - label="rc", - ), + _initial_version, + Version(f"{_initial_version.major}.{_initial_version.minor}.dev{_initial_version.micro}"), ], ) @pytest.mark.parametrize("approved", [True, False]) @@ -405,7 +336,7 @@ def test_update_version(version, approved, developmode): approved=approved, developmode=developmode, ) - updated = Version.from_file(version_file_path) + updated = Version(version_file_path.read_text().strip()) # check files containing version info were modified for p, t in zip(touched_file_paths, m_times): @@ -414,20 +345,10 @@ def test_update_version(version, approved, developmode): # check version number and optional label are correct if version: # version should be auto-incremented - assert updated.major == _initial_version.major - assert updated.minor == _initial_version.minor - assert updated.patch == _initial_version.patch - if version.label is not None: - assert updated.label == version.label + assert updated == _initial_version else: # version should not have changed - assert updated.major == _current_version.major - assert updated.minor == _current_version.minor - assert updated.patch == _current_version.patch - if version.label is not None: - assert updated.label == version.label - if version.label is not None: - assert updated.label == _initial_version + assert updated == _current_version # check IDEVELOPMODE was set correctly version_f90_path = project_root_path / "src" / "Utilities" / "version.f90" @@ -462,13 +383,10 @@ def test_update_version(version, approved, developmode): provided, the version number will not be changed. A file lock is held to synchronize file access. To indicate a version is production-ready use --approve. This will change the disclaimer and version tag label, - removing 'Release Candidate' from the latter and modifying the former - to reflect approval The IDEVELOPMODE flag is set to 1 for preliminary - versions and 0 for approved versions. The version tag must follow the + removing '(preliminary)' from the latter, and modifying the former to + reflect approval The --releasemode flag controls whether IDEVELOPMODE + is set to 0 instead of the default 1. The version tag must follow the '..' format conventions for semantic versioning. - If --version is provided, --bump-patch, --bump-minor and --bump-major - may not be provided. Likewise, if any of the latter are provided, the - version number must not be specified. """ ), ) @@ -492,24 +410,6 @@ def test_update_version(version, approved, developmode): action="store_true", help="Set IDEVELOPMODE to 0 for release mode (defaults to false for development distributions)", ) - parser.add_argument( - "--bump-major", - required=False, - action="store_true", - help="Increment the major version number (cannot be used with --version, defaults to false)", - ) - parser.add_argument( - "--bump-minor", - required=False, - action="store_true", - help="Increment the minor version number (cannot be used with --version, defaults to false)", - ) - parser.add_argument( - "--bump-patch", - required=False, - action="store_true", - help="Increment the patch version number (cannot be used with --version, defaults to false)", - ) parser.add_argument( "-g", "--get", @@ -518,33 +418,13 @@ def test_update_version(version, approved, developmode): help="Get the current version number, don't update anything (defaults to false)", ) args = parser.parse_args() - - if args.version and (args.bump_major or args.bump_minor or args.bump_patch): - raise ValueError(f"Cannot specify --version and --bump-*, use one or the other") - - bump_flags = [b for b in [args.bump_major, args.bump_minor, args.bump_patch] if b] - if len(bump_flags) > 1: - raise ValueError(f"Cannot specify more than one --bump-* flag, use just one") - if args.get: - print(Version.from_file(project_root_path / "version.txt")) + print(Version((project_root_path / "version.txt").read_text().strip())) else: - if not args.version and not any(bump_flags): - version = _current_version - elif args.version: - version = Version.from_string(args.version) - else: - current = Version.from_file(project_root_path / "version.txt") - if args.bump_major: - print(f"Incrementing major number") - version = Version(current.major + 1, 0, 0) - elif args.bump_minor: - print(f"Incrementing minor number") - version = Version(current.major, current.minor + 1, 0) - else: - print(f"Incrementing patch number") - version = Version(current.major, current.minor, current.patch + 1) - + print(f"Updating to version {args.version} with options") + print(f" releasemode: {args.releasemode}") + print(f" approved: {args.approved}") + version = Version(args.version) if args.version else _current_version update_version( version=version, timestamp=datetime.now(), diff --git a/doc/ReleaseNotes/ReleaseNotes.tex b/doc/ReleaseNotes/ReleaseNotes.tex index 26fbf93e8d8..95d18e90f8d 100644 --- a/doc/ReleaseNotes/ReleaseNotes.tex +++ b/doc/ReleaseNotes/ReleaseNotes.tex @@ -189,7 +189,7 @@ \section{Changes Introduced in this Release} This section describes changes introduced into MODFLOW~6 for the current release. These changes may substantially affect users. \begin{itemize} -\input{v6.4.2.tex} +\input{develop.tex} \end{itemize} % ------------------------------------------------- @@ -251,7 +251,15 @@ \section{Installation and Execution} % ------------------------------------------------- \section{Compiling MODFLOW~6} -MODFLOW~6 has been compiled using Intel Fortran and GNU Fortran on the Windows, macOS, and Linux operating systems. Because the program uses relatively new Fortran functionality, recent versions of the compilers may be required for successful compilation. MODFLOW~6 is currently tested with gfortran 7-12 on Linux and gfortran 12 on macOS and Windows. If you have gfortran installed on your computer, you can tell which version it is by entering ``\verb|gfortran --version|'' at a terminal window. MODFLOW~6 is currently not compatible with the next-generation Intel Fortran Compiler; a recent version of the Intel Fortran Compiler Classic (e.g. 2021.8.0) must be used. +MODFLOW~6 has been compiled using Intel Fortran and GNU Fortran on the Windows, macOS, and Linux operating systems. All MODFLOW~6 distributions are currently compiled with Intel Fortran. While the program uses relatively new Fortran functionality, it is not yet compatible with the latest versions of either toolchain. + +MODFLOW~6 is currently tested with gfortran 7-12 on Linux and gfortran 12 on macOS and Windows. The gfortran version can be queried with ``\verb|gfortran --version|''. Intel Fortran version 2022.3.0 is tested on all three platforms. Some 2021 versions have also been reported compatible. + +At this time, MODFLOW~6 is not compatible with: + +- GNU Fortran 13 +- Intel Fortran Compiler Classic versions 2023.y.z +- the next-generation Intel Fortran Compiler `ifx` Meson is the recommended build tool for MODFLOW~6. For more detailed compilation instructions, please refer to \url{https://github.com/MODFLOW-USGS/modflow6/blob/develop/DEVELOPER.md#building}. diff --git a/doc/ReleaseNotes/appendixA.tex b/doc/ReleaseNotes/appendixA.tex index 2bad0245dce..199d7151043 100644 --- a/doc/ReleaseNotes/appendixA.tex +++ b/doc/ReleaseNotes/appendixA.tex @@ -1,5 +1,6 @@ This appendix describes changes introduced into MODFLOW~6 in previous releases. These changes may substantially affect users. + \input{./previous/v6.4.2.tex} \input{./previous/v6.4.1.tex} \input{./previous/v6.4.0.tex} \input{./previous/v6.3.0.tex} diff --git a/doc/ReleaseNotes/develop.tex b/doc/ReleaseNotes/develop.tex new file mode 100644 index 00000000000..5993caf38d2 --- /dev/null +++ b/doc/ReleaseNotes/develop.tex @@ -0,0 +1,61 @@ +% Use this template for starting initializing the release notes +% after a release has just been made. + + \item \currentmodflowversion + + %\underline{NEW FUNCTIONALITY} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} + + %\underline{EXAMPLES} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} + + %\textbf{\underline{BUG FIXES AND OTHER CHANGES TO EXISTING FUNCTIONALITY}} \\ + %\underline{BASIC FUNCTIONALITY} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} + + %\underline{INTERNAL FLOW PACKAGES} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} + + %\underline{STRESS PACKAGES} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} + + %\underline{ADVANCED STRESS PACKAGES} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} + + %\underline{SOLUTION} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} + + %\underline{EXCHANGES} + %\begin{itemize} + % \item xxx + % \item xxx + % \item xxx + %\end{itemize} \ No newline at end of file diff --git a/doc/ReleaseNotes/folder_struct.tex b/doc/ReleaseNotes/folder_struct.tex index 51ba1dc21b0..7d52bc9562a 100644 --- a/doc/ReleaseNotes/folder_struct.tex +++ b/doc/ReleaseNotes/folder_struct.tex @@ -1,5 +1,5 @@ \begin{verbatim} -mf6.x.x/ +\currentmodflowversion bin/ doc/ examples/ diff --git a/doc/ReleaseNotes/v6.4.2.tex b/doc/ReleaseNotes/previous/v6.4.2.tex similarity index 99% rename from doc/ReleaseNotes/v6.4.2.tex rename to doc/ReleaseNotes/previous/v6.4.2.tex index 8d718485fc1..afc3511061a 100644 --- a/doc/ReleaseNotes/v6.4.2.tex +++ b/doc/ReleaseNotes/previous/v6.4.2.tex @@ -2,7 +2,7 @@ % after a release has just been made. %\item \currentmodflowversion - \item Version mf6.4.2--June 28, 2023 + \subsection{Version mf6.4.2--June 28, 2023} \underline{NEW FUNCTIONALITY} \begin{itemize} diff --git a/doc/version.py b/doc/version.py index b0cc293a662..2d2ec3a6151 100644 --- a/doc/version.py +++ b/doc/version.py @@ -1,10 +1,3 @@ # MODFLOW 6 version file automatically created using...update_version.py -# created on...June 29, 2023 00:01:07 - -major = 6 -minor = 4 -micro = 2 -label = '+' -__version__ = '{:d}.{:d}.{:d}'.format(major, minor, micro) -if label: - __version__ += '{}{}'.format(__version__, label) \ No newline at end of file +# created on...June 29, 2023 20:56:14 +__version__ = '6.4.3.dev0' \ No newline at end of file diff --git a/doc/version.tex b/doc/version.tex index ffd8225908d..39ca001268d 100644 --- a/doc/version.tex +++ b/doc/version.tex @@ -1,3 +1,3 @@ -\newcommand{\modflowversion}{mf6.4.2+} +\newcommand{\modflowversion}{mf6.4.3.dev0} \newcommand{\modflowdate}{June 29, 2023} \newcommand{\currentmodflowversion}{Version \modflowversion---\modflowdate} diff --git a/meson.build b/meson.build index bdab45cebf7..71bbaef550f 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'MODFLOW 6', 'fortran', - version: '6.4.2+', + version: '6.4.3.dev0', license: 'CC0', meson_version: '>= 1.1.0', default_options : [ diff --git a/src/Utilities/version.f90 b/src/Utilities/version.f90 index 3008fc2df63..5eda11409cf 100644 --- a/src/Utilities/version.f90 +++ b/src/Utilities/version.f90 @@ -16,7 +16,7 @@ module VersionModule public ! -- modflow 6 version integer(I4B), parameter :: IDEVELOPMODE = 1 - character(len=*), parameter :: VERSIONNUMBER = '6.4.2+' + character(len=*), parameter :: VERSIONNUMBER = '6.4.3.dev0' character(len=*), parameter :: VERSIONTAG = ' (preliminary) 06/29/2023' character(len=40), parameter :: VERSION = VERSIONNUMBER//VERSIONTAG character(len=2), parameter :: MFVNAM = ' 6' diff --git a/version.txt b/version.txt index b0cc293a662..6980736c52c 100644 --- a/version.txt +++ b/version.txt @@ -1,10 +1 @@ -# MODFLOW 6 version file automatically created using...update_version.py -# created on...June 29, 2023 00:01:07 - -major = 6 -minor = 4 -micro = 2 -label = '+' -__version__ = '{:d}.{:d}.{:d}'.format(major, minor, micro) -if label: - __version__ += '{}{}'.format(__version__, label) \ No newline at end of file +6.4.3.dev0 \ No newline at end of file From 51cce0436aa69b41b0201090f9824a0686f1d03b Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Fri, 30 Jun 2023 10:19:37 -0400 Subject: [PATCH 02/11] debug docs build --- .github/workflows/release.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4f386f06fbb..d5c43a44ee7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -295,6 +295,10 @@ jobs: fi eval "$cmd" + - name: Update FloPy classes + working-directory: modflow6/autotest + run: python update_flopy.py + - name: Download pre-built binaries uses: actions/download-artifact@v3 with: @@ -302,6 +306,7 @@ jobs: path: bin - name: Install dependencies for building models + if: inputs.full == true working-directory: modflow6-examples/etc env: GITHUB_TOKEN: ${{ github.token }} @@ -319,10 +324,6 @@ jobs: # the example model also needs mf2005 get-modflow "${{ github.workspace }}/bin" --subset mf2005,triangle,gridgen - - - name: Update FloPy - working-directory: modflow6/autotest - run: python update_flopy.py - name: Build example models if: inputs.full == true @@ -355,7 +356,7 @@ jobs: GITHUB_TOKEN: ${{ github.token }} run: | mkdir -p "${{ needs.build.outputs.distname }}/doc" - cmd="python modflow6/distribution/build_docs.py -b bin -o doc -e modflow6-examples" + cmd="python modflow6/distribution/build_docs.py -b bin -o doc" if [[ "${{ inputs.full }}" == "true" ]]; then cmd="$cmd --full" fi From 0dd6ac7cb0c670926a147746d5e3be28aac36ea1 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Fri, 30 Jun 2023 13:38:42 -0400 Subject: [PATCH 03/11] fix distname subbed into release notes (include ostag) --- distribution/update_version.py | 2 +- doc/ReleaseNotes/ReleaseNotes.tex | 2 +- doc/ReleaseNotes/develop.tex | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/distribution/update_version.py b/distribution/update_version.py index 8caf812a174..812c609a1bf 100755 --- a/distribution/update_version.py +++ b/distribution/update_version.py @@ -157,7 +157,7 @@ def update_meson_build(version: Version): def update_version_tex(version: Version, timestamp: datetime): path = project_root_path / "doc" / "version.tex" with open(path, "w") as f: - line = "\\newcommand{\\modflowversion}{mf" + f"{str(version)}" + "}" + line = "\\newcommand{\\modflowversion}{mf" + str(version) + "\\_[ostag]}" f.write(f"{line}\n") line = ( "\\newcommand{\\modflowdate}{" + f"{timestamp.strftime('%B %d, %Y')}" + "}" diff --git a/doc/ReleaseNotes/ReleaseNotes.tex b/doc/ReleaseNotes/ReleaseNotes.tex index 95d18e90f8d..350bcc40224 100644 --- a/doc/ReleaseNotes/ReleaseNotes.tex +++ b/doc/ReleaseNotes/ReleaseNotes.tex @@ -237,7 +237,7 @@ \section{Distribution File} % folder structured created by python script \input{folder_struct.tex} -It is recommended that no user files are kept in the \modflowversion~directory structure. If you do plan to put your own files in the \modflowversion~directory structure, do so only by creating additional subdirectories. +It is recommended that no user files are kept in the release directory. If you do plan to put your own files in the release directory, do so only by creating additional subdirectories. % ------------------------------------------------- \section{Installation and Execution} diff --git a/doc/ReleaseNotes/develop.tex b/doc/ReleaseNotes/develop.tex index 5993caf38d2..c64400bd1de 100644 --- a/doc/ReleaseNotes/develop.tex +++ b/doc/ReleaseNotes/develop.tex @@ -1,7 +1,7 @@ % Use this template for starting initializing the release notes % after a release has just been made. - \item \currentmodflowversion + \item \currentmodflowversion\_[ostag] %\underline{NEW FUNCTIONALITY} %\begin{itemize} From d5c8730af8e6e4c48d6471395f2189399712cab9 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Fri, 30 Jun 2023 17:19:45 -0400 Subject: [PATCH 04/11] fix distname in docs --- distribution/update_version.py | 2 +- doc/ReleaseNotes/ReleaseNotes.tex | 6 +++--- doc/ReleaseNotes/folder_struct.tex | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/distribution/update_version.py b/distribution/update_version.py index 812c609a1bf..e09e0c69aef 100755 --- a/distribution/update_version.py +++ b/distribution/update_version.py @@ -157,7 +157,7 @@ def update_meson_build(version: Version): def update_version_tex(version: Version, timestamp: datetime): path = project_root_path / "doc" / "version.tex" with open(path, "w") as f: - line = "\\newcommand{\\modflowversion}{mf" + str(version) + "\\_[ostag]}" + line = "\\newcommand{\\modflowversion}{mf" + str(version) + "}" f.write(f"{line}\n") line = ( "\\newcommand{\\modflowdate}{" + f"{timestamp.strftime('%B %d, %Y')}" + "}" diff --git a/doc/ReleaseNotes/ReleaseNotes.tex b/doc/ReleaseNotes/ReleaseNotes.tex index 350bcc40224..f1a8b80570d 100644 --- a/doc/ReleaseNotes/ReleaseNotes.tex +++ b/doc/ReleaseNotes/ReleaseNotes.tex @@ -232,7 +232,7 @@ \section{Known Issues and Incompatibilities} % ------------------------------------------------- \section{Distribution File} -The following distribution file is for use on personal computers: \texttt{\modflowversion.zip}. The distribution file is a compressed zip file. The following directory structure is incorporated in the zip file: +The following distribution file is for use on personal computers: \texttt{\modflowversion\_[ostag].zip}. The distribution file is a compressed zip file. The following directory structure is incorporated in the zip file: % folder structured created by python script \input{folder_struct.tex} @@ -241,11 +241,11 @@ \section{Distribution File} % ------------------------------------------------- \section{Installation and Execution} -There is no installation of MODFLOW~6 other than the requirement that \texttt{\modflowversion.zip} must be unzipped into a location where it can be accessed. +There is no installation of MODFLOW~6 other than the requirement that \texttt{\modflowversion\_[ostag].zip} must be unzipped into a location where it can be accessed. To make the executable versions of MODFLOW~6 accessible from any directory, the directory containing the executables should be included in the PATH environment variable. Also, if a prior release of MODFLOW~6 is installed on your system, the directory containing the executables for the prior release should be removed from the PATH environment variable. -As an alternative, the executable file, named ``\texttt{mf6.exe}'' on Windows, in the \modflowversion{}/bin directory can be copied into a directory already included in the PATH environment variable. +As an alternative, the executable file, named ``\texttt{mf6.exe}'' on Windows, in the \modflowversion\_[ostag]/bin directory can be copied into a directory already included in the PATH environment variable. To run MODFLOW~6, simply type \texttt{mf6} in a terminal window. The current working directory must be set to a location where the model input files are located. Upon execution, MODFLOW~6 will immediately look for file with the name \texttt{mfsim.nam} in the current working directory, and will terminate with an error if it does not find this file. diff --git a/doc/ReleaseNotes/folder_struct.tex b/doc/ReleaseNotes/folder_struct.tex index 7d52bc9562a..18039e95474 100644 --- a/doc/ReleaseNotes/folder_struct.tex +++ b/doc/ReleaseNotes/folder_struct.tex @@ -1,5 +1,5 @@ \begin{verbatim} -\currentmodflowversion +\currentmodflowversion\_[ostag] bin/ doc/ examples/ From cb802b09837f9d6d6b28797234be4a045aa1b008 Mon Sep 17 00:00:00 2001 From: Wes Bonelli Date: Sun, 9 Jul 2023 20:09:37 -0400 Subject: [PATCH 05/11] fix example script test in check_dist.py (some examples have nested dirs) --- distribution/check_dist.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/distribution/check_dist.py b/distribution/check_dist.py index 27be7d087bd..be7c9136140 100644 --- a/distribution/check_dist.py +++ b/distribution/check_dist.py @@ -142,13 +142,15 @@ def test_examples(dist_dir_path, full): print(f"{len(example_paths)} example models found:") pprint(example_paths) for p in example_paths: + script_path = p / f"run{_scext}" + if not script_path.is_file(): + continue pprint( - subprocess.check_output([str(p / f"run{_scext}")], cwd=p).decode().split() + subprocess.check_output([str(script_path)], cwd=p).decode().split() ) break - def test_binaries(dist_dir_path, approved): bin_path = dist_dir_path / "bin" assert (bin_path / f"mf6{_eext}").is_file() From b743eef3b2c30512d13a20255a10f502a4863065 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Thu, 13 Jul 2023 15:34:05 -0400 Subject: [PATCH 06/11] update version to 6.5.0.dev0 --- CITATION.cff | 4 ++-- README.md | 2 +- code.json | 4 ++-- doc/version.py | 4 ++-- doc/version.tex | 4 ++-- meson.build | 2 +- src/Utilities/version.f90 | 4 ++-- version.txt | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 6bcd160f534..2b38284daa0 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,8 +2,8 @@ cff-version: 1.2.0 message: If you use this software, please cite the software itself. type: software title: MODFLOW 6 Modular Hydrologic Model -version: 6.4.3.dev0 -date-released: '2023-06-29' +version: 6.5.0.dev0 +date-released: '2023-07-13' doi: 10.5066/F76Q1VQV abstract: MODFLOW 6 is an object-oriented program and framework developed to provide a platform for supporting multiple models and multiple types of models within the diff --git a/README.md b/README.md index 53a6d46378d..ee60e3696c7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is the development repository for the USGS MODFLOW 6 Hydrologic Model. The official USGS distribution is available at [USGS Release Page](https://water.usgs.gov/ogw/modflow/MODFLOW.html). -### Version 6.4.3.dev0 (preliminary) +### Version 6.5.0.dev0 (preliminary) [![GitHub release](https://img.shields.io/github/release/MODFLOW-USGS/modflow6.svg)](https://github.com/MODFLOW-USGS/modflow6/releases/latest) [![MODFLOW 6 continuous integration](https://github.com/MODFLOW-USGS/modflow6/actions/workflows/ci.yml/badge.svg)](https://github.com/MODFLOW-USGS/modflow6/actions/workflows/ci.yml) diff --git a/code.json b/code.json index 74b70f48377..0a579a5b6e2 100644 --- a/code.json +++ b/code.json @@ -18,9 +18,9 @@ "email": "langevin@usgs.gov" }, "laborHours": -1, - "version": "6.4.3.dev0", + "version": "6.5.0.dev0", "date": { - "metadataLastUpdated": "2023-06-29" + "metadataLastUpdated": "2023-07-13" }, "organization": "U.S. Geological Survey", "permissions": { diff --git a/doc/version.py b/doc/version.py index 2d2ec3a6151..6fd599035f7 100644 --- a/doc/version.py +++ b/doc/version.py @@ -1,3 +1,3 @@ # MODFLOW 6 version file automatically created using...update_version.py -# created on...June 29, 2023 20:56:14 -__version__ = '6.4.3.dev0' \ No newline at end of file +# created on...July 13, 2023 15:32:29 +__version__ = "6.5.0.dev0" diff --git a/doc/version.tex b/doc/version.tex index 39ca001268d..147b13cfba9 100644 --- a/doc/version.tex +++ b/doc/version.tex @@ -1,3 +1,3 @@ -\newcommand{\modflowversion}{mf6.4.3.dev0} -\newcommand{\modflowdate}{June 29, 2023} +\newcommand{\modflowversion}{mf6.5.0.dev0} +\newcommand{\modflowdate}{July 13, 2023} \newcommand{\currentmodflowversion}{Version \modflowversion---\modflowdate} diff --git a/meson.build b/meson.build index 71bbaef550f..879bf5d4c3a 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'MODFLOW 6', 'fortran', - version: '6.4.3.dev0', + version: '6.5.0.dev0', license: 'CC0', meson_version: '>= 1.1.0', default_options : [ diff --git a/src/Utilities/version.f90 b/src/Utilities/version.f90 index 5eda11409cf..2ae3d52a069 100644 --- a/src/Utilities/version.f90 +++ b/src/Utilities/version.f90 @@ -16,8 +16,8 @@ module VersionModule public ! -- modflow 6 version integer(I4B), parameter :: IDEVELOPMODE = 1 - character(len=*), parameter :: VERSIONNUMBER = '6.4.3.dev0' - character(len=*), parameter :: VERSIONTAG = ' (preliminary) 06/29/2023' + character(len=*), parameter :: VERSIONNUMBER = '6.5.0.dev0' + character(len=*), parameter :: VERSIONTAG = ' (preliminary) 07/13/2023' character(len=40), parameter :: VERSION = VERSIONNUMBER//VERSIONTAG character(len=2), parameter :: MFVNAM = ' 6' character(len=*), parameter :: MFTITLE = & diff --git a/version.txt b/version.txt index 6980736c52c..8d7edccd2da 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -6.4.3.dev0 \ No newline at end of file +6.5.0.dev0 \ No newline at end of file From 9ac7dd01587e1203bae9cf90cb529baf45e0ec3b Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Thu, 13 Jul 2023 16:36:07 -0400 Subject: [PATCH 07/11] clean up dist scripts, check dirs in dist in check_dist.py --- distribution/build_dist.py | 53 ++------------------------------------ distribution/build_docs.py | 8 +++--- distribution/check_dist.py | 27 +++++++++++++++++-- 3 files changed, 32 insertions(+), 56 deletions(-) diff --git a/distribution/build_dist.py b/distribution/build_dist.py index f60b76302c6..9aba5099e0a 100644 --- a/distribution/build_dist.py +++ b/distribution/build_dist.py @@ -4,7 +4,6 @@ import shutil import sys import textwrap -from collections import namedtuple from os import PathLike, environ from pathlib import Path from pprint import pprint @@ -24,49 +23,13 @@ ) from utils import get_project_root_path, run_command -_project_name = "MODFLOW 6" # default paths _project_root_path = get_project_root_path() -_version_texf_path = _project_root_path / "doc" / "version.tex" _examples_repo_path = _project_root_path.parent / "modflow6-examples" -_examples_path = _examples_repo_path / "examples" _build_path = _project_root_path / "builddir" -_bin_path = _project_root_path / "bin" -_docs_path = _project_root_path / "doc" -_benchmarks_path = _project_root_path / "distribution" / ".benchmarks" - -# top-level directories included in distribution -_included_dir_paths = [ - "bin", - "doc", - "examples", - "src", - "srcbmi", - "msvs", - "make", - "utils", -] - -Makefile = namedtuple("Makefile", ["app", "src_path", "out_path"]) - - -# makefiles included in distribution -_makefiles = [ - Makefile(app="mf6", src_path=_project_root_path / "src", out_path=Path("make")), - Makefile( - app="zbud6", - src_path=_project_root_path / "utils" / "zonebudget" / "src", - out_path=Path("utils") / "zonebudget" / "make", - ), - Makefile( - app="mf5to6", - src_path=_project_root_path / "utils" / "mf5to6" / "src", - out_path=Path("utils") / "mf5to6" / "make", - ), -] - -# system-specific filenames, extensions, etc + +# OS-specific extensions _system = platform.system() _eext = ".exe" if _system == "Windows" else "" _soext = ".dll" if _system == "Windows" else ".so" if _system == "Linux" else ".dylib" @@ -232,10 +195,6 @@ def setup_examples( print(f"Execute permission set for {script_path}") -def test_setup_examples(): - pass - - def build_programs_meson( build_path: PathLike, bin_path: PathLike, overwrite: bool = False ): @@ -446,13 +405,6 @@ def test_build_distribution(tmp_path, full): default=str(_examples_repo_path), help="Path to directory containing modflow6 example models", ) - # parser.add_argument( - # "-b", - # "--benchmarks-path", - # required=False, - # default=str(_project_root_path / "distribution" / ".benchmarks"), - # help="Path to directory containing benchmark results" - # ) parser.add_argument( "--full", required=False, @@ -469,7 +421,6 @@ def test_build_distribution(tmp_path, full): help="Recreate and overwrite existing artifacts", ) args = parser.parse_args() - build_path = Path(args.build_path) out_path = Path(args.output_path) examples_repo_path = ( diff --git a/distribution/build_docs.py b/distribution/build_docs.py index 86a4f0879c3..1990061bb37 100644 --- a/distribution/build_docs.py +++ b/distribution/build_docs.py @@ -29,6 +29,7 @@ from utils import convert_line_endings from utils import get_project_root_path +# paths _project_root_path = get_project_root_path() _bin_path = _project_root_path / "bin" _examples_repo_path = _project_root_path.parent / "modflow6-examples" @@ -47,12 +48,13 @@ _docs_path / "ConverterGuide" / "converter_mf5to6.tex", _docs_path / "SuppTechInfo" / "mf6suptechinfo.tex", ] + +# OS-specific extensions _system = platform.system() _eext = ".exe" if _system == "Windows" else "" _soext = ".dll" if _system == "Windows" else ".so" if _system == "Linux" else ".dylib" - -# publications included in distribution docs +# publications included in full dist docs _publication_urls = [ "https://pubs.usgs.gov/tm/06/a55/tm6a55.pdf", "https://pubs.usgs.gov/tm/06/a56/tm6a56.pdf", @@ -436,7 +438,7 @@ def build_documentation( overwrite: bool = False, repo_owner: str = "MODFLOW-USGS" ): - print(f"Building {'full' if full else 'full'} documentation") + print(f"Building {'full' if full else 'minimal'} documentation") bin_path = Path(bin_path).expanduser().absolute() output_path = Path(output_path).expanduser().absolute() diff --git a/distribution/check_dist.py b/distribution/check_dist.py index be7c9136140..d5f8e91ceb7 100644 --- a/distribution/check_dist.py +++ b/distribution/check_dist.py @@ -1,5 +1,4 @@ import platform -import re import subprocess from os import environ from pathlib import Path @@ -9,12 +8,31 @@ from utils import split_nonnumeric + +# OS-specific extensions _system = platform.system() _eext = ".exe" if _system == "Windows" else "" _soext = ".dll" if _system == "Windows" else ".so" if _system == "Linux" else ".dylib" _scext = ".bat" if _system == "Windows" else ".sh" + +# fortran compiler _fc = environ.get("FC", None) +# directories included in full distribution +_included_dir_paths = {"full": [ + "bin", + "doc", + "examples", + "src", + "srcbmi", + "msvs", + "make", + "utils", +], "minimal": [ + "bin", + "src", +]} + @pytest.fixture def approved(request): @@ -47,7 +65,12 @@ def skip(): return path -def test_sources(dist_dir_path, approved, releasemode, full): +def test_directories(dist_dir_path, full): + for dir_path in _included_dir_paths["full" if full else "minimal"]: + assert (dist_dir_path / dir_path).is_dir() + + +def test_sources(dist_dir_path, releasemode, full): if not full: pytest.skip(reason="sources not included in minimal distribution") From 15f6f3f664bb9752c9efadaf9deaa9a45e8eb8a3 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Thu, 13 Jul 2023 16:41:21 -0400 Subject: [PATCH 08/11] include meson.options in full dist --- distribution/build_dist.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/build_dist.py b/distribution/build_dist.py index 9aba5099e0a..6de4c7661ad 100644 --- a/distribution/build_dist.py +++ b/distribution/build_dist.py @@ -62,8 +62,9 @@ def copy_sources(output_path: PathLike): ignored = shutil.ignore_patterns(".DS_Store") - # copy top-level meson.build + # copy top-level meson.build and meson.options shutil.copy(_project_root_path / "meson.build", output_path) + shutil.copy(_project_root_path / "meson.options", output_path) # copy source folder src_path = _project_root_path / "src" From e6e6caad2e666de6c54a9a2eb84fe4dc2585f2d5 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Fri, 14 Jul 2023 00:04:28 -0400 Subject: [PATCH 09/11] fix version strings subbed into release notes, update compiling section --- doc/ReleaseNotes/ReleaseNotes.tex | 12 +++--------- doc/ReleaseNotes/develop.tex | 2 +- doc/ReleaseNotes/folder_struct.tex | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/doc/ReleaseNotes/ReleaseNotes.tex b/doc/ReleaseNotes/ReleaseNotes.tex index f1a8b80570d..2655e9d014d 100644 --- a/doc/ReleaseNotes/ReleaseNotes.tex +++ b/doc/ReleaseNotes/ReleaseNotes.tex @@ -251,21 +251,15 @@ \section{Installation and Execution} % ------------------------------------------------- \section{Compiling MODFLOW~6} -MODFLOW~6 has been compiled using Intel Fortran and GNU Fortran on the Windows, macOS, and Linux operating systems. All MODFLOW~6 distributions are currently compiled with Intel Fortran. While the program uses relatively new Fortran functionality, it is not yet compatible with the latest versions of either toolchain. +MODFLOW~6 has been compiled using Intel Fortran and GNU Fortran on Windows, macOS, and several Linux operating systems. All MODFLOW~6 distributions are currently compiled with Intel Fortran. Because the program uses relatively new Fortran functionality, recent versions of the compilers may be required for successful compilation. MODFLOW~6 is not yet compatible with the latest versions of the Intel toolchain, however. -MODFLOW~6 is currently tested with gfortran 7-12 on Linux and gfortran 12 on macOS and Windows. The gfortran version can be queried with ``\verb|gfortran --version|''. Intel Fortran version 2022.3.0 is tested on all three platforms. Some 2021 versions have also been reported compatible. - -At this time, MODFLOW~6 is not compatible with: - -- GNU Fortran 13 -- Intel Fortran Compiler Classic versions 2023.y.z -- the next-generation Intel Fortran Compiler `ifx` +MODFLOW~6 is currently tested with gfortran 7-12 on Linux and gfortran 12 on macOS and Windows. The gfortran version can be queried with ``\verb|gfortran --version|''. Intel Fortran Compiler Classic version 2022.3.0 is currently tested on all three platforms. Some 2021 versions have also been reported compatible. At this time, MODFLOW~6 is not compatible with the next-generation Intel Fortran Compiler `ifx`. Meson is the recommended build tool for MODFLOW~6. For more detailed compilation instructions, please refer to \url{https://github.com/MODFLOW-USGS/modflow6/blob/develop/DEVELOPER.md#building}. This distribution contains the Microsoft Visual Studio solution and project files for compiling MODFLOW~6 on Windows using the Intel Fortran Compiler Classic. The files have been used successfully with recent versions of Microsoft Visual Studio Community 2019 and the Intel Fortran Compiler Classic. -This distribution also comes with a makefile for compiling MODFLOW~6 with \texttt{gfortran}. The makefile is contained in the \texttt{make} folder. +This distribution also includes a makefile for compiling MODFLOW~6 with \texttt{gfortran}. The makefile is contained in the \texttt{make} folder. For those familiar with Python, the pymake package can also be used to compile MODFLOW~6. Additional information on the Python pymake utility can be found at: \url{https://github.com/modflowpy/pymake}. diff --git a/doc/ReleaseNotes/develop.tex b/doc/ReleaseNotes/develop.tex index c64400bd1de..5993caf38d2 100644 --- a/doc/ReleaseNotes/develop.tex +++ b/doc/ReleaseNotes/develop.tex @@ -1,7 +1,7 @@ % Use this template for starting initializing the release notes % after a release has just been made. - \item \currentmodflowversion\_[ostag] + \item \currentmodflowversion %\underline{NEW FUNCTIONALITY} %\begin{itemize} diff --git a/doc/ReleaseNotes/folder_struct.tex b/doc/ReleaseNotes/folder_struct.tex index 18039e95474..7d52bc9562a 100644 --- a/doc/ReleaseNotes/folder_struct.tex +++ b/doc/ReleaseNotes/folder_struct.tex @@ -1,5 +1,5 @@ \begin{verbatim} -\currentmodflowversion\_[ostag] +\currentmodflowversion bin/ doc/ examples/ From 9be68c725129cd956518f6787f32dfb1df08a3b1 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Fri, 14 Jul 2023 12:37:24 -0400 Subject: [PATCH 10/11] fix folder_struct.tex --- doc/ReleaseNotes/folder_struct.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ReleaseNotes/folder_struct.tex b/doc/ReleaseNotes/folder_struct.tex index 7d52bc9562a..544ea59f8e8 100644 --- a/doc/ReleaseNotes/folder_struct.tex +++ b/doc/ReleaseNotes/folder_struct.tex @@ -1,5 +1,5 @@ \begin{verbatim} -\currentmodflowversion +\modflowversion bin/ doc/ examples/ From 771440798bebe479bdf086e4b8454fde75f96200 Mon Sep 17 00:00:00 2001 From: w-bonelli Date: Fri, 14 Jul 2023 15:51:59 -0400 Subject: [PATCH 11/11] reformat dist scripts --- distribution/build_dist.py | 8 ++----- distribution/build_docs.py | 41 ++++++++++++++++++--------------- distribution/build_makefiles.py | 2 +- distribution/check_dist.py | 34 +++++++++++++-------------- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/distribution/build_dist.py b/distribution/build_dist.py index 6de4c7661ad..68c454ec650 100644 --- a/distribution/build_dist.py +++ b/distribution/build_dist.py @@ -16,14 +16,10 @@ from modflow_devtools.misc import get_model_paths from build_docs import build_documentation -from build_makefiles import ( - build_mf6_makefile, - build_mf5to6_makefile, - build_zbud6_makefile, -) +from build_makefiles import (build_mf5to6_makefile, build_mf6_makefile, + build_zbud6_makefile) from utils import get_project_root_path, run_command - # default paths _project_root_path = get_project_root_path() _examples_repo_path = _project_root_path.parent / "modflow6-examples" diff --git a/distribution/build_docs.py b/distribution/build_docs.py index 1990061bb37..37d5ad57fa6 100644 --- a/distribution/build_docs.py +++ b/distribution/build_docs.py @@ -5,7 +5,7 @@ import sys import textwrap from datetime import datetime -from os import environ, PathLike +from os import PathLike, environ from pathlib import Path from pprint import pprint from tempfile import TemporaryDirectory @@ -16,18 +16,13 @@ import pytest from flaky import flaky from modflow_devtools.build import meson_build -from modflow_devtools.download import ( - list_artifacts, - download_artifact, - get_release, - download_and_unzip, -) +from modflow_devtools.download import (download_and_unzip, download_artifact, + get_release, list_artifacts) from modflow_devtools.markers import requires_exe, requires_github -from modflow_devtools.misc import set_dir, run_cmd, is_in_ci +from modflow_devtools.misc import is_in_ci, run_cmd, set_dir from benchmark import run_benchmarks -from utils import convert_line_endings -from utils import get_project_root_path +from utils import convert_line_endings, get_project_root_path # paths _project_root_path = get_project_root_path() @@ -105,7 +100,9 @@ def clean_tex_files(): assert not os.path.isfile(str(pth) + ".pdf") -def download_benchmarks(output_path: PathLike, verbose: bool = False, repo_owner: str = "MODFLOW-USGS") -> Optional[Path]: +def download_benchmarks( + output_path: PathLike, verbose: bool = False, repo_owner: str = "MODFLOW-USGS" +) -> Optional[Path]: output_path = Path(output_path).expanduser().absolute() name = "run-time-comparison" # todo make configurable repo = f"{repo_owner}/modflow6" # todo make configurable, add pytest/cli args @@ -137,12 +134,18 @@ def github_user() -> Optional[str]: @flaky @requires_github def test_download_benchmarks(tmp_path, github_user): - path = download_benchmarks(tmp_path, verbose=True, repo_owner=github_user if github_user else "MODFLOW-USGS") + path = download_benchmarks( + tmp_path, + verbose=True, + repo_owner=github_user if github_user else "MODFLOW-USGS", + ) if path: assert path.name == "run-time-comparison.md" -def build_benchmark_tex(output_path: PathLike, overwrite: bool = False, repo_owner: str = "MODFLOW-USGS"): +def build_benchmark_tex( + output_path: PathLike, overwrite: bool = False, repo_owner: str = "MODFLOW-USGS" +): _benchmarks_path.mkdir(parents=True, exist_ok=True) benchmarks_path = _benchmarks_path / "run-time-comparison.md" @@ -436,7 +439,7 @@ def build_documentation( full: bool = False, output_path: Optional[PathLike] = None, overwrite: bool = False, - repo_owner: str = "MODFLOW-USGS" + repo_owner: str = "MODFLOW-USGS", ): print(f"Building {'full' if full else 'minimal'} documentation") @@ -448,7 +451,7 @@ def build_documentation( # build LaTex input/output docs from DFN files build_mf6io_tex_from_dfn(overwrite=True) - + # build LaTeX input/output example model docs with TemporaryDirectory() as temp: example_path = _project_root_path / ".mf6minsim" @@ -466,7 +469,9 @@ def build_documentation( build_pdfs_from_tex(tex_paths=_dev_dist_tex_paths, output_path=output_path) else: # convert benchmarks to LaTex, running them first if necessary - build_benchmark_tex(output_path=output_path, overwrite=overwrite, repo_owner=repo_owner) + build_benchmark_tex( + output_path=output_path, overwrite=overwrite, repo_owner=repo_owner + ) # download example docs latest = get_release(f"{repo_owner}/modflow6-examples", "latest") @@ -565,7 +570,7 @@ def test_build_documentation(tmp_path): "--repo-owner", required=False, default="MODFLOW-USGS", - help="Repository owner (substitute your own for a fork)" + help="Repository owner (substitute your own for a fork)", ) args = parser.parse_args() output_path = Path(args.output_path).expanduser().absolute() @@ -576,5 +581,5 @@ def test_build_documentation(tmp_path): full=args.full, output_path=output_path, overwrite=args.force, - repo_owner=args.repo_owner + repo_owner=args.repo_owner, ) diff --git a/distribution/build_makefiles.py b/distribution/build_makefiles.py index ce441200775..e9fb09645db 100644 --- a/distribution/build_makefiles.py +++ b/distribution/build_makefiles.py @@ -6,8 +6,8 @@ import pymake import pytest from flaky import flaky -from modflow_devtools.misc import set_dir from modflow_devtools.markers import requires_exe +from modflow_devtools.misc import set_dir from utils import get_modified_time, get_project_root_path diff --git a/distribution/check_dist.py b/distribution/check_dist.py index d5f8e91ceb7..0ee03e974b5 100644 --- a/distribution/check_dist.py +++ b/distribution/check_dist.py @@ -8,7 +8,6 @@ from utils import split_nonnumeric - # OS-specific extensions _system = platform.system() _eext = ".exe" if _system == "Windows" else "" @@ -19,19 +18,22 @@ _fc = environ.get("FC", None) # directories included in full distribution -_included_dir_paths = {"full": [ - "bin", - "doc", - "examples", - "src", - "srcbmi", - "msvs", - "make", - "utils", -], "minimal": [ - "bin", - "src", -]} +_included_dir_paths = { + "full": [ + "bin", + "doc", + "examples", + "src", + "srcbmi", + "msvs", + "make", + "utils", + ], + "minimal": [ + "bin", + "src", + ], +} @pytest.fixture @@ -168,9 +170,7 @@ def test_examples(dist_dir_path, full): script_path = p / f"run{_scext}" if not script_path.is_file(): continue - pprint( - subprocess.check_output([str(script_path)], cwd=p).decode().split() - ) + pprint(subprocess.check_output([str(script_path)], cwd=p).decode().split()) break