Skip to content

Commit

Permalink
Merge branch 'releases/0.9.x' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
jlorieau committed Jul 30, 2023
2 parents bc04ec7 + 237c602 commit a3723ea
Show file tree
Hide file tree
Showing 15 changed files with 258 additions and 133 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e .[dev]
python -m pip install .[dev]
- name: Test with pytest
run: |
pytest --log-level=DEBUG
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,21 @@ resources, or for checking environments that use the
<!-- start features -->
Geomancy checks include:

- __Operating systems__ meet the minimum required versions
([checkOS](https://geomancy.readthedocs.io/en/latest/usage/format.html#checkplatform))
- __Environment variables__ are properly set and, optionally,
check that they have valid values with regular expressions
([checkEnv](https://geomancy.readthedocs.io/en/latest/usage/index.html#checkenv))
([checkEnv](https://geomancy.readthedocs.io/en/latest/usage/format.html#checkenv))
- __Paths__ exist and whether they're files or directories
([checkPath](https://geomancy.readthedocs.io/en/latest/usage/index.html#checkpath))
([checkPath](https://geomancy.readthedocs.io/en/latest/usage/format.html#checkpath))
- __Executables__ are available and, optionally, have the minimum or correct
versions
([checkExec](https://geomancy.readthedocs.io/en/latest/usage/index.html#checkexec))
([checkExec](https://geomancy.readthedocs.io/en/latest/usage/format.html#checkexec))
- __Python packages__ are available and, optionally, have the minimum or
correct versions
([checkPythonPkg](https://geomancy.readthedocs.io/en/latest/usage/index.html#checkpythonpkg))
([checkPythonPkg](https://geomancy.readthedocs.io/en/latest/usage/format.html#checkpythonpkg))
- __Group checks__ to nested groups of checks with conditional (all or any) pass
criteria ([groups of checks](https://geomancy.readthedocs.io/en/latest/usage/index.html#check-groups))
criteria ([groups of checks](https://geomancy.readthedocs.io/en/latest/usage/format.html#check-groups))

Additionally, geomancy can:

Expand Down
13 changes: 13 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ deprecations section.

<!-- towncrier release notes start -->

## [0.9.4](https://github.com/jlorieau/geomancy/tree/0.9.4) - 2023-07-29


### Features

- [#14](https://github.com/jlorieau/geomancy/issues/14). Added checkPlatform check for checking minimum OS versions


### Improved Documentation

- [#14](https://github.com/jlorieau/geomancy/issues/14). Added documentation for checkPlatform check


## [0.9.3](https://github.com/jlorieau/geomancy/tree/0.9.3) - 2023-07-29


Expand Down
71 changes: 70 additions & 1 deletion docs/usage/format.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,75 @@ Pyproject = { checkPath = "./pyproject.toml", type = "file" }
:::
::::

### checkPlatform

Check the current platform and, optionally, its minimum version.

:::{card}
Parameters
^^^
`checkPlatform`: str
: Operating system to check. Additionally, an optional version check can be added
with a test operator. <br>
__aliases__: ``checkOS``, ``checkPlatform``

{{check_base_args}}
:::

::::{tab-set}
:::{tab-item} Example 1 (yaml)
The ``checkPlatform`` check in YAML format.
```yaml
check:
OperatingSystem:
desc: Check the minimum operating system versions
subchecks: any

checkMacOS:
desc: MacOS 10.9 or later (released 2013)
checkOS: "macOS >= 10.9"
checkLinuxOS:
desc: Linux 4.0 or later (released 2015)
checkOS: "Linux >= 3.0"
checkWindows:
desc: Windows 10 or later (released 2015)
checkOS: "Windows >= 10"
```
:::
:::{tab-item} Example 2 (toml)
The ``checkPlatfor`` check in TOML format.
```toml
[checks.OperatingSystem]
desc = "Check the minimum operating system versions"
subchecks = "any"

[checks.OperatingSystem.checkMacOS]
desc = "MacOS 10.9 or later (released 2013)"
checkOS = "macOS >= 10.9"

[checks.OperatingSystem.checkLinuxOS]
desc = "Linux 4.0 or later (released 2015)"
checkOS = "Linux >= 3.0"

[checks.OperatingSystem.checkWindows]
desc = "Windows 10 or later (released 2015)"
checkOS = "Windows >= 10"
```
:::
:::{tab-item} Example 3 (toml)
The ``checkPlatform`` check in abbreviated TOML format.
```toml
[checks.OperatingSystem]
desc = "Check the minimum operating system versions"
subchecks = "any"

checkMacOS = {desc = "MacOS 10.9 or later (released 2013)", checkOS = "macOS >= 10.9"}
checkLinuxOS = {desc = "Linux 4.0 or later (released 2015)", checkOS = "Linux >= 3.0"}
checkWindows = {desc = "Windows 10 or later (released 2015)", checkOS = "Windows >= 10"}
```
:::
::::

### checkPythonPkg

Checks whether the python package is installed and, optionally, check its
Expand Down Expand Up @@ -475,7 +544,7 @@ substitution=false
```
:::
:::{tab-item} Literal string (toml)
Use triple (4) single quotes
Use quadruple (4) single quotes
```yaml
[MyOddFilename]
checkpath=''''myfile$.txt''''
Expand Down
14 changes: 11 additions & 3 deletions examples/geomancy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,17 @@ desc = "Check environment variables common to all development environments"
checkEnv = "$PATH"

[checks.Environment.Username]
desc = "The current username"
checkEnv = "$USER"
regex = "[a-z_][a-z0-9_-]*[$]?"
subchecks = "any"

[checks.Environment.Username.UnixUsername] # linux and macOS
desc = "The current username"
checkEnv = "$USER"
regex = "[a-z_][a-z0-9_-]*[$]?"

[checks.Environment.Username.WindowsUsername] # windows
desc = "The current username"
checkEnv = "$USERNAME"
regex = "[a-z_][a-z0-9_-]*[$]?"

[checks.Paths]
desc = "Checks the existence of needed files and directories"
Expand Down
35 changes: 27 additions & 8 deletions examples/geomancy.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
# Configuration options
config:
config: # Configuration options
CHECKBASE:
env_substitute: True

# Nested changes
checks:
checks: # Nested checks
OperatingSystem:
desc: Check the minimum operating system versions
subchecks: any

checkMacOS:
desc: MacOS 10.9 or later (released 2013)
checkOS: "macOS >= 10.9"
checkLinuxOS:
desc: Linux 4.0 or later (released 2015)
checkOS: "Linux >= 3.0"
checkWindows:
desc: Windows 10 or later (released 2015)
checkOS: "Windows >= 10"

Environment:
desc: Check environment variables common to all development environments

Path:
decs: Paths to search for executables
checkEnv: "$PATH"
checkEnv: $PATH
Username:
desc: The current username
checkEnv: "$USER"
regex: "[a-z_][a-z0-9_-]*[$]?"
subchecks: any

UnixUsername: # Username on linux and macOS
desc: The current username
checkEnv: $USER
regex: "[a-z_][a-z0-9_-]*[$]?"
WindowsUsername: # Username on Windows
desc: The current username
checkEnv: $USERNAME
regex: "[a-z_][a-z0-9_-]*[$]?"

Paths:
desc: Checks the existence of needed files and directories
Expand Down
4 changes: 0 additions & 4 deletions examples/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,3 @@ desc = "Check environment variables common to all development environments"
desc = "Paths to search for executables"
checkEnv = "$PATH"

[tool.geomancy.checks.Environment.Username]
desc = "The current username"
checkEnv = "$USER"
regex = "[a-z_][a-z0-9_-]*[$]?"
2 changes: 1 addition & 1 deletion geomancy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from . import checks, cli, config, environment

# Project version
__version__ = (0, 9, 3) # Major, minor, patch, stage
__version__ = (0, 9, 4) # Major, minor, patch, stage


def get_version(version=__version__):
Expand Down
14 changes: 8 additions & 6 deletions geomancy/checks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
from .env import CheckEnv
from .path import CheckPath
from .exec import CheckExec
from .platform import CheckPlatform
from .python import CheckPythonPackage

__all__ = (
"CheckBase",
"CheckException",
"CheckEnv",
"CheckPath",
"CheckExec",
"CheckPythonPackage",
CheckBase,
CheckException,
CheckEnv,
CheckPath,
CheckExec,
CheckPlatform,
CheckPythonPackage,
)
12 changes: 12 additions & 0 deletions geomancy/checks/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@ def types_dict(cls) -> t.Dict[str, t.Type]:
if isabstract(cls_type):
continue

# Make sure class name isn't alreay in the dict
assert (
cls_type.__name__ not in d
), f"class {cls_type.__name__} already registered class"

# Add the class name directly
d[cls_type.__name__] = cls_type

Expand All @@ -273,6 +278,13 @@ def types_dict(cls) -> t.Dict[str, t.Type]:
# Aliases should not create name collisions
assert alias not in d, f"Duplicate alias name '{alias}'"

# Make sure the alias doesn't match a class that's already
# registered
assert (
alias not in d
), f"Alias {alias} already matches a registered class"

# Add alias
d[alias] = cls_type
return d

Expand Down
74 changes: 74 additions & 0 deletions geomancy/checks/platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
Checks the platform (Operating System) and its version
"""
import typing as t
import platform
import logging

from .base import CheckResult
from .version import CheckVersion
from .utils import version_to_tuple
from ..config import Parameter

__all__ = ("CheckPlatform",)

logger = logging.getLogger(__name__)


class CheckPlatform(CheckVersion):
"""Check the availability and version of a python package"""

# The message for checking python packages
msg = Parameter(
"CHECKPLATFORM.MSG",
default="Check platform '{check.raw_value}'...",
)

aliases = ("checkOS", "checkPlatform")

def get_current_platform(self) -> str:
"""Retrieve the OS platform name"""
uname = platform.uname()

if uname.system in ("Darwin",):
return "macOS"
elif uname.system in ("Linux",):
return "Linux"
elif uname.system in ("Microsoft", "Windows"):
return "Windows"
else:
raise NotImplementedError

def get_current_version(self) -> t.Union[None, t.Tuple[int]]:
"""Retrieve the OS current version"""
uname = platform.uname()

# Get the current OS version
current_platform = self.get_current_platform()

# This code follows 'platform.platform()' to some extent
if current_platform == "macOS":
release = platform.mac_ver()[0]
current_version = version_to_tuple(release) if release else None
elif current_platform in ("Linux", "Windows"):
current_version = version_to_tuple(uname.release) if uname.release else None
else:
current_version = None

logger.debug(
f"current_platform: {current_platform}, current_version: {current_version}"
)
return current_version

def check(self, level: int = 0) -> CheckResult:
"""Check whether the OS matches and the version"""
# Get the OS name checked against
name, op, version = self.value
current_platform = self.get_current_platform()

if current_platform.lower() != name.lower():
# Failed check if the platform doesn't match this check
return CheckResult(passed=False, msg=self.msg, status="wrong platform")

# Check the version, as usual
return super().check(level=level)
Loading

0 comments on commit a3723ea

Please sign in to comment.