import os
from typing import Optional, Any
"""gpilib2 utility methods"""
[docs]def gpilib2_data_dir(indir: Optional[str] = None) -> str:
"""Returns the full path to the gpilib2 data directory
Order of selection priority is:
1. Input (indir)
2. Environment variable (GPILIB2_DATA_DIR)
3. Default ($HOME/gpilib2_data)
Args:
indir (str or None):
Full path to data directory. Environment variables allowed.
Returns:
str:
Full absolute path to data directory
.. note::
If path does not exist, it will be created. Path must have read/write/access
permissions.
"""
# try input if given
if indir is not None:
# expand path
outdir = os.path.normpath(os.path.expandvars(indir))
elif "GPILIB2_DATA_DIR" in os.environ:
outdir = os.path.normpath(os.path.expandvars(os.environ["GPILIB2_DATA_DIR"]))
else:
outdir = os.path.join(os.environ["HOME"], "gpilib2_data")
validate_directory(outdir, perms="rwx")
return outdir
[docs]def validate_directory(
outdir: str,
perms: Optional[str] = None,
mkdir: bool = True,
mode: Optional[int] = None,
) -> None:
"""Ensure that a directory exists and has proper permissions.
Attempt to create if it doesn't.
Args:
outdir (str):
Full path to directory
perms (str or None):
Required permissions. Any combination of 'r', 'w', 'x'.
mkdir (bool):
Attempt to create direcotry if it exists. Defaults True.
mode (int or None):
Apply this mode setting to any newly created directories. Ignored if mkdir
is False and when None.
Returns:
None
.. note::
The reason why we use os.chmod rather than sending the mode directly to os.mkdir
is that the latter will ignore mode settings in the presence of a conflicting
umask. Doing it this way ensures that permissions are actually properly set.
Remember that the mode is octal. For 777 you want input 0o777.
"""
# if it doesn't exist, try creating it
if not (os.path.isdir(outdir)) and mkdir:
os.mkdir(outdir)
if mode is not None:
os.chmod(outdir, mode)
assert os.path.isdir(outdir), "{} does not exist.".format(outdir)
if perms:
if "r" in perms:
assert os.access(outdir, os.R_OK), "{} is not readable.".format(outdir)
if "w" in perms:
assert os.access(outdir, os.W_OK), "{} is not writeable.".format(outdir)
if "x" in perms:
assert os.access(outdir, os.X_OK), "{} is not accessible.".format(outdir)
[docs]def get_tlc_root() -> str:
"""Return the TLC_ROOT directory
Args:
None
Returns:
str:
Full path to TLC_ROOT directory
.. note::
Environment variable $TLC_ROOT must be set.
"""
tlcroot = os.getenv("TLC_ROOT")
assert tlcroot is not None, "TLC_ROOT environment variable unset."
validate_directory(tlcroot, mkdir=False, perms="rx")
return tlcroot
[docs]def get_tlc_bindir() -> str:
"""Return TLC binary directory
Args:
None
Returns:
str:
Full path to binary directory
.. note::
If environment variable $TLC_BIN_DIR is set, then that will be used. Otherwise
the default is $TLC_ROOT/bin/linux64
"""
tlcbindir = os.getenv("TLC_BIN_DIR")
if not tlcbindir:
tlcbindir = os.path.join(get_tlc_root(), "bin", "linux64")
validate_directory(tlcbindir, mkdir=False, perms="rx")
return tlcbindir
[docs]def get_tlc_configdir() -> str:
"""Return TLC config directory
Args:
None
Returns:
str:
Full path to config directory
.. note::
If environment variable $TLC_CONFIG_DIR is set, then that will be used.
Otherwise the default is $TLC_ROOT/config
"""
tlcconfigdir = os.getenv("TLC_CONFIG_DIR")
if not tlcconfigdir:
tlcconfigdir = os.path.join(get_tlc_root(), "config")
validate_directory(tlcconfigdir, mkdir=False, perms="rx")
return tlcconfigdir
[docs]def get_tlc_logdir() -> str:
"""Return TLC log directory
Args:
None
Returns:
str:
Full path to config directory
.. note::
If environment variable $TLC_LOG_DIR is set, then that will be used.
Otherwise the default is $TLC_ROOT/log
"""
tlclogdir = os.getenv("TLC_LOG_DIR")
if not tlclogdir:
tlclogdir = os.path.join(get_tlc_root(), "log")
validate_directory(tlclogdir, mkdir=False, perms="rx")
return tlclogdir