Skip to content

Commit

Permalink
feat(get-modflow): allow specifying repo owner
Browse files Browse the repository at this point in the history
* support --owner arg and corresponding params on run_main() and other fns
* update tests to allow configuring multiple owners (e.g. personal forks)
  • Loading branch information
wpbonelli committed Aug 8, 2023
1 parent c25c0b3 commit 57bf4e5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 15 deletions.
21 changes: 15 additions & 6 deletions autotest/test_get_modflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
/ ("Scripts" if system() == "Windows" else "bin"),
"home": Path.home() / ".local" / "bin",
}
owner_options = [
"MODFLOW-USGS",
]
repo_options = {
"executables": [
"crt",
Expand Down Expand Up @@ -95,14 +98,14 @@ def append_ext(path: str):
@pytest.mark.parametrize("per_page", [-1, 0, 101, 1000])
def test_get_releases_bad_page_size(per_page):
with pytest.raises(ValueError):
get_releases("executables", per_page=per_page)
get_releases(repo="executables", per_page=per_page)


@flaky
@requires_github
@pytest.mark.parametrize("repo", repo_options.keys())
def test_get_releases(repo):
releases = get_releases(repo)
releases = get_releases(repo=repo)
assert "latest" in releases


Expand All @@ -111,7 +114,7 @@ def test_get_releases(repo):
@pytest.mark.parametrize("repo", repo_options.keys())
def test_get_release(repo):
tag = "latest"
release = get_release(repo, tag)
release = get_release(repo=repo, tag=tag)
assets = release["assets"]

expected_assets = ["linux.zip", "mac.zip", "win64.zip"]
Expand Down Expand Up @@ -245,11 +248,14 @@ def test_script_valid_options(function_tmpdir, downloads_dir):
@flaky
@requires_github
@pytest.mark.slow
@pytest.mark.parametrize("owner", owner_options)
@pytest.mark.parametrize("repo", repo_options.keys())
def test_script(function_tmpdir, repo, downloads_dir):
def test_script(function_tmpdir, owner, repo, downloads_dir):
bindir = str(function_tmpdir)
stdout, stderr, returncode = run_get_modflow_script(
bindir,
"--owner",
owner,
"--repo",
repo,
"--downloads-dir",
Expand All @@ -267,11 +273,14 @@ def test_script(function_tmpdir, repo, downloads_dir):
@flaky
@requires_github
@pytest.mark.slow
@pytest.mark.parametrize("owner", owner_options)
@pytest.mark.parametrize("repo", repo_options.keys())
def test_python_api(function_tmpdir, repo, downloads_dir):
def test_python_api(function_tmpdir, owner, repo, downloads_dir):
bindir = str(function_tmpdir)
try:
get_modflow(bindir, repo=repo, downloads_dir=downloads_dir)
get_modflow(
bindir, owner=owner, repo=repo, downloads_dir=downloads_dir
)
except HTTPError as err:
if err.code == 403:
pytest.skip(f"GitHub {rate_limit_msg}")
Expand Down
4 changes: 3 additions & 1 deletion docs/get_modflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Other auto-select options are only available if the current user can write files

## Selecting a distribution

By default the distribution from the [executables repository](https://github.com/MODFLOW-USGS/executables) is installed. This includes the MODFLOW 6 binary `mf6` and over 20 other related programs. The utility can also install from the main [MODFLOW 6 repo](https://github.com/MODFLOW-USGS/modflow6) or the [nightly build](https://github.com/MODFLOW-USGS/modflow6-nightly-build) distributions, which contain only:
By default the distribution from the [`MODFLOW-USGS/executables` repository](https://github.com/MODFLOW-USGS/executables) is installed. This includes the MODFLOW 6 binary `mf6` and over 20 other related programs. The utility can also install from the main [MODFLOW 6 repo](https://github.com/MODFLOW-USGS/modflow6) or the [nightly build](https://github.com/MODFLOW-USGS/modflow6-nightly-build) distributions, which contain only:

- `mf6`
- `mf5to6`
Expand All @@ -85,3 +85,5 @@ To select a distribution, specify a repository name with the `--repo` command li
- `executables` (default)
- `modflow6`
- `modflow6-nightly-build`

The repository owner can also be configured with the `--owner` option. This can be useful for installing from unreleased MODFLOW 6 feature branches still in development — the only compatibility requirement is that release assets be named identically to those on the official repositories.
32 changes: 24 additions & 8 deletions flopy/utils/get_modflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@

from typing import Dict, List, Tuple

owner = "MODFLOW-USGS"
default_owner = "MODFLOW-USGS"
default_repo = "executables"
# key is the repo name, value is the renamed file prefix for the download
renamed_prefix = {
"modflow6": "modflow6",
Expand Down Expand Up @@ -93,8 +94,12 @@ def get_request(url, params={}):
return urllib.request.Request(url, headers=headers)


def get_releases(repo, quiet=False, per_page=None) -> List[str]:
def get_releases(
owner=None, repo=None, quiet=False, per_page=None
) -> List[str]:
"""Get list of available releases."""
owner = default_owner if owner is None else owner
repo = default_repo if repo is None else repo
req_url = f"https://api.github.com/repos/{owner}/{repo}/releases"

params = {}
Expand Down Expand Up @@ -133,8 +138,10 @@ def get_releases(repo, quiet=False, per_page=None) -> List[str]:
return avail_releases


def get_release(repo, tag="latest", quiet=False) -> dict:
def get_release(owner=None, repo=None, tag="latest", quiet=False) -> dict:
"""Get info about a particular release."""
owner = default_owner if owner is None else owner
repo = default_repo if repo is None else repo
api_url = f"https://api.github.com/repos/{owner}/{repo}"
req_url = (
f"{api_url}/releases/latest"
Expand Down Expand Up @@ -166,7 +173,7 @@ def get_release(repo, tag="latest", quiet=False) -> dict:
) from err
elif err.code == 404:
if releases is None:
releases = get_releases(repo, quiet)
releases = get_releases(owner, repo, quiet)
if tag not in releases:
raise ValueError(
f"Release {tag} not found (choose from {', '.join(releases)})"
Expand Down Expand Up @@ -287,7 +294,8 @@ def select_bindir(bindir, previous=None, quiet=False, is_cli=False) -> Path:

def run_main(
bindir,
repo="executables",
owner=default_owner,
repo=default_repo,
release_id="latest",
ostag=None,
subset=None,
Expand All @@ -304,6 +312,8 @@ def run_main(
Writable path to extract executables. Auto-select options start with a
colon character. See error message or other documentation for further
information on auto-select options.
owner : str, default "MODFLOW-USGS"
Name of GitHub repository owner (user or organization).
repo : str, default "executables"
Name of GitHub repository. Choose one of "executables" (default),
"modflow6", or "modflow6-nightly-build".
Expand Down Expand Up @@ -393,7 +403,7 @@ def run_main(
)

# get the selected release
release = get_release(repo, release_id, quiet)
release = get_release(owner, repo, release_id, quiet)
assets = release.get("assets", [])

for asset in assets:
Expand Down Expand Up @@ -683,11 +693,17 @@ def cli_main():
"Option ':system' is '/usr/local/bin'."
)
parser.add_argument("bindir", help=bindir_help)
parser.add_argument(
"--owner",
type=str,
default=default_owner,
help=f"GitHub repository owner; default is '{default_owner}'.",
)
parser.add_argument(
"--repo",
choices=available_repos,
default="executables",
help="Name of GitHub repository; default is 'executables'.",
default=default_repo,
help=f"Name of GitHub repository; default is '{default_repo}'.",
)
parser.add_argument(
"--release-id",
Expand Down

0 comments on commit 57bf4e5

Please sign in to comment.