Skip to content

Conversation

@CLHatch
Copy link
Contributor

@CLHatch CLHatch commented Dec 28, 2025

Summary by Sourcery

Add detailed system information collection and formatting to fatal error handling, and align default installation paths and documentation with the .dockstarter directory while updating CI dependencies.

Enhancements:

  • Prepend fatal stack traces with collected system and environment details, including shell, architecture, paths, user info, and OS metadata, formatted with improved indentation and visuals.
  • Recognize arm64 as a supported architecture and improve fatal and log handling messages and formatting.
  • Centralize the default application folder name as a constant and use it for repository cloning and execution paths.
  • Improve log cleanup by truncating the application log via tail piped into sudo tee instead of shell-embedded echo redirection.

Build:

  • Update GitHub Actions workflows to newer pinned versions of actions/checkout and actions/stale, and bump the markdownlint-cli2 container image version.

Documentation:

  • Update documentation to reference the new ~/.dockstarter install and compose paths across usage, backups, overrides, uninstall, Plex, and FAQ guides.

@CLHatch CLHatch requested review from a team as code owners December 28, 2025 06:23
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 28, 2025

Reviewer's Guide

Adds a reusable system information collector and indentation helper to improve fatal error stack traces, updates default DockSTARTer installation paths, and refreshes GitHub Actions workflows and docs accordingly.

Sequence diagram for fatal error handling with system info

sequenceDiagram
    participant Script as main_sh
    participant Fatal as fatal
    participant SysInfo as get_system_info
    participant Indent as indent_text
    participant FatalNoTrace as fatal_notrace
    participant Logger as log

    Script->>Fatal: fatal(message...)
    activate Fatal
    Fatal->>SysInfo: get_system_info()
    SysInfo-->>Fatal: system_info_lines[]
    Fatal->>Indent: indent_text(2, system_info_and_stack[])
    Indent-->>Fatal: indented_text
    Fatal->>FatalNoTrace: fatal_notrace(header, indented_text, footer, message...)
    deactivate Fatal

    activate FatalNoTrace
    FatalNoTrace->>Logger: log(true, timestamped_log("[FATAL]", ...))
    Logger-->>FatalNoTrace: write_to_log_and_stderr
    FatalNoTrace-->>Script: exit 1
    deactivate FatalNoTrace
Loading

File-Level Changes

Change Details Files
Enhance fatal error handling to prepend detailed system info and reformat stack traces.
  • Introduce indent_text helper using pr for consistent indentation of multi-line output.
  • Add get_system_info to gather version, process, ARCH, script, user/group, home dir and OS details from various system commands and files.
  • Modify fatal() to prepend system info, adjust frame formatting and prefixes, and indent both system info and stack trace in a combined header/footer block.
  • Adjust fatal_notrace quoting style while preserving behavior.
main.sh
Broaden architecture support and improve error messaging.
  • Extend ARCH validation to accept arm64 in addition to aarch64 and x86_64.
  • Fix spelling and wording of unsupported architecture error messages.
main.sh
Change default DockSTARTer install directory from ~/.docker to ~/.dockstarter in code and docs.
  • Add APPLICATION_FOLDER_NAME_DEFAULT='.dockstarter' constant and use it for clone paths and exec paths in clone_repo().
  • Update documentation references for compose, env, backups, overrides, uninstall, Plex app configuration, and FAQ paths from ~/.docker to ~/.dockstarter.
main.sh
docs/basics/command-line-usage.md
docs/advanced/backups.md
docs/overrides/introduction.md
docs/README.md
docs/advanced/uninstall.md
docs/apps/plex.md
docs/basics/faq.md
Improve log cleanup implementation on shutdown.
  • Replace sudo sh -c with tail piped into sudo tee to truncate APPLICATION_LOG to last 1000 lines while avoiding complex shell-escaped echo.
main.sh
Refresh CI workflows to use newer actions and images.
  • Bump actions/checkout from v6.0.0 to v6.0.1 across lint, tests, validate, and mkdocs deploy workflows.
  • Update markdownlint-cli2 container image tag and digest.
  • Bump actions/stale from v10.1.0 to v10.1.1.
.github/workflows/lint.yml
.github/workflows/deploy-mkdocs.yml
.github/workflows/stale.yml
.github/workflows/tests.yml
.github/workflows/validate.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions bot added ci Automatic label docs Automatic label core Automatic label repo Automatic label labels Dec 28, 2025
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 6 issues, and left some high level feedback:

  • The new indent_text helper is now defined in both main.sh and .includes/misc_functions.sh; consider centralizing it in one place and reusing it to avoid duplication and divergence.
  • The hard-coded fatal "Super Fatal Error" call at the start of menu_main looks like a leftover debug statement and will prevent the menu from ever displaying; it should probably be removed or guarded.
  • After adding arm64 as a supported architecture in check_arch, the error message still only lists aarch64 and x86_64; update the message so it matches the actual set of supported architectures.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `indent_text` helper is now defined in both `main.sh` and `.includes/misc_functions.sh`; consider centralizing it in one place and reusing it to avoid duplication and divergence.
- The hard-coded `fatal "Super Fatal Error"` call at the start of `menu_main` looks like a leftover debug statement and will prevent the menu from ever displaying; it should probably be removed or guarded.
- After adding `arm64` as a supported architecture in `check_arch`, the error message still only lists `aarch64` and `x86_64`; update the message so it matches the actual set of supported architectures.

## Individual Comments

### Comment 1
<location> `main.sh:306` </location>
<code_context>
+
     local -a Stack=()
+
+    get_system_info | readarray -t Stack
+    Stack+=("")
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Using `readarray` in a pipeline will populate `Stack` in a subshell, leaving `Stack` empty in the current shell.

In bash, unless `lastpipe` is enabled, this means the `Stack` array in the current shell never gets updated, so the system info you want to prepend is lost. Prefer process substitution to keep `readarray` in the current shell:

```bash
readarray -t Stack < <(get_system_info)
Stack+=("")
```

This ensures `Stack` is correctly populated with the system info.
</issue_to_address>

### Comment 2
<location> `.scripts/menu_main.sh:10` </location>
<code_context>
         return
     fi

+    fatal "Super Fatal Error"
     local Title="Main Menu"
     local Option_Configure="Configuration"
</code_context>

<issue_to_address>
**issue (bug_risk):** Calling `fatal` at the top of `menu_main` will abort every invocation of the main menu.

This unconditional `fatal` causes every `menu_main` call to exit immediately before running any menu logic. If it’s only for debugging, remove it or guard it behind a condition so normal menu execution can proceed.
</issue_to_address>

### Comment 3
<location> `main.sh:397-399` </location>
<code_context>
 # Check for supported CPU architecture
 check_arch() {
-    if [[ ${ARCH} != "aarch64" ]] && [[ ${ARCH} != "x86_64" ]]; then
+    if [[ ${ARCH} != "arm64" ]] && [[ ${ARCH} != "aarch64" ]] && [[ ${ARCH} != "x86_64" ]]; then
         fatal_notrace \
             "Unsupported architeture." \
</code_context>

<issue_to_address>
**suggestion:** The error message still lists only `aarch64` and `x86_64` as supported even though `arm64` is now accepted.

Consider updating the fatal message to mention `arm64` alongside `aarch64` and `x86_64` so it matches the actual supported architectures, and optionally fix the `architeture` typo.

```suggestion
        fatal_notrace \
            "Unsupported architecture." \
            "Supported architectures are 'arm64', 'aarch64' or 'x86_64', running architecture is '${ARCH}'."
```
</issue_to_address>

### Comment 4
<location> `.includes/misc_functions.sh:78-83` </location>
<code_context>
     printf '%s\n' "${Result}"
 }

+indent_text() {
+    local -i IndentSize=${1}
+    shift
+    pr -e -t -o ${IndentSize} <<< "$(
+        printf "%s\n" "$@"
+    )"
+}
+
</code_context>

<issue_to_address>
**suggestion:** `indent_text` is now defined in both `main.sh` and `.includes/misc_functions.sh`, which introduces duplication and possible confusion about which implementation is used.

There are now two identical `indent_text` definitions (here and in `main.sh`). If both files are sourced, this can cause confusion about which one is actually used and risk divergence if only one is updated. Please keep a single shared definition (preferably in a common helper file) and have other scripts call that, or remove this copy if `main.sh` is the intended source of truth.

Suggested implementation:

```
}


is_true() {

```

1. Ensure that `main.sh` (or whichever file now owns `indent_text`) is sourced before any script that relies on `indent_text`.
2. If other scripts were previously sourcing `.includes/misc_functions.sh` specifically to get `indent_text`, update them to source the new canonical location instead.
</issue_to_address>

### Comment 5
<location> `docs/basics/command-line-usage.md:79` </location>
<code_context>
 This is the best place to change the app's external default ports.

-There will also be an application specific variable file created at `~/.docker/compose/.env.app.<appname>`.  This may or not be populated with variables.  The variables included, if any, will entierly depend on the application installed.  If you need to edit the values of the variables, or include any new variables for the app, it is entirely safe to do so.
+There will also be an application specific variable file created at `~/.dockstarter/compose/.env.app.<appname>`.  This may or not be populated with variables.  The variables included, if any, will entierly depend on the application installed.  If you need to edit the values of the variables, or include any new variables for the app, it is entirely safe to do so.

 #### Removing Apps
</code_context>

<issue_to_address>
**issue (typo):** Fix grammar and spelling in the description of the application-specific variable file.

Consider rephrasing to: "This may or may not be populated with variables. The variables included, if any, will entirely depend on the application installed."

```suggestion
There will also be an application specific variable file created at `~/.dockstarter/compose/.env.app.<appname>`.  This may or may not be populated with variables.  The variables included, if any, will entirely depend on the application installed.  If you need to edit the values of the variables, or include any new variables for the app, it is entirely safe to do so.
```
</issue_to_address>

### Comment 6
<location> `docs/basics/faq.md:12` </location>
<code_context>
+For new installs the default `DOCKER_VOLUME_CONFIG` is `~/.config/appdata`. Users who ran DockSTARTer before this location became the default may have `~/.dockstarter/config`, and we advise relocating.

 If you'd like to move your existing config to a new location you can do the following:
 Edit `~/. docker/compose/.env` (in any text editor) and set
</code_context>

<issue_to_address>
**suggestion (typo):** Remove the stray space in the path and align it with the updated `~/.dockstarter` directory.

The path is currently written as `~/. docker/compose/.env`, which has an extra space after `~/.`. To match the rest of the docs and the new default, this should be `~/.dockstarter/compose/.env`.

```suggestion
Edit `~/.dockstarter/compose/.env` (in any text editor) and set
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@CLHatch
Copy link
Contributor Author

CLHatch commented Dec 28, 2025

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues, and left some high level feedback:

  • In fatal(), the [[ Frame -ge StartFrame ]] checks never expand Frame and will be treated as a literal string, which can cause runtime errors under set -euo pipefail; use arithmetic context (e.g. (( Frame >= StartFrame ))) or [[ $Frame -ge $StartFrame ]] instead.
  • The check_arch() error message still lists only aarch64 and x86_64 as supported, but the function now accepts arm64 as well; consider updating the message to include arm64 to avoid confusing users.
  • In get_system_info(), calls like readlink /proc/$$/exe assume /proc exists and can emit noisy errors on platforms without it; you may want to guard them (e.g. with 2>/dev/null and a fallback) to keep fatal output clean and robust across environments.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `fatal()`, the `[[ Frame -ge StartFrame ]]` checks never expand `Frame` and will be treated as a literal string, which can cause runtime errors under `set -euo pipefail`; use arithmetic context (e.g. `(( Frame >= StartFrame ))`) or `[[ $Frame -ge $StartFrame ]]` instead.
- The `check_arch()` error message still lists only `aarch64` and `x86_64` as supported, but the function now accepts `arm64` as well; consider updating the message to include `arm64` to avoid confusing users.
- In `get_system_info()`, calls like `readlink /proc/$$/exe` assume `/proc` exists and can emit noisy errors on platforms without it; you may want to guard them (e.g. with `2>/dev/null` and a fallback) to keep fatal output clean and robust across environments.

## Individual Comments

### Comment 1
<location> `main.sh:326` </location>
<code_context>
-        local StackLineFormat="  ${C["TraceFrameNumber"]}%${FrameNumberLength}d${NC}:${indent}${FramePrefix}${C["TraceSourceFile"]}%s${NC}:${C["TraceLineNumber"]}%d${NC} (${C["TraceFunction"]}%s${NC})"
+        local StackLineFormat="${C["TraceFrameNumber"]}%${FrameNumberLength}d${NC}:${indent}${FramePrefix}${C["TraceSourceFile"]}%s${NC}:${C["TraceLineNumber"]}%d${NC} (${C["TraceFunction"]}%s${NC})"
+
+        if [[ Frame -ge StartFrame ]]; then
+            # shellcheck disable=SC2059 # Don't use variables in the printf format string.
+            Stack+=(
</code_context>

<issue_to_address>
**issue (bug_risk):** Frame/StartFrame comparison is missing `$` expansions and will fail as an integer comparison at runtime.

In the `fatal` loop, `[[ Frame -ge StartFrame ]]` (and the later `if [[ Frame -ge StartFrame ]]; then`) compare the literal strings `Frame`/`StartFrame`, so `[[` treats them as arithmetic and fails with `integer expression expected`. This can cause unexpected recursion into `fatal` or terminate the script. Use variable expansion and a numeric comparison, e.g. `if (( Frame >= StartFrame )); then` or `if [[ $Frame -ge $StartFrame ]]; then`, and update the other occurrence accordingly.
</issue_to_address>

### Comment 2
<location> `main.sh:396-399` </location>
<code_context>
 # Check for supported CPU architecture
 check_arch() {
-    if [[ ${ARCH} != "aarch64" ]] && [[ ${ARCH} != "x86_64" ]]; then
+    if [[ ${ARCH} != "arm64" ]] && [[ ${ARCH} != "aarch64" ]] && [[ ${ARCH} != "x86_64" ]]; then
         fatal_notrace \
-            "Unsupported architeture." \
-            "Supported architetures are 'aarch64' or 'x86_64', running architeture is '${ARCH}'."
+            "Unsupported architecture." \
+            "Supported architectures are 'aarch64' or 'x86_64', running architecture is '${ARCH}'."
     fi
 }
</code_context>

<issue_to_address>
**issue:** The supported architectures message is out of sync with the newly-allowed `arm64` architecture.

The condition now allows `arm64`, but the error message still lists only `'aarch64'` and `'x86_64'`. This could confuse `arm64` users who hit this path. Please update the message to include `arm64` (or derive the supported list from a single source to avoid future drift).
</issue_to_address>

### Comment 3
<location> `docs/basics/command-line-usage.md:50` </location>
<code_context>
 ## Setup Your Environment

-If you do not yet have a `~/.docker/compose/.env` and/or `~/.docker/compose.env.app.<appname>`files:
+If you do not yet have a `~/.dockstarter/compose/.env` and/or `~/.dockstarter/compose.env.app.<appname>`files:

 ```bash
</code_context>

<issue_to_address>
**suggestion (typo):** Fix minor spacing and path issues in the application env file sentence.

Please add a space before "files" and update the second path to include the missing `/` after `compose`: `~/.dockstarter/compose/.env.app.<appname>` for consistency with the rest of the docs.

```suggestion
If you do not yet have a `~/.dockstarter/compose/.env` and/or `~/.dockstarter/compose/.env.app.<appname>` files:
```
</issue_to_address>

### Comment 4
<location> `docs/basics/command-line-usage.md:79` </location>
<code_context>
 This is the best place to change the app's external default ports.

-There will also be an application specific variable file created at `~/.docker/compose/.env.app.<appname>`.  This may or not be populated with variables.  The variables included, if any, will entierly depend on the application installed.  If you need to edit the values of the variables, or include any new variables for the app, it is entirely safe to do so.
+There will also be an application specific variable file created at `~/.dockstarter/compose/.env.app.<appname>`.  This may or not be populated with variables.  The variables included, if any, will entierly depend on the application installed.  If you need to edit the values of the variables, or include any new variables for the app, it is entirely safe to do so.

 #### Removing Apps
</code_context>

<issue_to_address>
**suggestion (typo):** Correct minor grammar and spelling in the description of the application-specific variable file.

Please update the sentence to "This may or may not be populated with variables." and correct "entierly" to "entirely" for clarity.

```suggestion
There will also be an application specific variable file created at `~/.dockstarter/compose/.env.app.<appname>`.  This may or may not be populated with variables.  The variables included, if any, will entirely depend on the application installed.  If you need to edit the values of the variables, or include any new variables for the app, it is entirely safe to do so.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

CLHatch and others added 2 commits December 28, 2025 00:46
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
@CLHatch CLHatch merged commit a6aaf5c into main Dec 28, 2025
20 checks passed
@CLHatch CLHatch deleted the Trace branch December 28, 2025 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Automatic label core Automatic label docs Automatic label repo Automatic label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants