hpcman.user.dotenv
Functions
print_reload_message
def print_reload_message() -> None
Source code in hpcman/hpcman/user/dotenv.py
| def print_reload_message() -> None:
logger.success(f"Remember to restart your shell (e.g. 'exec {get_shell()}') to see the changes.")
|
prefix_error
def prefix_error() -> None
Source code in hpcman/hpcman/user/dotenv.py
| def prefix_error() -> None:
logger.critical(f"Your {VARUSERPREFIX} is not set.")
logger.critical("Run 'hpcman user setup prefix' first to continue.")
exit(1)
|
is_str_dict
def is_str_dict(
values: dict[str, str | None]
) -> TypeGuard[dict[str, str]]
Source code in hpcman/hpcman/user/dotenv.py
| def is_str_dict(values: dict[str, str | None]) -> TypeGuard[dict[str, str]]:
return values is not None
|
is_path
def is_path(
value: Path | None
) -> TypeGuard[Path]
Source code in hpcman/hpcman/user/dotenv.py
| def is_path(value: Path | None) -> TypeGuard[Path]:
return value is not None
|
update_csh_envfile
def update_csh_envfile(
envfile: str | None = None,
envcshfile: str | None = None
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def update_csh_envfile(envfile: str | None = None, envcshfile: str | None = None) -> None:
if envfile is None:
envfile = environ.get(VARENVFILE, Path(get_default_config_path() / "env.sh").as_posix())
if envcshfile is None:
envcshfile = environ.get(VARENVCSHFILE, Path(get_default_config_path() / "env.csh").as_posix())
with open(envfile, "r") as envfh, open(envcshfile, "w") as envcshfh:
for line in envfh:
if line.startswith("export PATH="):
envcshfh.write(
line.replace('export PATH="', "set path = (", 1).replace(":", " ").replace('$PATH"', "$path)")
)
else:
envcshfh.write(line.replace("export", "setenv", 1).replace("=", " ", 1))
|
get_shell
Source code in hpcman/hpcman/user/dotenv.py
| def get_shell() -> str:
try:
shell: str = sh.detect_shell()[0]
except sh.ShellDetectionFailure:
shell = environ.get("SHELL", "bash")
return shell
|
prepend_path
def prepend_path(
dirname: str,
suppress_reload_message: bool = False
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def prepend_path(dirname: str, suppress_reload_message: bool = False) -> None:
logger.debug("Getting raw values from hpcman env file.")
logger.trace(f"raw_values = dotenv_values(environ[{VARENVFILE}])")
raw_values = dotenv_values(environ[VARENVFILE])
if not is_str_dict(raw_values):
logger.info("Setting up new $PATH var.")
pathvar = ""
else:
logger.info("Adding to already present $PATH var.")
logger.trace('pathvar = raw_values.get("PATH", "")')
pathvar = raw_values.get("PATH", "")
logger.debug("Splitting old PATH var")
pathlist = pathvar.split(":")
logger.trace(pathlist)
logger.debug("Removing duplicate '$PATH' entries.")
for x in ("$PATH", dirname, ""):
while x in pathlist:
pathlist.remove(x)
logger.debug(f"Prepending {dirname} and appending '$PATH'")
if pathlist:
pathlist.insert(0, dirname)
else:
pathlist = [dirname]
pathlist.append("$PATH")
logger.debug("Setting up string so it can be double instead of single quoted.")
pathstr = ":".join(pathlist)
logger.debug("Setting PATH variable into hpcman env file.")
logger.trace('set_key(environ[VARENVFILE], "PATH", ":".join(pathlist), export=True)')
if "PATH" in raw_values:
unset_key(environ[VARENVFILE], "PATH")
set_key(environ[VARENVFILE], "PATH", f'"{pathstr}"', export=True, quote_mode="never")
logger.debug("Checking for existence of just set PATH variable.")
if (value := get_key(environ[VARENVFILE], "PATH")) is not None:
logger.success(f"Successfully added {dirname} to path PATH={value}")
if not suppress_reload_message:
print_reload_message()
else:
logger.critical("Unable to set PATH properly!")
logger.critical(f"Check your env var {VARENVFILE} and your permissions for the file listed, if present.")
exit(1)
|
generate_rlibs_dir
def generate_rlibs_dir(
rscript: Path | None = None,
r_libs_user: str | None = None
) -> bool | None
Source code in hpcman/hpcman/user/dotenv.py
| def generate_rlibs_dir(rscript: Path | None = None, r_libs_user: str | None = None) -> bool | None:
if rscript is None:
if (result := which("Rscript")) is not None:
rscript = Path(result)
if not is_path(rscript):
logger.warning("Unable to find rscript program to make R_LIBS_USER directory.")
return False
# Set new_env to allow for modifying R_LIBS_USER, if provided
new_env = environ.copy()
if r_libs_user is None:
if (
environ.get("R_LIBS_USER") is None
and get_key(Path(Path.home() / ".Renviron").as_posix(), "R_LIBS_USER") is None
):
logger.warning("Unable to find R_LIBS_USER setting to generate rlibs dir.")
return False
else:
new_env["R_LIBS_USER"] = r_libs_user
if SUBMITNODE in platform.node():
logger.log("HINT", f"To get your R_LIBS_USER directory setup, try again on a node other than {SUBMITNODE}.")
logger.log("HINT", "You can check out a node with 'srun --pty bash'")
return None
cmd = [rscript.as_posix(), "-e", "cat(Sys.getenv('R_LIBS_USER'))"]
logger.trace(f"Running {cmd}")
rlibs_dir = Path(run(cmd, text=True, capture_output=True, check=True, env=new_env).stdout)
if not rlibs_dir.exists():
logger.info(f"Making R_LIBS_USER directory: {rlibs_dir}")
rlibs_dir.mkdir(0o755, parents=True, exist_ok=True)
if rlibs_dir.exists():
logger.success(f"Set up your R_LIBS_USER directory: {rlibs_dir}")
return True
else:
return False
else:
logger.success(f"R_LIBS_USER directory already found: {rlibs_dir}")
return True
|
setup_envfile
def setup_envfile(
config: Path
) -> None
Enables hpcman to update hpcman-managed config files for users.
Source code in hpcman/hpcman/user/dotenv.py
| def setup_envfile(config: Path) -> None:
"""Enables hpcman to update hpcman-managed config files for users."""
if environ.get(VARENVFILE):
logger.error("Your shell is already configured using hpcman.")
logger.error(
f"unset {VARENVFILE} and remove the old source env line from your bashrc and cshrc to re-set your shell."
)
exit(1)
envfile = Path(config / "env.sh")
envfile_str = envfile.resolve().as_posix()
configline = "## hpcman config; Added by hpcman user enable"
source = f"source {quote(envfile_str)}"
envfile_csh = Path(config / "env.csh")
envfile_csh_str = envfile_csh.resolve().as_posix()
source_csh = f"source {quote(envfile_csh_str)}"
if not config.exists():
logger.trace(f"{config} does not exist.")
if Confirm.ask(f"Dir '{config}' does not exist. Create it?", default=True):
config.mkdir(mode=0o750, parents=True, exist_ok=True)
if not config.exists():
logger.error(f"Config dir {config} does not exist.")
logger.error("Make the directory or specify another before continuing.")
exit(1)
else:
logger.trace(f"Making envfiles {envfile_str}, {envfile_csh_str}.")
envfile.touch(mode=0o640, exist_ok=True)
logger.info(f"Setting {VARENVFILE} in envfile to enable configuration.")
set_key(envfile, VARENVFILE, envfile_str, export=True)
set_key(envfile, VARENVCSHFILE, envfile_csh_str, export=True)
update_csh_envfile(envfile_str, envfile_csh_str)
if get_key(envfile, VARENVFILE) is not None:
logger.success("hpcman envfile created.")
logger.success(
f"Add {source} to your ~/.bashrc or {source_csh} to your ~/.cshrc and restart your shell to finalize the "
"setup."
)
logger.success("Copy/paste the below line into your terminal for this to work automatically:")
print(f"\necho {quote(source)} >> ~/.bashrc")
print(f"echo {quote(source_csh)} >> ~/.cshrc\n")
if Confirm.ask(
"I can also add the line to your configs for you automatically, would you like that?", default=False
):
for rcfn in (".bashrc", ".cshrc", ".zshrc"):
rc = Path(Path.home() / rcfn)
logger.debug(f"Opening {rc} for writing.")
if not rc.exists():
logger.warning(f"Specified config file {rcfn} does not exist. Skipping...")
continue
with rc.open("r+t") as fh:
logger.trace("Searching for line already present in file")
for i, line in enumerate(fh, start=1):
if line.strip() == configline:
logger.error(f"hpcman config line already detected on line {i}")
logger.error(f"Clean your {rcfn} before continuing.")
exit(1)
match rcfn:
case ".bashrc":
sourceline = source
case ".cshrc":
sourceline = source_csh
case ".zshrc":
sourceline = source
logger.trace(f"Adding {sourceline} to {rcfn}")
fh.write(f"\n{configline}\n")
fh.write(f"{sourceline}\n\n")
logger.success(f"Here is your updated {rcfn} file:")
console = Console()
console.print(Syntax.from_path(rc.as_posix(), line_numbers=True))
print_reload_message()
else:
logger.critical(f"The {VARENVFILE} setting does not seem to be present in {envfile}")
logger.critical("hpcman cannot continue with configuration of your shell. Check your settings/permissions.")
|
run_setup
def run_setup(
setuptype: SetupType,
optionalpath: Path | None = None,
cpuarch: CPUArch = CPUArch.X86_64
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def run_setup(setuptype: SetupType, optionalpath: Path | None = None, cpuarch: CPUArch = CPUArch.X86_64) -> None:
match setuptype:
case SetupType.PREFIX:
set_prefix(optionalpath)
case SetupType.RLIBSUSER:
set_rlibs()
case SetupType.R:
set_r(optionalpath)
case SetupType.PIXI:
set_pixi(cpuarch=cpuarch)
case SetupType.UV:
set_uv(cpuarch=cpuarch)
case SetupType.AUGUSTUS:
set_augustus()
case SetupType.CONDA:
set_conda(cpuarch=cpuarch)
case _:
logger.error(f"Supplied setup type {setuptype} isn't supported!")
exit(1)
|
set_prefix
def set_prefix(
prefix: Path | None = None
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def set_prefix(prefix: Path | None = None) -> None:
if prefix is None:
logger.log("HINT", "Please specify a directory that you have write access to when running this command.")
logger.log("HINT", f"e.g. -> hpcman user setup prefix /nfs/lab/home/{getuser()}/opt")
logger.log("HINT", "If the directory is not present, it will be generated for you, if possible.")
logger.log("HINT", "If you need help finding your lab directory, run 'hpcman lab info' to find some options.")
exit()
else:
logger.trace(f"Working on {prefix}")
prefix.mkdir(0o755, parents=True, exist_ok=True)
logger.info(f"Adding prefix {prefix} to hpcman env file.")
set_key(environ[VARENVFILE], VARUSERPREFIX, prefix.resolve().as_posix(), export=True)
update_csh_envfile()
if (value := get_key(environ[VARENVFILE], VARUSERPREFIX)) is not None:
logger.success(f"Successfully set up hpcman prefix {VARUSERPREFIX}={value}")
print_reload_message()
else:
logger.critical("Unable to set prefix properly!")
logger.critical(f"Check your env var {VARENVFILE} and your permissions for the file listed, if present.")
|
set_rlibs
Updates R_LIBS_USER to value within the HPCMAN_USER_PREFIX directory.
Source code in hpcman/hpcman/user/dotenv.py
| def set_rlibs() -> None:
"""Updates R_LIBS_USER to value within the HPCMAN_USER_PREFIX directory."""
logger.trace(f"Pulling {VARUSERPREFIX} from {VARENVFILE}.")
renviron = Path(Path.home() / ".Renviron").as_posix()
if (value := get_key(environ[VARENVFILE], VARUSERPREFIX)) is not None:
r_libs_user = f"{value}/R/%p-library/%v"
logger.trace(r_libs_user)
logger.log("HINT", "R_LIBS_USER is set in ~/.Renviron for you.")
logger.log("HINT", "If you want to manually change it, you'll have to do it there.")
logger.log("HINT", "To temporarily disable the R_LIBS_USER for an R session, you can use 'R --no-environ'")
set_key(renviron, "R_LIBS_USER", r_libs_user, export=False)
else:
prefix_error()
if (value := get_key(renviron, "R_LIBS_USER")) is not None:
logger.success(f"Successfully set up R_LIBS_USER={value}")
retval = generate_rlibs_dir(r_libs_user=value)
if retval is None:
pass
elif not retval:
logger.log("HINT", "Use 'hpcman user setup R' to get a directory generated using the new value.")
else:
logger.critical("Unable to set R_LIBS_USER properly!")
logger.critical(f"Check your env var {VARENVFILE} and your permissions for the file listed, if present.")
|
run_gmes_setup
def run_gmes_setup() -> None
Runs gmes setup script to link gmes key in home directory
Source code in hpcman/hpcman/user/dotenv.py
| def run_gmes_setup() -> None:
"""Runs gmes setup script to link gmes key in home directory"""
run([GMESSETUP], check=False)
|
set_augustus
def set_augustus() -> None
Updates AUGUSTUS_CONFIG_PATH to value within the HPCMAN_USER_PREFIX directory.
Source code in hpcman/hpcman/user/dotenv.py
| def set_augustus() -> None:
"""Updates AUGUSTUS_CONFIG_PATH to value within the HPCMAN_USER_PREFIX directory."""
logger.trace(f"Pulling {VARUSERPREFIX} from {VARENVFILE}.")
if (value := get_key(environ[VARENVFILE], VARUSERPREFIX)) is not None:
if (prefix := Path(value)).exists():
augustus_prefix = prefix / "augustus"
logger.info(f"Making augustus directory {augustus_prefix.as_posix()}")
augustus_prefix.mkdir(mode=0o755, exist_ok=True)
logger.info("Copying default augustus config directory")
config_path = augustus_prefix / "config"
if config_path.exists():
logger.warning(f"augustus config directory already exists {config_path}")
logger.warning("Did you already set up augustus?")
logger.log("HINT", "Remove the config dir if you want to make a new copy.")
exit(1)
result = copytree(AUGUSTUSCONFIG, config_path)
if Path(result).exists():
logger.success(f"Successfully copied augustus config to {result}")
set_key(environ[VARENVFILE], "AUGUSTUS_CONFIG_PATH", result.as_posix(), export=True)
update_csh_envfile()
else:
logger.error(f"Provided user prefix {value} does not exist.")
logger.error("Rerun 'hpcman user setup prefix' and try again.")
exit(1)
else:
prefix_error()
logger.info("Setting up genemark key file")
run_gmes_setup()
if (value := get_key(environ[VARENVFILE], "AUGUSTUS_CONFIG_PATH")) is not None:
logger.success(f"Successfully set up AUGUSTUS_CONFIG_PATH={value}")
print_reload_message()
else:
logger.critical("Unable to set AUGUSTUS_CONFIG_PATH properly!")
logger.critical(f"Check your env var {VARENVFILE} and your permissions for the file listed, if present.")
|
set_default_channels
def set_default_channels(
pixi_home: str,
pixi_cache: str,
cpuarch: CPUArch
) -> None
Sets default pixi channels in the pixi config.toml file.
Source code in hpcman/hpcman/user/dotenv.py
| def set_default_channels(pixi_home: str, pixi_cache: str, cpuarch: CPUArch) -> None:
"""Sets default pixi channels in the pixi config.toml file."""
new_env = environ.copy()
new_env["PIXI_HOME"] = pixi_home
new_env["PIXI_CACHE_DIR"] = pixi_cache
run(["pixi", "config", "unset", "-g", "default-channels"], text=True, check=True, env=new_env)
if cpuarch == CPUArch.IBM:
run(
["pixi", "config", "append", "-g", "default-channels", "https://ftp.osuosl.org/pub/open-ce/current"],
text=True,
check=True,
env=new_env,
)
run(["pixi", "config", "append", "-g", "default-channels", "conda-forge"], text=True, check=True, env=new_env)
run(["pixi", "config", "append", "-g", "default-channels", "bioconda"], text=True, check=True, env=new_env)
|
set_pixi
def set_pixi(
cpuarch: CPUArch
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def set_pixi(cpuarch: CPUArch) -> None:
logger.trace(f"Pulling {VARUSERPREFIX} from {VARENVFILE}.")
if (value := get_key(environ[VARENVFILE], VARUSERPREFIX)) is not None:
pixi_home = f"{value}/pixi/{cpuarch.value}"
cache = f"{value}/pixi/cache"
logger.trace(f"pixi_home = {pixi_home}")
logger.trace(f"cache = {cache}")
Path(cache).mkdir(mode=0o755, parents=True, exist_ok=True)
set_key(environ[VARENVFILE], "PIXI_HOME", f'"{value}/pixi/$ARCH"', export=True, quote_mode="never")
set_key(environ[VARENVFILE], "PIXI_CACHE_DIR", cache, export=True, quote_mode="never")
update_csh_envfile()
prepend_path(f"{value}/pixi/$ARCH/bin", suppress_reload_message=True)
else:
prefix_error()
logger.info("Setting default-channels for pixi")
set_default_channels(pixi_home, cache, cpuarch)
if (value := get_key(environ[VARENVFILE], "PIXI_HOME")) is not None:
logger.success(f"Successfully set up PIXI_HOME={value}")
logger.success("Now you can install conda envs using pixi.")
logger.success("And you can use 'pixi global install' as well.")
print_reload_message()
else:
logger.critical("Unable to set PIXI_HOME properly!")
logger.critical(f"Check your env var {VARENVFILE} and your permissions for the file listed, if present.")
|
activate_conda_in_bashrc
def activate_conda_in_bashrc(
activate: str = CONDAACTIVATE
) -> bool
Source code in hpcman/hpcman/user/dotenv.py
| def activate_conda_in_bashrc(activate: str = CONDAACTIVATE) -> bool:
configline = "## hpcman conda; Added by hpcman user setup conda"
lines = []
lines.append(f"if [ -f {activate} ]; then")
lines.append(f" source {activate}")
lines.append("fi")
if not Path(expandvars(activate)).exists():
logger.log("HINT", "conda may not be available for your current cpu ARCH as the activate file is missing.")
else:
logger.success("Copy/paste the below lines into your terminal to activate conda with the new settings:")
for line in lines:
print(f"echo {quote(line)} >> ~/.bashrc")
if Confirm.ask(
"Alternatively, I can add the lines to your bashrc for you automatically. Would you like that?", default=False
):
rcfn = ".bashrc"
rc = Path(Path.home() / rcfn)
logger.debug(f"Opening {rc} for writing.")
with rc.open("r+t") as fh:
logger.trace("Searching for line already present in file")
for i, line in enumerate(fh, start=1):
if line.strip() == configline:
logger.error(f"hpcman conda line already detected on line {i}")
logger.error(f"Clean your {rcfn} before continuing.")
exit(1)
logger.trace(f"Adding {configline} to {rcfn}")
if line.strip():
fh.write("\n")
fh.write(f"{configline}\n")
for line in lines:
fh.write(f"{line}\n")
fh.write("\n")
logger.success(f"Here is your updated {rcfn} file:")
console = Console()
console.print(Syntax.from_path(rc.as_posix(), line_numbers=True))
return True
else:
return False
|
set_conda
def set_conda(
cpuarch: CPUArch
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def set_conda(cpuarch: CPUArch) -> None:
condarc = get_default_config_path() / f"{cpuarch.value}.condarc.yaml"
if condarc.exists():
logger.error(f"condarc file '{condarc.as_posix()}' already exists. Did you already set up conda with hpcman?")
logger.error("If intentional, delete the file and try again.")
exit(1)
logger.trace(f"Pulling {VARUSERPREFIX} from {VARENVFILE}.")
if (value := get_key(environ[VARENVFILE], VARUSERPREFIX)) is not None:
logger.info(f"Setting up conda envs and pkgs dirs for {cpuarch.value}")
conda_home = Path(f"{value}/conda/{cpuarch.value}")
pkgs_dir = conda_home / "pkgs"
envs_dir = conda_home / "envs"
logger.trace(f"pkgs_dir = {pkgs_dir}")
logger.trace(f"envs_dir = {envs_dir}")
pkgs_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
envs_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
else:
prefix_error()
yaml = YAML(typ="rt", pure=True)
new_settings = {"pkgs_dirs": [pkgs_dir.as_posix()], "envs_dirs": [envs_dir.as_posix()]}
old_settings = {}
if (old_condarc := Path().home() / ".condarc").exists():
logger.log("HINT", "Backing up old condarc file. Old pkgs_dirs and envs_dirs will be carried to new config.")
with old_condarc.open("rt") as condarcfh:
old_settings = yaml.load(condarcfh)
make_backup(old_condarc)
old_condarc.unlink()
new_settings["pkgs_dirs"].extend(old_settings.get("pkgs_dirs", []))
new_settings["envs_dirs"].extend(old_settings.get("envs_dirs", []))
logger.info("Writing pkgs_dirs and envs_dirs to new condarc file.")
with condarc.open("wt") as condarcfh:
yaml.dump(new_settings, condarcfh)
set_key(
environ[VARENVFILE], "CONDARC", f'"{get_default_config_path()}/{CONDARCBASE}"', export=True, quote_mode="never"
)
if (value := get_key(environ[VARENVFILE], "CONDARC")) is not None:
logger.success(f"Successfully set up CONDARC={value}")
if activate_conda_in_bashrc():
logger.success("Now you can install and activate conda envs in bash using conda and mamba.")
logger.success("Reload your bash shell, e.g. 'exec bash', to see the changes")
else:
logger.log("HINT", "When you add the source activate lines to your bashrc, you will have access to conda.")
else:
logger.critical("Unable to set CONDARC properly!")
logger.critical(f"Check your env var {VARENVFILE} and your permissions for the file listed, if present.")
|
set_uv
def set_uv(
cpuarch: CPUArch
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def set_uv(cpuarch: CPUArch) -> None:
logger.trace(f"Pulling {VARUSERPREFIX} from {VARENVFILE}.")
if (value := get_key(environ[VARENVFILE], VARUSERPREFIX)) is not None:
uv_home = f"{value}/uv/{cpuarch.value}"
logger.trace(f"uv_home = {uv_home}")
for dirname in ("cache", "bin", "python", "tools"):
Path(f"{uv_home}/{dirname}").mkdir(mode=0o755, parents=True, exist_ok=True)
set_key(environ[VARENVFILE], "UV_CACHE_DIR", f'"{value}/uv/$ARCH/cache"', export=True, quote_mode="never")
set_key(environ[VARENVFILE], "UV_TOOL_DIR", f'"{value}/uv/$ARCH/tools"', export=True, quote_mode="never")
set_key(environ[VARENVFILE], "UV_TOOL_BIN_DIR", f'"{value}/uv/$ARCH/bin"', export=True, quote_mode="never")
set_key(
environ[VARENVFILE], "UV_PYTHON_INSTALL_DIR", f'"{value}/uv/$ARCH/python"', export=True, quote_mode="never"
)
update_csh_envfile()
prepend_path(f"{value}/uv/$ARCH/bin", suppress_reload_message=True)
else:
prefix_error()
if (value := get_key(environ[VARENVFILE], "UV_TOOL_BIN_DIR")) is not None:
logger.success(f"Successfully set up UV_TOOL_BIN_DIR={value}")
logger.success("Now you can install python tools into your lab directory.")
print_reload_message()
else:
logger.critical("Unable to set UV_TOOL_BIN_DIR properly!")
logger.critical(f"Check your env var {VARENVFILE} and your permissions for the file listed, if present.")
|
set_r
def set_r(
rdir: Path | None = None
) -> None
Source code in hpcman/hpcman/user/dotenv.py
| def set_r(rdir: Path | None = None) -> None:
if not is_path(rdir):
logger.log("HINT", "Please specify a directory to the version of R you want to use.")
logger.log("HINT", "e.g. -> hpcman user setup R /local/cqls/R/R-4.3.3")
logger.log(
"HINT", f"Feel free to choose from these options: {[x.as_posix() for x in Path(BASERDIR).glob('R-*')]}"
)
logger.log(
"HINT",
"If you are choosing from your own installs, you need to provide the directory where the R "
"binary is present, e.g. the 'bin' dir. The CQLS-managed installs are set up differently.",
)
exit()
if (value := which("R")) is not None:
logger.warning(f"R is already in your $PATH: {value}")
if not Confirm.ask("Do you want to continue adding the new R to your path?", default=False):
logger.log(
"HINT",
"Exiting. You can continue to manually edit your $PATH, or remove R from your $PATH and retry.",
)
exit()
rbinary = rdir / "R"
rscript = rdir / "Rscript"
for exe in (rbinary, rscript):
if not exe.is_file():
logger.error(f"The provided R directory {rdir} does not appear to have a {exe.name} binary in it.")
logger.error("Check the provided directory and try again.")
exit(1)
logger.info(f"Prepending given path '{rdir}' to $PATH")
set_key(environ[VARENVFILE], VARUSERRHOME, rdir.resolve().as_posix(), export=True)
logger.trace(f"preprend_path(${VARUSERRHOME})")
prepend_path(f"${VARUSERRHOME}")
update_csh_envfile()
logger.debug("Setting up R_LIBS_USER dir, if env var is set.")
retval = generate_rlibs_dir(rscript=rscript)
if retval is None:
pass
elif not retval:
logger.log(
"HINT",
"If you set R_LIBS_USER, e.g. hpcman user setup R_LIBS_USER, then I can make sure that "
"directory is present at this time.",
)
logger.log("HINT", "Go set that and try again, if desired!")
|
check_etcpath
def check_etcpath(
etcpath: Path
) -> bool
Checks for expected files in etcpath.
Source code in hpcman/hpcman/user/dotenv.py
| def check_etcpath(etcpath: Path) -> bool:
"""Checks for expected files in etcpath."""
filenames = ("std.bashrc", "std.cshrc", "std.zshrc")
check = True
for fn in filenames:
if not Path(etcpath / fn).exists():
logger.error(f"{fn} is missing from {etcpath.as_posix()}")
check = False
return check
|
make_backup
def make_backup(
fn: str | Path
) -> Path
Makes backup of provided file.
Source code in hpcman/hpcman/user/dotenv.py
| def make_backup(fn: str | Path) -> Path:
"""Makes backup of provided file."""
backup = Path(fn)
i = 1
while backup.exists() and i <= 10:
backup = backup.with_suffix(f".bak{i}")
i += 1
logger.info(f"Backup copy of {fn} is here: {copyfile(fn, backup)}")
return backup
|
backup_and_update_dotfiles
def backup_and_update_dotfiles(
etcpath: Path,
oldetc: str,
configs: list[ConfigFiles]
) -> None
Updates dotfiles
Source code in hpcman/hpcman/user/dotenv.py
| def backup_and_update_dotfiles(etcpath: Path, oldetc: str, configs: list[ConfigFiles]) -> None:
"""Updates dotfiles"""
if not check_etcpath(etcpath):
logger.error("Please provide a different path to look for dotfiles.")
exit(1)
for conf in configs:
if (rc := Path.home() / conf.value).exists():
backup = make_backup(rc.as_posix())
match conf:
case ConfigFiles.BASHRC:
stdrc = "std.bashrc"
copyln = f"cp {INITSDIR}/bashrc ~/.bashrc"
case ConfigFiles.CSHRC:
stdrc = "std.cshrc"
copyln = f"cp {INITSDIR}/cshrc ~/.cshrc"
case ConfigFiles.ZSHRC:
stdrc = "std.zshrc"
copyln = f"cp {INITSDIR}/zshrc ~/.zshrc"
count = 0
replace = 0
with fileinput.input(rc, inplace=True) as fh:
for ln, line in enumerate(fh):
if stdrc in line:
count += 1
if oldetc in line:
logger.info(f"Updating line {ln}: {line.strip()}")
line = line.replace(oldetc, etcpath.as_posix())
replace += 1
elif (etc_str := etcpath.as_posix()) in line:
logger.warning(f"New etc path {etc_str} already found on line {ln}.")
print(line, end="")
if replace == 0:
logger.info(f"No lines updated in {rc.as_posix()}. Did you already update {conf.value}?")
logger.info(f"old etc -> {oldetc}; new etc -> {etcpath.as_posix()}")
logger.log("HINT", "If you think you need a new config file, you can run the below command to get one:")
logger.log("HINT", copyln)
logger.log("HINT", f"You can view your backup {backup} to copy any additional changes over.")
logger.log(
"HINT",
f"Alternatively, you can manually update your dotfile to point to {etcpath.as_posix()}/{stdrc}",
)
elif count == 0:
logger.warning(f"No {stdrc} found in {rc.as_posix()}.")
logger.warning(f"Did you previously make custom changes to your {stdrc} file?")
logger.error(f"Unable to update {rc.as_posix()} as {stdrc} is not found. Manual intervention required.")
elif count == replace:
logger.info(f"Updated {replace} lines in {rc.as_posix()}.")
else:
logger.warning(f"Updated {replace} lines in {rc.as_posix()} with {stdrc} found on {count}.")
logger.warning("Check the config file before continuing.")
logger.warning(f"Consider getting the backup from {backup.as_posix()}")
else:
logger.warning(f"Skipping {conf.value} as it does not exist.")
print_reload_message()
|