Skip to content

Update Camtasia uninstall script - #45603

Merged
allenhouchins merged 2 commits into
mainfrom
allenhouchins-camtasia-script-updates
May 15, 2026
Merged

Update Camtasia uninstall script#45603
allenhouchins merged 2 commits into
mainfrom
allenhouchins-camtasia-script-updates

Conversation

@allenhouchins

@allenhouchins allenhouchins commented May 15, 2026

Copy link
Copy Markdown
Member

Improve Camtasia uninstall handling by updating trash() to glob-expand target paths (using compgen), iterate matches (preserving spaces), and move each found file/symlink to the user's Trash with unique timestamp+rand+index suffixes. If no matches are found the script now reports the path doesn't exist. Also update darwin.json to point to the new uninstall script ref (252f6f0e) and include the updated script content in the refs section.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced Camtasia macOS uninstall process to more reliably handle removal of application cache and preference files.

Review Change Stack

Improve Camtasia uninstall handling by updating trash() to glob-expand target paths (using compgen), iterate matches (preserving spaces), and move each found file/symlink to the user's Trash with unique timestamp+rand+index suffixes. If no matches are found the script now reports the path doesn't exist. Also update darwin.json to point to the new uninstall script ref (252f6f0e) and include the updated script content in the refs section.
fleet-release
fleet-release previously approved these changes May 15, 2026
@allenhouchins
allenhouchins marked this pull request as ready for review May 15, 2026 15:43
Copilot AI review requested due to automatic review settings May 15, 2026 15:43

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@allenhouchins
allenhouchins merged commit 6cdb5b8 into main May 15, 2026
14 of 15 checks passed
@allenhouchins
allenhouchins deleted the allenhouchins-camtasia-script-updates branch May 15, 2026 15:43
@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2317ed07-9003-43dc-8143-8120215d1a20

📥 Commits

Reviewing files that changed from the base of the PR and between 855caac and 9134482.

📒 Files selected for processing (2)
  • ee/maintained-apps/inputs/homebrew/scripts/camtasia_uninstall.sh
  • ee/maintained-apps/outputs/camtasia/darwin.json

Walkthrough

This PR updates the Camtasia macOS uninstall script to handle glob patterns in file removal. The trash() helper function was modified to expand glob patterns using compgen -G, iterate over each matched file or symlink, and move each match into the user's .Trash directory with unique timestamp/random/index suffixes. A found_any flag tracks whether any matches were found to properly distinguish between successful removal and cases where the glob yields no results. Both the shell script implementation and the JSON manifest reference were updated.

Possibly related PRs

  • fleetdm/fleet#45503: Implements the same glob-aware trash() helper logic with compgen -G expansion and per-match suffix generation for the Camtasia uninstall script.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch allenhouchins-camtasia-script-updates

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Fleet-maintained Camtasia macOS uninstall script to correctly handle wildcard paths by expanding globs and moving each matched file/symlink to the logged-in user’s Trash with unique suffixes, and updates the generated darwin.json manifest to reference the new uninstall script ref.

Changes:

  • Update trash() to glob-expand target paths via compgen -G and iterate matches safely (including paths with spaces).
  • Ensure multiple matched files don’t collide in Trash by appending timestamp + random + index suffixes.
  • Update the Camtasia darwin.json output to reference and embed the new uninstall script ref.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
ee/maintained-apps/outputs/camtasia/darwin.json Bumps uninstall_script_ref and embeds the updated uninstall script in refs.
ee/maintained-apps/inputs/homebrew/scripts/camtasia_uninstall.sh Updates trash() to expand glob patterns and move each match to Trash with unique naming.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 19 to +33
local trash="/Users/$logged_in_user/.Trash"
local file_name="$(basename "${target_file}")"
local file file_name
local found_any=false
local i=0

if [[ -e "$target_file" ]]; then
echo "removing $target_file."
mv -f "$target_file" "$trash/${file_name}_${timestamp}_${rand}"
else
# Glob-expand target_file (compgen preserves spaces in the path; [[ -e "$x" ]] does not expand *).
while IFS= read -r file; do
[[ -n "$file" ]] || continue
if [[ -e "$file" ]] || [[ -L "$file" ]]; then
found_any=true
i=$((i + 1))
file_name="$(basename "$file")"
echo "removing $file."
mv -f "$file" "$trash/${file_name}_${timestamp}_${rand}_${i}"
fi
"refs": {
"2fda011f": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nhdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\"\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\"\n# copy to the applications folder\nquit_and_track_application 'com.techsmith.camtasia'\nif [ -d \"$APPDIR/Camtasia.app\" ]; then\n\tsudo mv \"$APPDIR/Camtasia.app\" \"$TMPDIR/Camtasia.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Camtasia.app\" \"$APPDIR\"\nrelaunch_application 'com.techsmith.camtasia'\n",
"a83239bb": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Camtasia.app\"\ntrash $LOGGED_IN_USER '/Users/Shared/TechSmith/Camtasia'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.camtasia26.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.camtasia2026.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/TechSmith/Camtasia*'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.plausiblelabs.crashreporter.data/com.techsmith.camtasia*'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.techsmith.camtasia*'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.techsmith.camtasia*'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.techsmith.camtasia*.binarycookies'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.techsmith.camtasia*.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.techsmith.camtasia*.savedState'\ntrash $LOGGED_IN_USER '~/Library/WebKit/com.techsmith.camtasia*'\n"
"252f6f0e": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n local file file_name\n local found_any=false\n local i=0\n\n # Glob-expand target_file (compgen preserves spaces in the path; [[ -e \"$x\" ]] does not expand *).\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n if [[ -e \"$file\" ]] || [[ -L \"$file\" ]]; then\n found_any=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n fi\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n\n if [[ \"$found_any\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Camtasia.app\"\ntrash $LOGGED_IN_USER '/Users/Shared/TechSmith/Camtasia'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.camtasia26.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.techsmith.camtasia2026.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/TechSmith/Camtasia*'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.plausiblelabs.crashreporter.data/com.techsmith.camtasia*'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.techsmith.camtasia*'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.techsmith.camtasia*'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.techsmith.camtasia*.binarycookies'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.techsmith.camtasia*.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.techsmith.camtasia*.savedState'\ntrash $LOGGED_IN_USER '~/Library/WebKit/com.techsmith.camtasia*'\n",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants