-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript_runner.ex
More file actions
74 lines (58 loc) · 2.33 KB
/
Copy pathscript_runner.ex
File metadata and controls
74 lines (58 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
defmodule ScriptManager.ScriptRunner do
@moduledoc """
Runs shell scripts from `scripts/` and reports real duration + exit status.
Scripts that source `scripts/lib/common.sh` honour these env vars (set
any of them via the third arg of `run_script/3`):
GS_DRY_RUN=1 no destructive writes
GS_YES=1 skip confirmation prompts (CI mode)
GS_LOG_LEVEL=debug|info|warn|error
GS_PARALLEL=N bounded parallelism for repo iteration
GS_REPO_LIST=… one-repo-per-line filter file
NO_COLOR=1 disable ANSI in output
See `scripts/README.adoc` for the full common.sh contract.
"""
@scripts_dir "scripts"
@doc """
Run a script. Backwards-compatible 2-arity form.
"""
@spec run_script(String.t(), list(String.t())) :: non_neg_integer()
def run_script(script_name, args \\ []), do: run_script(script_name, args, %{})
@doc """
Run a script with an explicit env map. Use this to surface common.sh
flags (dry-run, log level, parallelism) from TUI menu choices.
Example: `run_script("audit_contractiles.sh", ["--report"], %{"GS_DRY_RUN" => "1"})`
"""
@spec run_script(String.t(), list(String.t()), map()) :: non_neg_integer()
def run_script(script_name, args, env) when is_map(env) do
script_path = Path.join(@scripts_dir, script_name)
if !File.exists?(script_path) do
IO.puts("❌ Script not found: #{script_path}")
127
else
env_list = Enum.map(env, fn {k, v} -> {to_string(k), to_string(v)} end)
if env_list != [] do
env_summary =
env_list
|> Enum.map(fn {k, v} -> "#{k}=#{v}" end)
|> Enum.join(" ")
IO.puts("ℹ️ env: #{env_summary}")
end
started_at = System.monotonic_time(:millisecond)
{_out, status} =
System.cmd("bash", [script_path | args],
into: IO.stream(:stdio, :line),
stderr_to_stdout: true,
env: env_list
)
elapsed_ms = System.monotonic_time(:millisecond) - started_at
elapsed_s = elapsed_ms / 1000
case status do
0 -> IO.puts("\n✅ Completed in #{Float.round(elapsed_s, 2)}s")
_ -> IO.puts("\n❌ Failed (exit #{status}) after #{Float.round(elapsed_s, 2)}s")
end
status
end
end
end