aboutsummaryrefslogtreecommitdiff
path: root/scripts/lib/common.sh
blob: 0fdf98a97cb9eeb0c090416d8445783374192b3f (plain)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# scripts/lib/common.sh
# Shared helpers for the trbldoc report scripts.
#
# POSIX sh compatible. Verified to work under mingw bash, WSL bash and
# Alpine/busybox ash. Sourced by the entrypoint scripts; do not execute
# directly.

# Resolve the repository root from the location of the scripts/ directory.
# Sets: REPO_ROOT, SCRIPTS_DIR, LIB_DIR
tb_resolve_paths() {
  # $1: path to the calling script ($0)
  script_path="$1"
  # Directory containing the calling script (scripts/).
  SCRIPTS_DIR="$(CDPATH= cd -- "$(dirname -- "$script_path")" && pwd)"
  LIB_DIR="$SCRIPTS_DIR/lib"
  REPO_ROOT="$(CDPATH= cd -- "$SCRIPTS_DIR/.." && pwd)"
  export REPO_ROOT SCRIPTS_DIR LIB_DIR
}

# Print an ISO-8601 UTC timestamp suitable for directory names.
# Falls back to epoch seconds when the platform date(1) cannot format UTC.
tb_timestamp() {
  if date -u +%Y%m%dT%H%M%SZ 2>/dev/null; then
    return 0
  fi
  printf '%s\n' "$(date +%s)"
}

# Emit an informational message to stderr.
tb_info() {
  printf '[trbldoc-report] %s\n' "$*" >&2
}

# Emit an error message to stderr and return non-zero.
tb_die() {
  printf '[trbldoc-report] ERROR: %s\n' "$*" >&2
  exit 1
}

# Verify a command exists on PATH, otherwise abort.
tb_require() {
  command -v "$1" >/dev/null 2>&1 || tb_die "required tool not found on PATH: $1"
}

# Resolve the bats suite directories for a target keyword.
# $1: all|unit|integration ; echoes space-separated dirs relative to REPO_ROOT.
tb_suite_dirs() {
  case "$1" in
    unit)        printf '%s\n' "$REPO_ROOT/tests/unit" ;;
    integration) printf '%s\n' "$REPO_ROOT/tests/integration" ;;
    all)         printf '%s\n' "$REPO_ROOT/tests/unit $REPO_ROOT/tests/integration" ;;
    *)           tb_die "unknown suite '$1' (expected: all|unit|integration)" ;;
  esac
}

# Resolve bats suite directories relative to repository root.
# $1: all|unit|integration ; echoes a space-separated relative path list.
tb_suite_dirs_rel() {
  case "$1" in
    unit)        printf '%s\n' "tests/unit" ;;
    integration) printf '%s\n' "tests/integration" ;;
    all)         printf '%s\n' "tests/unit tests/integration" ;;
    *)           tb_die "unknown suite '$1' (expected: all|unit|integration)" ;;
  esac
}

# Convert a POSIX-style MSYS path (/d/foo/bar) to a WSL Linux path
# (/mnt/d/foo/bar). Other paths are returned unchanged.
tb_to_wsl_path() {
  p="$1"
  case "$p" in
    [A-Za-z]:\\*|[A-Za-z]:/*)
      d="$(printf '%s' "$p" | cut -c1 | tr 'A-Z' 'a-z')"
      rest="$(printf '%s' "$p" | cut -c3- | sed 's#\\\\#/#g')"
      rest="$(printf '%s' "$rest" | sed 's#^/*##')"
      printf '/mnt/%s/%s\n' "$d" "$rest"
      ;;
    /[A-Za-z]/*)
      d="$(printf '%s' "$p" | cut -c2 | tr 'A-Z' 'a-z')"
      rest="$(printf '%s' "$p" | cut -c4-)"
      printf '/mnt/%s/%s\n' "$d" "$rest"
      ;;
    *)
      printf '%s\n' "$p"
      ;;
  esac
}

# Returns success if the local `bats` command appears usable for this repo.
# Some mixed Windows/MSYS setups expose a broken bats wrapper that exits 0
# without running tests or producing output; this guard catches that case.
tb_bats_usable() {
  suite="${1:-integration}"
  dirs="$(tb_suite_dirs "$suite")"
  # shellcheck disable=SC2086
  count="$(bats --count $dirs 2>/dev/null | tr -d '[:space:]')"
  case "$count" in
    ''|*[!0-9]*)
      return 1
      ;;
    *)
      return 0
      ;;
  esac
}