Skip to content

Commit

Permalink
Reduce run() indent, add condarun()
Browse files Browse the repository at this point in the history
  • Loading branch information
maddenp committed Sep 28, 2023
1 parent 8801838 commit 21a5409
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ Several public helper callables are available in the `iotaa` module:
- `logcfg()` configures Python's root logger to support `logging.info()` et al calls, which `iotaa` itself makes. It is called when the `iotaa` CLI is used, but could also be called by standalone applications with simple logging needs.
- `main()` is the entry-point function for CLI use.
- `run()` runs a command in a subshell -- functionality commonly needed in workflows.
- `runconda()` runs a command in a subshell with a named conda environment activated.

## Development

Expand Down
2 changes: 1 addition & 1 deletion recipe/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
],
"run": []
},
"version": "0.2.0"
"version": "0.3.0"
}
2 changes: 1 addition & 1 deletion recipe/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package:
name: iotaa
version: 0.2.0
version: 0.3.0
source:
path: ../src
build:
Expand Down
35 changes: 33 additions & 2 deletions src/iotaa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,15 @@ def run(
"""
Run a command in a subshell.
:param taskname: The name of the task, for logging.
:param taskname: The current task's name.
:param cmd: The command to run.
:param cwd: Change to this directory before running cmd.
:param env: Environment variables to set before running cmd.
:param log: Log output from successful cmd? (Error output is always logged.)
:return: A result object providing stderr, stdout and success info.
"""

indent = " "
indent = " "
logging.info("%s: Running: %s", taskname, cmd)
if cwd:
logging.info("%s: %sin %s", taskname, indent, cwd)
Expand All @@ -162,6 +162,37 @@ def run(
return result(output=output, success=success)


def runconda(
conda_path: str,
conda_env: str,
taskname: str,
cmd: str,
cwd: Optional[Union[Path, str]] = None,
env: Optional[Dict[str, str]] = None,
log: Optional[bool] = False,
) -> result:
"""
Run a command in the specified conda environment.
:param conda_path: Path to the conda installation to use.
:param conda_env: Name of the conda environment in which to run cmd.
:param taskname: The current task's name.
:param cmd: The command to run.
:param cwd: Change to this directory before running cmd.
:param env: Environment variables to set before running cmd.
:param log: Log output from successful cmd? (Error output is always logged.)
:return: A result object providing stderr, stdout and success info.
"""
cmd = " && ".join(
[
'eval "$(%s/bin/conda shell.bash hook)"' % conda_path,
"conda activate %s" % conda_env,
cmd,
]
)
return run(taskname=taskname, cmd=cmd, cwd=cwd, env=env, log=log)


# Decorators


Expand Down
31 changes: 23 additions & 8 deletions src/iotaa/tests/test_iotaa.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,21 +180,36 @@ def test_run_failure(caplog):
assert "division by zero" in result.output
assert result.success is False
assert logged("task: Running: %s" % cmd, caplog)
assert logged("task: Failed with status: 2", caplog)
assert logged("task: Output:", caplog)
assert logged("task: expr: division by zero", caplog)
assert logged("task: Failed with status: 2", caplog)
assert logged("task: Output:", caplog)
assert logged("task: expr: division by zero", caplog)


def test_run_success(caplog, tmp_path):
iotaa.logging.getLogger().setLevel(iotaa.logging.INFO)
cmd = "echo hello $FOO"
assert iotaa.run(taskname="task", cmd=cmd, cwd=tmp_path, env={"FOO": "bar"}, log=True)
assert logged("task: Running: %s" % cmd, caplog)
assert logged("task: in %s" % tmp_path, caplog)
assert logged("task: with environment variables:", caplog)
assert logged("task: FOO=bar", caplog)
assert logged("task: Output:", caplog)
assert logged("task: hello bar", caplog)
assert logged("task: in %s" % tmp_path, caplog)
assert logged("task: with environment variables:", caplog)
assert logged("task: FOO=bar", caplog)
assert logged("task: Output:", caplog)
assert logged("task: hello bar", caplog)


def test_runconda():
conda_path = "/path/to_conda"
conda_env = "env-name"
taskname = "task"
cmd = "foo"
fullcmd = 'eval "$(%s/bin/conda shell.bash hook)" && conda activate %s && %s' % (
conda_path,
conda_env,
cmd,
)
with patch.object(iotaa, "run") as run:
iotaa.runconda(conda_path=conda_path, conda_env=conda_env, taskname=taskname, cmd=cmd)
run.assert_called_once_with(taskname=taskname, cmd=fullcmd, cwd=None, env=None, log=False)


# Decorator tests
Expand Down
1 change: 1 addition & 0 deletions src/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ disable = [
"consider-using-f-string",
"disallowed-name",
"invalid-name",
"too-many-arguments",
"unnecessary-lambda-assignment",
]
recursive = true
Expand Down

0 comments on commit 21a5409

Please sign in to comment.