Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ostags,misc): deprecate fns in misc, add ostags alternatives #105

Merged
merged 1 commit into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/md/ostags.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,14 @@ OSTag.convert(platform.system(), "py2mf")
The second argument specifies the mapping in format `<source>2<target>`, where `<source>` and `<target>` may take values `py`, `mf`, or `gh`.

**Note**: source and target must be different.

## Getting suffixes

A convenience function is available to get the appropriate binary file extensions for a given operating system, identified by tag (or the current operating system if no tag is provided). The return value is a 2-tuple containing the executable and library extensions, respectively.

```python
get_binary_suffixes() # get extensions for current OS
get_binary_suffixes("linux") # returns ("", ".so")
get_binary_suffixes("linux") # returns ("", ".so")
get_binary_suffixes("win64") # returns (".exe", ".dll")
```
47 changes: 41 additions & 6 deletions modflow_devtools/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ def __exit__(self, exc_type, exc_value, traceback):


def get_ostag() -> str:
"""Determine operating system tag from sys.platform."""
"""
Determine operating system tag from sys.platform.

.. deprecated:: 1.1.0
Use ``ostags.get_modflow_ostag()`` instead.
"""
if sys.platform.startswith("linux"):
return "linux"
elif sys.platform.startswith("win"):
Expand All @@ -93,7 +98,12 @@ def get_ostag() -> str:


def get_suffixes(ostag) -> Tuple[str, str]:
"""Returns executable and library suffixes for the given OS (as returned by sys.platform)"""
"""
Returns executable and library suffixes for the given OS (as returned by sys.platform)

.. deprecated:: 1.1.0
Use ``ostags.get_binary_suffixes()`` instead.
"""

tag = ostag.lower()

Expand Down Expand Up @@ -136,6 +146,23 @@ def run_py_script(script, *args, verbose=False):


def get_current_branch() -> str:
"""
Tries to determine the name of the current branch, first by the GITHUB_REF
environent variable, then by asking ``git`` if GITHUB_REF is not set.

Returns
-------
str
name of the current branch

Raises
------
RuntimeError
if ``git`` is not available
ValueError
if the current branch could not be determined
"""

# check if on GitHub Actions CI
ref = environ.get("GITHUB_REF")
if ref is not None:
Expand All @@ -160,6 +187,7 @@ def get_packages(namefile_path: PathLike) -> List[str]:
----------
namefile_path : PathLike
path to MODFLOW 6 simulation or model name file

Returns
-------
a list of packages used by the simulation or model
Expand Down Expand Up @@ -215,7 +243,9 @@ def parse_model_namefile(line):


def has_package(namefile_path: PathLike, package: str) -> bool:
"""Determines whether the model with the given namefile contains the selected package"""
"""
Determines whether the model with the given namefile contains the selected package.
"""
packages = get_packages(namefile_path)
return package.lower() in packages

Expand Down Expand Up @@ -306,7 +336,9 @@ def get_model_paths(
def is_connected(hostname):
"""
Tests whether the given URL is accessible.
See https://stackoverflow.com/a/20913928/."""
See https://stackoverflow.com/a/20913928/.
"""

try:
host = socket.gethostbyname(hostname)
s = socket.create_connection((host, 80), 2)
Expand All @@ -318,7 +350,10 @@ def is_connected(hostname):


def is_in_ci():
"""Determines whether the current process is running GitHub Actions CI"""
"""
Determines whether the current process is running GitHub Actions CI
by checking for the "CI" environment variable.
"""

# if running in GitHub Actions CI, "CI" variable always set to true
# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
Expand All @@ -328,7 +363,7 @@ def is_in_ci():
def is_github_rate_limited() -> Optional[bool]:
"""
Determines if a GitHub API rate limit is applied to the current IP.
Running this function will consume an API request!
Calling this function will consume an API request!

Returns
-------
Expand Down
46 changes: 43 additions & 3 deletions modflow_devtools/ostags.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
"""
MODFLOW 6, Python3, and build servers may all refer to operating
systems by different names. This module contains conversion utilities.
MODFLOW 6, Python3, and GitHub Actions refer to operating
systems differently. This module contains conversion utilities.
"""


import sys
from enum import Enum
from platform import system
from typing import Tuple

_system = system()


def get_modflow_ostag() -> str:
if _system == "Windows":
return "win64"
return "win" + ("64" if sys.maxsize > 2**32 else "32")
elif _system == "Linux":
return "linux"
elif _system == "Darwin":
Expand All @@ -30,6 +32,44 @@ def get_github_ostag() -> str:
raise NotImplementedError(f"Unsupported system: {_system}")


def get_binary_suffixes(ostag: str = None) -> Tuple[str, str]:
"""
Returns executable and library suffixes for the given OS tag, if provided,
otherwise for the current operating system.

Parameters
----------
ostag : str, optional
The OS tag. May be provided in modflow, python, or github format.

Returns
-------
Tuple[str, str]
The executable and library suffixes, respectively.
"""

if ostag is None:
ostag = get_modflow_ostag()

def _suffixes(tag):
if tag in ["win32", "win64"]:
return ".exe", ".dll"
elif tag == "linux":
return "", ".so"
elif tag == "mac" or tag == "darwin":
return "", ".dylib"
else:
raise KeyError(f"unrecognized OS tag: {tag!r}")

try:
return _suffixes(ostag.lower())
except:
try:
return _suffixes(python_to_modflow_ostag(ostag))
except:
return _suffixes(github_to_modflow_ostag(ostag))


def python_to_modflow_ostag(tag: str) -> str:
"""
Convert a platform.system() string to an ostag as expected
Expand Down
41 changes: 40 additions & 1 deletion modflow_devtools/test/test_ostags.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from platform import system

import pytest
from modflow_devtools.ostags import OSTag, get_github_ostag, get_modflow_ostag
from modflow_devtools.ostags import (
OSTag,
get_binary_suffixes,
get_github_ostag,
get_modflow_ostag,
)

_system = system()

Expand Down Expand Up @@ -53,3 +58,37 @@ def test_get_github_ostag():
)
def test_ostag_convert(cvt, tag, exp):
assert OSTag.convert(tag, cvt) == exp


def test_get_binary_suffixes():
exe, lib = get_binary_suffixes()
if _system == "Windows":
assert exe == ".exe"
assert lib == ".dll"
elif _system == "Linux":
assert exe == ""
assert lib == ".so"
elif _system == "Darwin":
assert exe == ""
assert lib == ".dylib"


@pytest.mark.parametrize(
"tag,exe,lib",
[
("win64", ".exe", ".dll"),
("win32", ".exe", ".dll"),
("Windows", ".exe", ".dll"),
("linux", "", ".so"),
("Linux", "", ".so"),
("mac", "", ".dylib"),
("macOS", "", ".dylib"),
("Darwin", "", ".dylib"),
],
)
def test_get_binary_suffixes_given_tag(tag, exe, lib):
from modflow_devtools.misc import get_suffixes

assert get_binary_suffixes(tag) == (exe, lib)
if tag in ("win64", "win32", "linux", "mac"):
assert get_suffixes(tag) == (exe, lib)