Skip to content

Commit

Permalink
feat(ostags): add OS tag conversion utilities (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
wpbonelli authored Aug 5, 2023
1 parent 9cda074 commit 33ab22a
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Python development tools for MODFLOW 6.

This is a small toolkit for developing MODFLOW 6, FloPy, and related projects. It includes standalone utilities and optional [Pytest](https://github.com/pytest-dev/pytest) extensions.

Standalone utilities include a very minimal GitHub API client, mainly for retrieving release information and downloading assets, and a `ZipFile` subclass that [preserves file permissions](https://stackoverflow.com/questions/39296101/python-zipfile-removes-execute-permissions-from-binaries) (workaround for [Python #15795](https://bugs.python.org/issue15795))
The former include a very minimal GitHub API client for retrieving release information and downloading assets, a `ZipFile` subclass that [preserves file permissions](https://stackoverflow.com/questions/39296101/python-zipfile-removes-execute-permissions-from-binaries) (workaround for [Python #15795](https://bugs.python.org/issue15795)), and other release/distribution-related tools.

Pytest features include:

Expand Down
45 changes: 45 additions & 0 deletions docs/md/ostags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# OS Tags

MODFLOW 6, Python3, build servers, and other systems may refer to operating systems by different names. Utilities are provided in the `modflow_devtools.ostags` module to convert between

- the output of `platform.system()`
- GitHub Actions `runner.os` tags
- MODFLOW 6 release asset OS tags

Only Linux, Mac and Windows are supported.

## Tag specification

Python3's `platform.system()` returns "Linux", "Darwin", and "Windows", respectively.

GitHub Actions (e.g. `runner.os` context) use "Linux", "macOS" and "Windows".

MODFLOW 6 release asset names end with "linux", "mac" or "win64".

## Getting tags

To get the MODFLOW 6 or GitHub tag for the current OS, use:

- `get_modflow_ostag()`
- `get_github_ostag()`

## Converting tags

Conversion functions are available for each direction:

- `python_to_modflow_ostag(tag)`
- `modflow_to_python_ostag(tag)`
- `modflow_to_github_ostag(tag)`
- `github_to_modflow_ostag(tag)`
- `python_to_github_ostag(tag)`
- `github_to_python_ostag(tag)`

Alternatively:

```python
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.
147 changes: 147 additions & 0 deletions modflow_devtools/ostags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"""
MODFLOW 6, Python3, and build servers may all refer to operating
systems by different names. This module contains conversion utilities.
"""


from enum import Enum
from platform import system

_system = system()


def get_modflow_ostag() -> str:
if _system == "Windows":
return "win64"
elif _system == "Linux":
return "linux"
elif _system == "Darwin":
return "mac"
else:
raise NotImplementedError(f"Unsupported system: {_system}")


def get_github_ostag() -> str:
if _system in ("Windows", "Linux"):
return _system
elif _system == "Darwin":
return "macOS"
else:
raise NotImplementedError(f"Unsupported system: {_system}")


def python_to_modflow_ostag(tag: str) -> str:
"""
Convert a platform.system() string to an ostag as expected
by MODFLOW 6.
Parameters
----------
platform_system : str
The platform.system() string.
Returns
-------
str
"""

if tag == "Windows":
return "win64"
elif tag == "Linux":
return "linux"
elif tag == "Darwin":
return "mac"
else:
raise ValueError(f"Invalid or unsupported tag: {tag}")


def modflow_to_python_ostag(tag: str) -> str:
"""
Convert a MODFLOW os tag to a platform.system() string.
Parameters
----------
tag : str
The MODFLOW os tag.
Returns
-------
str
"""

if tag == "win64":
return "Windows"
elif tag == "linux":
return "Linux"
elif tag == "mac":
return "Darwin"
else:
raise ValueError(f"Invalid or unsupported tag: {tag}")


def modflow_to_github_ostag(tag: str) -> str:
if tag == "win64":
return "Windows"
elif tag == "linux":
return "Linux"
elif tag == "mac":
return "macOS"
else:
raise ValueError(f"Invalid modflow os tag: {tag}")


def github_to_modflow_ostag(tag: str) -> str:
if tag == "Windows":
return "win64"
elif tag == "Linux":
return "linux"
elif tag == "macOS":
return "mac"
else:
raise ValueError(f"Invalid github os tag: {tag}")


def python_to_github_ostag(tag: str) -> str:
return modflow_to_github_ostag(python_to_modflow_ostag(tag))


def github_to_python_ostag(tag: str) -> str:
return modflow_to_python_ostag(github_to_modflow_ostag(tag))


def get_ostag(kind: str = "modflow") -> str:
if kind == "modflow":
return get_modflow_ostag()
elif kind == "github":
return get_github_ostag()
else:
raise ValueError(f"Invalid kind: {kind}")


class OSTagCvt(Enum):
py2mf = "py2mf"
mf2py = "mf2py"
gh2mf = "gh2mf"
mf2gh = "mf2gh"
py2gh = "py2gh"
gh2py = "gh2py"


class OSTag:
@staticmethod
def convert(tag: str, cvt: str) -> str:
cvt = OSTagCvt(cvt)
if cvt == OSTagCvt.py2mf:
return python_to_modflow_ostag(tag)
elif cvt == OSTagCvt.mf2py:
return modflow_to_python_ostag(tag)
elif cvt == OSTagCvt.gh2mf:
return github_to_modflow_ostag(tag)
elif cvt == OSTagCvt.mf2gh:
return modflow_to_github_ostag(tag)
elif cvt == OSTagCvt.py2gh:
return python_to_github_ostag(tag)
elif cvt == OSTagCvt.gh2py:
return github_to_python_ostag(tag)
else:
raise ValueError(f"Unsupported mapping: {cvt}")
55 changes: 55 additions & 0 deletions modflow_devtools/test/test_ostags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from platform import system

import pytest
from modflow_devtools.ostags import OSTag, get_github_ostag, get_modflow_ostag

_system = system()


def test_get_modflow_ostag():
t = get_modflow_ostag()
if _system == "Windows":
assert t == "win64"
elif _system == "Linux":
assert t == "linux"
elif _system == "Darwin":
assert t == "mac"
else:
pytest.skip(reason="Unsupported platform")


def test_get_github_ostag():
t = get_github_ostag()
if _system in ("Windows", "Linux"):
assert t == _system
elif _system == "Darwin":
assert t == "macOS"
else:
pytest.skip(reason="Unsupported platform")


@pytest.mark.parametrize(
"cvt,tag,exp",
[
("py2mf", "Windows", "win64"),
("mf2py", "win64", "Windows"),
("py2mf", "Darwin", "mac"),
("mf2py", "mac", "Darwin"),
("py2mf", "Linux", "linux"),
("mf2py", "linux", "Linux"),
("gh2mf", "Windows", "win64"),
("mf2gh", "win64", "Windows"),
("gh2mf", "macOS", "mac"),
("mf2gh", "mac", "macOS"),
("gh2mf", "Linux", "linux"),
("mf2gh", "linux", "Linux"),
("py2gh", "Windows", "Windows"),
("gh2py", "Windows", "Windows"),
("py2gh", "Darwin", "macOS"),
("gh2py", "macOS", "Darwin"),
("py2gh", "Linux", "Linux"),
("gh2py", "Linux", "Linux"),
],
)
def test_ostag_convert(cvt, tag, exp):
assert OSTag.convert(tag, cvt) == exp

0 comments on commit 33ab22a

Please sign in to comment.