Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bin): x-asdf-cleanup #29

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

feat(bin): x-asdf-cleanup #29

wants to merge 7 commits into from

Conversation

ivuorinen
Copy link
Owner

@ivuorinen ivuorinen commented Sep 22, 2024

Tool for cleaning up unused and old asdf plugin installations.

Summary by CodeRabbit

  • New Features

    • Introduced a new script, x-asdf-cleanup, for managing tool versions with user interaction options.
    • Added an export statement for TMS_CONFIG_FILE to streamline configuration for the TMS tool.
    • Updated markdown linting configuration to use JSON format.
  • Bug Fixes

    • Resolved redundancy in the export statement for TMS_CONFIG_FILE.
  • Documentation

    • Created comprehensive documentation for the x-asdf-cleanup script, including usage instructions and configuration options.

Copy link

1 similar comment
Copy link

@ivuorinen
Copy link
Owner Author

@coderabbitai summary

Copy link

coderabbitai bot commented Nov 11, 2024

✅ Actions performed

Summary regeneration triggered.

Copy link

coderabbitai bot commented Nov 11, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces a new Bash script x-asdf-cleanup in the local/bin/ directory, designed to manage tool versions installed via the asdf version manager. The script provides comprehensive functionality for locating, analyzing, and optionally uninstalling unused tool versions across different projects. Additionally, a duplicate export for the TMS_CONFIG_FILE configuration path has been added in the config/exports file. Changes also include updates to markdown linting configuration and documentation for the new script.

Changes

File Change Summary
local/bin/x-asdf-cleanup New Bash script for managing asdf tool versions, with features including:
- Argument parsing
- Logging and error handling
- Version management
- Uninstallation logic
- Backup and restore functionality
- Performance monitoring
config/exports Added duplicate export for TMS_CONFIG_FILE configuration path
.markdownlint.json New rule added: "ol-prefix": false
.pre-commit-config.yaml Updated markdownlint hook argument from YAML to JSON configuration file
local/bin/x-asdf-cleanup.md New documentation file for x-asdf-cleanup, detailing usage, installation, configuration options, and development setup

Poem

🐰 Hop, hop, version cleanup time!
Asdf tools, now in their prime
Unused versions, bid farewell
With scripts that work so very well
A cleaner dev environment's delight! 🧹


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ivuorinen
Copy link
Owner Author

@coderabbitai review

Copy link

coderabbitai bot commented Nov 11, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (11)
local/bin/x-asdf-cleanup (4)

17-17: Consider re-enabling 'set -euo pipefail' for robustness.
Having this setting enabled can help catch errors early and avoid unexpected behavior, especially in shell scripts meant for system cleanup and management. Currently, it's commented out, which may lead to silent failures.

-# set -euo pipefail
+set -euo pipefail

28-34: Add error handling for plugin installation failure.
If the command to install fd with asdf fails or is not permitted, the script will exit with a missing dependency. Consider adding error-handling logic or guidance to the user for manual installation.


211-244: Enhance error handling for 'asdf list' parsing.
If 'asdf list' fails or its output format changes, the loop parsing the tool versions might break silently. Consider checking the exit status of 'asdf list' or validating the contents before processing.


330-357: Consider breaking the 'main' function into smaller, focused functions.
The logic within 'main' is somewhat lengthy (parsing, directory checks, reading versions, displaying, uninstalling). Splitting it into smaller functions can improve readability, maintainability, and testability.

config/nvim/lua/plugins/neogen.lua (1)

6-6: Consider pinning to a specific version

Using version = '*' could lead to unexpected breaking changes when the plugin updates. Consider pinning to a specific version for better stability.

-  version = '*',
+  version = '^0.10.0', -- Replace with the latest stable version
config/nvim/lua/plugins/lsp-saga.lua (1)

7-10: Mark dependencies as optional in configuration

The dependencies are marked as optional in comments, but this should be reflected in the configuration itself using the optional = true field.

  dependencies = {
-   'nvim-treesitter/nvim-treesitter', -- optional
-   'nvim-tree/nvim-web-devicons', -- optional
+   { 'nvim-treesitter/nvim-treesitter', optional = true },
+   { 'nvim-tree/nvim-web-devicons', optional = true },
  },
config/nvim/lua/plugins/flash.lua (1)

1-37: Add configuration documentation

Consider adding comments explaining the purpose of each key mapping group for better maintainability.

 return {
   'folke/flash.nvim',
   event = 'VeryLazy',
   opts = {},
   keys = {
+    -- Basic jump functionality
     {
       'zk',
       mode = { 'n', 'x', 'o' },
       function() require('flash').jump() end,
       desc = 'Flash',
     },
+    -- Treesitter-based navigation
     {
       'Zk',
       mode = { 'n', 'x', 'o' },
       function() require('flash').treesitter() end,
       desc = 'Flash Treesitter',
     },
config/nvim/lua/plugins/harpoon.lua (2)

16-32: Optimize telescope configuration for better performance.

The toggle_telescope function creates a new table on each call. Consider memoizing the picker configuration for better performance.

-local function toggle_telescope(harpoon_files)
+local picker_conf = {
+  prompt_title = 'Harpoon',
+  previewer = conf.file_previewer {},
+  sorter = conf.generic_sorter {},
+}
+
+local function toggle_telescope(harpoon_files)
   local file_paths = {}
   for _, item in ipairs(harpoon_files.items) do
     table.insert(file_paths, item.value)
   end

   require('telescope.pickers')
       .new({}, {
-        prompt_title = 'Harpoon',
+        prompt_title = picker_conf.prompt_title,
         finder = require('telescope.finders').new_table {
           results = file_paths,
         },
-        previewer = conf.file_previewer {},
-        sorter = conf.generic_sorter {},
+        previewer = picker_conf.previewer,
+        sorter = picker_conf.sorter,
       })
       :find()
 end

34-45: Consider adding more descriptive key mapping descriptions.

The current descriptions are good but could be more specific about what the commands do.

-{ desc = 'Open harpoon window with telescope' }
+{ desc = 'Open Harpoon file list in Telescope' }

-{ desc = 'Open Harpoon Quick menu' }
+{ desc = 'Toggle Harpoon quick menu overlay' }
config/nvim/lua/plugins/conform.lua (2)

15-22: Remove redundant comments and consolidate default formatter configuration.

There are duplicate comments about setting the default formatter, and the commented-out formatter_opts adds noise.

 default_formatter = 'injected',
-      -- Set the default formatter for all filetypes
       default_formatter_opts = {
         lsp_format = 'fallback',
-        -- Set the default formatter for all filetypes
         formatter = 'injected',
-        -- Set the default formatter for all filetypes
-        -- formatter_opts = {},
       },

46-69: Refactor format-on-save function for better maintainability.

The function contains multiple conditions that could be extracted into separate functions for better readability and maintainability.

+local function should_ignore_filetype(bufnr)
+  local ignore_filetypes = { 'c', 'cpp', 'sql', 'java' }
+  return vim.tbl_contains(ignore_filetypes, vim.bo[bufnr].filetype)
+end
+
+local function is_formatting_disabled(bufnr)
+  return vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat
+end
+
+local function is_ignored_path(bufname)
+  local ignored_patterns = {
+    '/node_modules/',
+    '/vendor/',
+    '/dist/',
+    '/build/',
+  }
+  for _, pattern in ipairs(ignored_patterns) do
+    if bufname:match(pattern) then
+      return true
+    end
+  end
+  return false
+end
+
 format_on_save = function(bufnr)
-  -- Disable autoformat on certain filetypes
-  local ignore_filetypes = {
-    'c',
-    'cpp',
-    'sql',
-    'java',
-  }
-  if vim.tbl_contains(ignore_filetypes, vim.bo[bufnr].filetype) then
+  if should_ignore_filetype(bufnr) then
     return
   end
-  -- Disable with a global or buffer-local variable
-  if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then
+  if is_formatting_disabled(bufnr) then
     return
   end
-  -- Disable autoformat for files in a certain path
   local bufname = vim.api.nvim_buf_get_name(bufnr)
-  if bufname:match '/node_modules/' then return end
-  if bufname:match '/vendor/' then return end
-  if bufname:match '/dist/' then return end
-  if bufname:match '/build/' then return end
+  if is_ignored_path(bufname) then
+    return
+  end
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a76033a and 00bb730.

📒 Files selected for processing (14)
  • config/exports (1 hunks)
  • config/nvim/lua/plugins/comment.lua (1 hunks)
  • config/nvim/lua/plugins/conform.lua (1 hunks)
  • config/nvim/lua/plugins/flash.lua (1 hunks)
  • config/nvim/lua/plugins/harpoon.lua (1 hunks)
  • config/nvim/lua/plugins/lsp-saga.lua (1 hunks)
  • config/nvim/lua/plugins/neogen.lua (1 hunks)
  • config/nvim/lua/plugins/refactoring.lua (1 hunks)
  • config/nvim/lua/plugins/surround.lua (1 hunks)
  • config/nvim/lua/plugins/todo-comments.lua (1 hunks)
  • config/nvim/lua/plugins/treesj.lua (1 hunks)
  • config/nvim/lua/plugins/ufo.lua (1 hunks)
  • config/nvim/lua/plugins/vim-sleuth.lua (1 hunks)
  • local/bin/x-asdf-cleanup (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • config/nvim/lua/plugins/vim-sleuth.lua
  • config/nvim/lua/plugins/refactoring.lua
  • config/nvim/lua/plugins/todo-comments.lua
  • config/exports
🔇 Additional comments (10)
config/nvim/lua/plugins/ufo.lua (5)

1-2: Great descriptive header and reference link.
It's helpful that you included a short comment and the GitHub link for context and documentation.


15-37: Clear configuration for 'statuscol.nvim'.
The presence of well-documented segments with click-handlers provides a good user experience for fold functions, diagnostic signs, and line numbers. Nicely done!


41-53: LSP capabilities integration is well-structured.
Enabling foldingRange with dynamic registration ensures that your fold provider adapts to each LSP. Good approach.


55-71: Neat UFO plugin setup.
The configurations for open/close fold highlights, border, and scrolling mappings look correct. This provides a more intuitive folding experience.


76-119: Custom fold text handler is elegantly implemented.
The thorough inline documentation for folding lines is appreciated. The logic for displaying the truncated text and suffix ensures a better reading experience in folded lines.

config/nvim/lua/plugins/surround.lua (1)

Line range hint 3-9: Straightforward plugin addition.
This configuration is succinct and properly references the plugin repository. Loading on 'VeryLazy' helps optimize startup.

config/nvim/lua/plugins/comment.lua (1)

1-9: Solid addition of Comment.nvim integration.
The usage notes and the event triggers for 'BufRead' and 'BufNewFile' will ensure convenient plugin loading for commenting functionality.

config/nvim/lua/plugins/treesj.lua (1)

3-9: Nice plugin for splitting/joining code blocks.
Disabling the default keymaps offers flexibility for custom mappings. The chosen approach is straightforward and clean.

config/nvim/lua/plugins/flash.lua (1)

7-11: Verify key mapping conflicts

The zk mapping might conflict with popular note-taking plugins like zk-nvim. Consider documenting this potential conflict or using a different mapping.

config/nvim/lua/plugins/harpoon.lua (1)

4-9: Consider pinning the dependency versions for stability.

The plugin configuration uses the harpoon2 branch without specifying a specific commit or version. This could lead to unexpected behavior if the branch is updated.

Comment on lines 178 to 183
local fd_command="fd --base-directory $BASE_DIR --glob '.tool-versions' --hidden"
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
fd_command="$fd_command --exclude $pattern"
done
eval "$fd_command"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid using 'eval' for command construction.
Using 'eval' can potentially introduce security risks if BASE_DIR or excluded patterns are dynamically sourced from user input and contain malicious characters. Instead, build an array of arguments and pass it to 'fd' directly without eval.

- eval "$fd_command"
+ $fd_command

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 295 to 345
# Function to uninstall versions
# It will prompt the user for confirmation before uninstalling
# If DRYRUN is set to true, it will only print out the versions that would be uninstalled
#
# Usage: uninstall_versions
# Output: Uninstall the versions in uninstall_list array
uninstall_versions() {
if [[ ${#uninstall_list[@]} -gt 0 ]]; then
if [ "$DRYRUN" = true ]; then
confirm="y"
fi
if [ ! "$DRYRUN" = true ]; then
read -p "Do you want to proceed with uninstallation? (y/N): " confirm
fi
if [[ "$confirm" =~ ^[Yy]$ ]]; then
for key in "${uninstall_list[@]}"; do
local name="${key% *}"
local version="${key#* }"
if [ "$DRYRUN" = true ]; then
echo "(?) Dry run: would uninstall $name $version"
else
echo "(*) Uninstalling $name: $version"
asdf uninstall $name $version
fi
done
else
echo "Uninstallation aborted by user."
fi
else
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Based on the code review, I can now provide the final response:

Add error handling for asdf uninstall command failures
The current implementation doesn't check the exit status of asdf uninstall. Add error handling to inform users of failures and potentially continue with remaining uninstallations:

if ! asdf uninstall "$name" "$version"; then
  echo "(!) Failed to uninstall $name: $version"
  # Optionally: exit 1 or continue
fi
🔗 Analysis chain

Provide explicit error handling for 'asdf uninstall' failures.
While iterating over the versions to uninstall, if 'asdf uninstall' fails for any reason, the script continues. Consider implementing checks on the exit status of 'asdf uninstall' to inform the user if something fails.


Let me verify if there's any error handling for the asdf uninstall command in the codebase.


Let me try a different approach to get the context of the function.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# This script will search for any code references to asdf uninstall
# and verify if there's error handling already present.
rg -A3 'asdf uninstall'

Length of output: 196


Script:

#!/bin/bash
# Get more context around the uninstall_versions function
ast-grep --pattern 'uninstall_versions() {
  $$$
}'

Length of output: 53


Script:

#!/bin/bash
# Get the content of the file containing uninstall_versions function
cat local/bin/x-asdf-cleanup

Length of output: 9993

config/nvim/lua/plugins/neogen.lua Outdated Show resolved Hide resolved
config/nvim/lua/plugins/conform.lua Outdated Show resolved Hide resolved
@ivuorinen
Copy link
Owner Author

@coderabbitai full review

Copy link

coderabbitai bot commented Dec 20, 2024

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
local/bin/x-asdf-cleanup (1)

366-368: Use local declarations for arrays in main function

The associative arrays should be declared as local to prevent global namespace pollution:

-  declare -A defined_versions
-  declare -A installed_versions
-  declare -A keep_version
+  local -A defined_versions
+  local -A installed_versions
+  local -A keep_version
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a76033a and b1311b1.

📒 Files selected for processing (2)
  • config/exports (1 hunks)
  • local/bin/x-asdf-cleanup (1 hunks)
🔇 Additional comments (2)
local/bin/x-asdf-cleanup (2)

338-340: Add error handling for asdf uninstall command failures

The current implementation doesn't check if the uninstall command succeeds.


177-184: ⚠️ Potential issue

Security: Avoid using eval with command construction

The use of eval with $fd_command is potentially dangerous if BASE_DIR contains malicious characters. Consider using an array to build and execute the command:

-  local fd_command="fd --base-directory $BASE_DIR --glob '$FILE' --hidden"
-  for pattern in "${EXCLUDE_PATTERNS[@]}"; do
-    fd_command="$fd_command --exclude $pattern"
-  done
-  eval "$fd_command"
+  local -a cmd=(fd --base-directory "$BASE_DIR" --glob "$FILE" --hidden)
+  for pattern in "${EXCLUDE_PATTERNS[@]}"; do
+    cmd+=(--exclude "$pattern")
+  done
+  "${cmd[@]}"

Likely invalid or redundant comment.

Comment on lines 189 to 191
find_tool_versions_files() {
echo find_version_files ".tool-versions"
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix: Helper functions incorrectly echo command name instead of executing it

The helper functions find_tool_versions_files, find_nvmrc_files, and find_python_version_files are incorrectly echoing the command name instead of executing it.

-  echo find_version_files ".tool-versions"
+  find_version_files ".tool-versions"

Apply similar fixes to find_nvmrc_files and find_python_version_files.

Also applies to: 196-198, 203-205

local/bin/x-asdf-cleanup Outdated Show resolved Hide resolved
local/bin/x-asdf-cleanup Outdated Show resolved Hide resolved
Comment on lines +491 to +493
# tms, https://github.com/jrmoulton/tmux-sessionizer
export TMS_CONFIG_FILE="${XDG_CONFIG_HOME}/tms/config.toml"

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate export of TMS_CONFIG_FILE

This export statement is already defined earlier in the file and is redundant.

-# tms, https://github.com/jrmoulton/tmux-sessionizer
-export TMS_CONFIG_FILE="${XDG_CONFIG_HOME}/tms/config.toml"
-

@ivuorinen
Copy link
Owner Author

@coderabbitai generate docstrings

Copy link

coderabbitai bot commented Dec 25, 2024

✅ Actions performed

Docstrings generation started.

Copy link

coderabbitai bot commented Dec 25, 2024

Caution

No docstrings were generated.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
local/bin/x-asdf-cleanup (3)

177-184: ⚠️ Potential issue

Security: Avoid using 'eval' for command construction

Using 'eval' can introduce security risks if BASE_DIR or excluded patterns contain malicious characters.

Apply this fix:

 find_version_files() {
   local FILE="$1"
-  local fd_command="fd --base-directory $BASE_DIR --glob '$FILE' --hidden"
+  local args=("--base-directory" "$BASE_DIR" "--glob" "$FILE" "--hidden")
   for pattern in "${EXCLUDE_PATTERNS[@]}"; do
-    fd_command="$fd_command --exclude $pattern"
+    args+=("--exclude" "$pattern")
   done
-  eval "$fd_command"
+  fd "${args[@]}"
 }

189-191: ⚠️ Potential issue

Fix: Helper functions incorrectly echo command name instead of executing it

The helper functions are incorrectly echoing the command name instead of executing it.

Apply this fix to all helper functions:

 find_tool_versions_files() {
-  echo find_version_files ".tool-versions"
+  find_version_files ".tool-versions"
 }

 find_nvmrc_files() {
-  echo find_version_files ".nvmrc"
+  find_version_files ".nvmrc"
 }

 find_python_version_files() {
-  echo find_version_files ".python-version"
+  find_version_files ".python-version"
 }

Also applies to: 196-198, 203-205


319-347: ⚠️ Potential issue

Add error handling for asdf uninstall command failures

The uninstall_versions function doesn't check the exit status of asdf uninstall.

Apply this fix:

 if [ "$DRYRUN" = true ]; then
   echo "(?) Dry run: would uninstall $name $version"
 else
   echo "(*) Uninstalling $name: $version"
-  asdf uninstall $name $version
+  if ! asdf uninstall "$name" "$version"; then
+    echo "(!) Failed to uninstall $name: $version"
+    # Continue with remaining uninstallations
+  fi
 fi
🧹 Nitpick comments (1)
local/bin/x-asdf-cleanup (1)

352-381: Add cleanup confirmation before starting

When not in dry run mode, it would be helpful to ask for confirmation before starting the cleanup process, as it might take time for large codebases.

Apply this enhancement:

 main() {
   parse_arguments "$@"
 
   BASEDIR_IS_DIR=$(is_dir "$BASE_DIR")
   if [ "$BASEDIR_IS_DIR" = "no" ]; then
     echo "(!) Base directory $BASE_DIR does not exist or is not a directory"
     exit 1
   fi
 
+  if [ "$DRYRUN" = false ]; then
+    read -p "Start cleanup in $BASE_DIR? This might take a while. (y/N): " confirm
+    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
+      echo "Cleanup aborted by user."
+      exit 0
+    fi
+  fi
+
   files=$(find_tool_versions_files)
   echo "Found .tool-versions files:"
   echo "$files"
   echo
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b1311b1 and 4738dd8.

📒 Files selected for processing (1)
  • local/bin/x-asdf-cleanup (1 hunks)
🔇 Additional comments (1)
local/bin/x-asdf-cleanup (1)

1-40: LGTM! Well-structured initialization with proper dependency checks.

The script follows best practices with:

  • Comprehensive documentation
  • Strict mode enabled
  • Thorough dependency checks with helpful error messages
  • Proper debug mode implementation

Comment on lines 67 to 103
parse_arguments() {
for arg in "$@"; do
case $arg in
-h|--help)
usage
;;
-v|--version)
version
;;
--base-dir=*)
BASE_DIR="${arg#*=}"
shift
;;
--dry-run)
DRYRUN=true
shift
;;
--exclude=*)
EXCLUDE_PATTERNS+=("${arg#*=}")
shift
;;
--verbose)
VERBOSE=true
shift
;;
--debug)
DEBUG=true
shift
debug_info "$@"
;;
*)
echo "Unknown option: $arg"
usage
;;
esac
done
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix argument parsing logic

The shift commands in the parse_arguments function are misplaced and won't work as intended since they're inside the case statement but after the ;;. This means they never execute.

Apply this fix:

 parse_arguments() {
   for arg in "$@"; do
     case $arg in
       -h|--help)
         usage
-        ;;
-      -v|--version)
-        version
-        ;;
-      --base-dir=*)
-        BASE_DIR="${arg#*=}"
-        shift
-        ;;
-      --dry-run)
-        DRYRUN=true
-        shift
-        ;;
-      --exclude=*)
-        EXCLUDE_PATTERNS+=("${arg#*=}")
-        shift
-        ;;
-      --verbose)
-        VERBOSE=true
-        shift
-        ;;
-      --debug)
-        DEBUG=true
-        shift
-        debug_info "$@"
-        ;;
-      *)
-        echo "Unknown option: $arg"
-        usage
-        ;;
+        ;;
+      -v|--version)
+        version
+        ;;
+      --base-dir=*)
+        BASE_DIR="${arg#*=}"
+        ;;
+      --dry-run)
+        DRYRUN=true
+        ;;
+      --exclude=*)
+        EXCLUDE_PATTERNS+=("${arg#*=}")
+        ;;
+      --verbose)
+        VERBOSE=true
+        ;;
+      --debug)
+        DEBUG=true
+        debug_info "$@"
+        ;;
+      *)
+        echo "Unknown option: $arg"
+        usage
+        ;;
     esac
+    shift
   done
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
parse_arguments() {
for arg in "$@"; do
case $arg in
-h|--help)
usage
;;
-v|--version)
version
;;
--base-dir=*)
BASE_DIR="${arg#*=}"
shift
;;
--dry-run)
DRYRUN=true
shift
;;
--exclude=*)
EXCLUDE_PATTERNS+=("${arg#*=}")
shift
;;
--verbose)
VERBOSE=true
shift
;;
--debug)
DEBUG=true
shift
debug_info "$@"
;;
*)
echo "Unknown option: $arg"
usage
;;
esac
done
}
parse_arguments() {
for arg in "$@"; do
case $arg in
-h|--help)
usage
;;
-v|--version)
version
;;
--base-dir=*)
BASE_DIR="${arg#*=}"
;;
--dry-run)
DRYRUN=true
;;
--exclude=*)
EXCLUDE_PATTERNS+=("${arg#*=}")
;;
--verbose)
VERBOSE=true
;;
--debug)
DEBUG=true
debug_info "$@"
;;
*)
echo "Unknown option: $arg"
usage
;;
esac
shift
done
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
local/bin/x-asdf-cleanup (4)

23-26: Enhance dependency checks with version requirements

The dependency checks could be improved by verifying minimum required versions:

 if ! command -v asdf &> /dev/null; then
   echo "(!) asdf itself is not installed or not in PATH"
   exit 1
+else
+  # Verify minimum asdf version
+  local asdf_version=$(asdf --version | cut -d' ' -f1)
+  if ! printf '%s\n%s\n' "0.10.0" "$asdf_version" | sort -V -C; then
+    echo "(!) asdf version >= 0.10.0 is required"
+    exit 1
+  fi
 fi

 if ! command -v fd &> /dev/null; then
   echo "(!) Required tool fd is not installed or not in PATH"
   echo "It's used to find .tool-versions files faster"
   echo "Install it with asdf:"
   echo "asdf plugin add fd && asdf install fd latest"
   exit 1
+else
+  # Verify minimum fd version
+  local fd_version=$(fd --version | cut -d' ' -f2)
+  if ! printf '%s\n%s\n' "8.0.0" "$fd_version" | sort -V -C; then
+    echo "(!) fd version >= 8.0.0 is required"
+    exit 1
+  fi
 fi

Also applies to: 28-34


108-115: Add error handling to is_dir function

The function should handle cases where the directory parameter is empty or contains special characters:

 is_dir() {
   local dir="$1"
+  if [ -z "$dir" ]; then
+    echo "(!) Empty directory parameter" >&2
+    return 1
+  fi
   if [ -d "$dir" ]; then
     echo "yes"
   else
     echo "no"
   fi
 }

305-315: Enhance version comparison logic

The current implementation might miss versions that are semantically equivalent but syntactically different (e.g., "1.0.0" vs "1.0"):

 determine_versions_to_uninstall() {
   echo ""
   echo "Versions to Uninstall:"
   for key in "${!installed_versions[@]}"; do
-    if [[ -z ${keep_version[$key]} ]]; then
+    local name="${key% *}"
+    local version="${key#* }"
+    local normalized_version=$(normalize_version "$version")
+    local normalized_key="$name $normalized_version"
+    if [[ -z ${keep_version[$normalized_key]} ]]; then
       echo "$key"
       uninstall_list+=("$key")
     fi
   done
   echo
 }

Add this helper function at the top of the file:

# Normalize version string for comparison
# Example: normalize_version "1.0" returns "1.0.0"
normalize_version() {
  echo "$1" | awk -F. '{ printf("%d.%d.%d\n", $1,$2,$3) }' 2>/dev/null || echo "$1"
}

350-379: Improve main function organization and cleanup

  1. Move array declarations to the beginning
  2. Add cleanup handling
 # Main script execution
 main() {
+  # Declare associative arrays at the beginning
+  declare -A defined_versions
+  declare -A installed_versions
+  declare -A keep_version
+
+  # Set up cleanup trap
+  cleanup() {
+    unset defined_versions installed_versions keep_version
+    # Add any other cleanup needed
+  }
+  trap cleanup EXIT
+
   parse_arguments "$@"

   BASEDIR_IS_DIR=$(is_dir "$BASE_DIR")
   if [ "$BASEDIR_IS_DIR" = "no" ]; then
     echo "(!) Base directory $BASE_DIR does not exist or is not a directory"
     exit 1
   fi

   files=$(find_tool_versions_files)
   echo "Found .tool-versions files:"
   echo "$files"
   echo

-  # Declare associative arrays
-  declare -A defined_versions
-  declare -A installed_versions
-  declare -A keep_version

   read_defined_versions
   display_defined_versions
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4738dd8 and 663f4b7.

📒 Files selected for processing (2)
  • config/exports (1 hunks)
  • local/bin/x-asdf-cleanup (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • config/exports

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (6)
local/bin/x-asdf-cleanup (3)

121-126: Ensure proper cleanup in error handler.

The error_handler function should remove temporary files before calling cleanup to prevent resource leaks.

 error_handler()
 {
   local exit_code=$1
   print_error "An error occurred (exit code: $exit_code)"
+  rm -f "$TMPFILE"
   cleanup
 }

179-186: Optimize debug output handling.

The debug function writes to stderr unconditionally, which could impact performance when debug mode is off.

 debug()
 {
   if [[ $DEBUG == true ]]; then
     local timestamp
     timestamp=$(date '+%Y-%m-%d %H:%M:%S')
-    echo "[$timestamp][DEBUG] $*" >&2
+    printf '[%s][DEBUG] %s\n' "$timestamp" "$*" >&2
   fi
 }

1199-1276: Improve signal handling in main function.

The main function should handle additional signals and ensure proper cleanup.

 # Main execution
 main()
 {
+  # Set up signal handlers
+  trap 'cleanup' SIGTERM SIGINT SIGQUIT
+
   check_dependencies
   initialize_directories
   load_config
   # ... rest of the function ...
 }
local/bin/x-asdf-cleanup.md (3)

73-77: Enhance performance settings documentation

Consider adding explanations for:

  • How MAX_PARALLEL_JOBS affects system resources and cleanup speed
  • What data is cached and how USE_CACHE and CACHE_MAX_AGE impact performance

107-111: Fix grammar and enhance example with output

  1. Fix the grammar in the heading:
-Dry run to see what would be uninstalled:
+Dry-run to see what would be uninstalled:
  1. Consider adding example output to show users what to expect:
x-asdf-cleanup --dry-run
# Example output:
# Found unused versions:
#   nodejs 14.17.0
#   python 3.8.5
# These versions would be backed up and removed.
🧰 Tools
🪛 LanguageTool

[grammar] ~107-~107: The verb form doesn’t seem to match ‘Dry’. If it is an imperative, consider using a comma.
Context: ...ormation and exit ### Examples Dry run to see what would be uninstalled: b...

(NNP_VB_TO)


142-148: Fix grammar in contributing guidelines

Standardize the format of the list items:

3. Follow the coding standards:

-- Use shellcheck for bash script linting
-- Add comments for complex logic
-- Update documentation as needed
-- Add error handling for new functions
+- Use shellcheck for bash script linting
+- Add comments for complex logic
+- Update documentation as needed
+- Add error handling for new functions
🧰 Tools
🪛 LanguageTool

[grammar] ~147-~147: Did you mean “to Add”?
Context: ...ogic - Update documentation as needed - Add error handling for new functions 4. Te...

(MISSING_TO_BEFORE_A_VERB)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 663f4b7 and 11e1309.

📒 Files selected for processing (4)
  • .markdownlint.json (1 hunks)
  • .pre-commit-config.yaml (1 hunks)
  • local/bin/x-asdf-cleanup (1 hunks)
  • local/bin/x-asdf-cleanup.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
local/bin/x-asdf-cleanup.md

[grammar] ~107-~107: The verb form doesn’t seem to match ‘Dry’. If it is an imperative, consider using a comma.
Context: ...ormation and exit ### Examples Dry run to see what would be uninstalled: b...

(NNP_VB_TO)


[grammar] ~147-~147: Did you mean “to Add”?
Context: ...ogic - Update documentation as needed - Add error handling for new functions 4. Te...

(MISSING_TO_BEFORE_A_VERB)

🔇 Additional comments (4)
.markdownlint.json (1)

16-16: LGTM! Configuration change is appropriate.

The addition of "ol-prefix": false aligns well with the documentation needs and maintains consistency with existing markdown configuration.

.pre-commit-config.yaml (1)

28-28: LGTM! Configuration path updated correctly.

The markdownlint configuration path has been properly updated to reference the JSON configuration file, maintaining consistency with the previous change.

local/bin/x-asdf-cleanup (1)

16-16: 🛠️ Refactor suggestion

Enable full strict mode for better error handling.

The script only uses set -u but would benefit from full strict mode to catch errors early and prevent subtle bugs.

-#set -euo pipefail
+set -euo pipefail

Likely invalid or redundant comment.

local/bin/x-asdf-cleanup.md (1)

36-55: LGTM! Well-organized directory structure

The directory structure follows the XDG Base Directory Specification correctly, with clear separation of binaries, state data, configuration, and cache.


# Signal handling and cleanup
trap 'cleanup' INT TERM
#trap 'error_handler $?' ERR
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Uncomment error handler trap for comprehensive error handling.

The error handler trap is commented out, which means some errors might not be properly caught and handled.

-#trap 'error_handler $?' ERR
+trap 'error_handler $?' ERR
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#trap 'error_handler $?' ERR
trap 'error_handler $?' ERR

Comment on lines +1004 to +1006
--base-dir=*)
BASE_DIR="${arg#*=}"
;;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Validate base directory path in argument parsing.

The base directory path should be validated when it's provided as an argument.

       --base-dir=*)
         BASE_DIR="${arg#*=}"
+        if [[ ! -d $BASE_DIR ]]; then
+          handle_error 1 "Invalid base directory: $BASE_DIR"
+        fi
+        if [[ ! -r $BASE_DIR ]]; then
+          handle_error 1 "Base directory not readable: $BASE_DIR"
+        fi
         ;;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
--base-dir=*)
BASE_DIR="${arg#*=}"
;;
--base-dir=*)
BASE_DIR="${arg#*=}"
if [[ ! -d $BASE_DIR ]]; then
handle_error 1 "Invalid base directory: $BASE_DIR"
fi
if [[ ! -r $BASE_DIR ]]; then
handle_error 1 "Base directory not readable: $BASE_DIR"
fi
;;

Comment on lines +630 to +640
process_tool_versions_file()
{
local file="$1"
if [[ ! -f $file ]]; then
debug "File not found: $file"
return 1
fi
# Process file content and output "tool version" pairs
# Ignore comments and empty lines, require at least tool and version
awk '!/#/ && NF >= 2 {print $1, $2}' "$file"
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for file read operations.

The process_tool_versions_file function should handle file read errors properly.

 process_tool_versions_file()
 {
   local file="$1"
   if [[ ! -f $file ]]; then
     debug "File not found: $file"
     return 1
   fi
+  if [[ ! -r $file ]]; then
+    debug "File not readable: $file"
+    return 1
+  fi
   # Process file content and output "tool version" pairs
   # Ignore comments and empty lines, require at least tool and version
   awk '!/#/ && NF >= 2 {print $1, $2}' "$file"
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
process_tool_versions_file()
{
local file="$1"
if [[ ! -f $file ]]; then
debug "File not found: $file"
return 1
fi
# Process file content and output "tool version" pairs
# Ignore comments and empty lines, require at least tool and version
awk '!/#/ && NF >= 2 {print $1, $2}' "$file"
}
process_tool_versions_file()
{
local file="$1"
if [[ ! -f $file ]]; then
debug "File not found: $file"
return 1
fi
if [[ ! -r $file ]]; then
debug "File not readable: $file"
return 1
fi
# Process file content and output "tool version" pairs
# Ignore comments and empty lines, require at least tool and version
awk '!/#/ && NF >= 2 {print $1, $2}' "$file"
}

Comment on lines +851 to +868
create_backup()
{
local tool=$1
local version=$2
local backup_path="$BACKUP_DIR/${tool}_${version}_$(date +%Y%m%d_%H%M%S)"
local tool_path
tool_path=$(asdf where "$tool" "$version")

if [[ -d $tool_path ]]; then
debug "Creating backup of $tool $version"
log_to_file "INFO" "Creating backup of $tool $version"
if tar czf "$backup_path.tar.gz" -C "$(dirname "$tool_path")" "$(basename "$tool_path")"; then
echo "$tool $version" > "$LAST_OP_FILE"
return 0
fi
fi
return 1
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add backup directory permission checks and backup integrity verification.

The backup functions should validate directory permissions and verify backup integrity.

 create_backup()
 {
   local tool=$1
   local version=$2
   local backup_path="$BACKUP_DIR/${tool}_${version}_$(date +%Y%m%d_%H%M%S)"
   local tool_path
   tool_path=$(asdf where "$tool" "$version")

+  # Check backup directory permissions
+  if [[ ! -w $BACKUP_DIR ]]; then
+    debug "Backup directory not writable: $BACKUP_DIR"
+    return 1
+  fi

   if [[ -d $tool_path ]]; then
     debug "Creating backup of $tool $version"
     log_to_file "INFO" "Creating backup of $tool $version"
     if tar czf "$backup_path.tar.gz" -C "$(dirname "$tool_path")" "$(basename "$tool_path")"; then
+      # Verify backup integrity
+      if ! tar tzf "$backup_path.tar.gz" >/dev/null 2>&1; then
+        debug "Backup verification failed"
+        rm -f "$backup_path.tar.gz"
+        return 1
+      fi
       echo "$tool $version" > "$LAST_OP_FILE"
       return 0
     fi
   fi
   return 1
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
create_backup()
{
local tool=$1
local version=$2
local backup_path="$BACKUP_DIR/${tool}_${version}_$(date +%Y%m%d_%H%M%S)"
local tool_path
tool_path=$(asdf where "$tool" "$version")
if [[ -d $tool_path ]]; then
debug "Creating backup of $tool $version"
log_to_file "INFO" "Creating backup of $tool $version"
if tar czf "$backup_path.tar.gz" -C "$(dirname "$tool_path")" "$(basename "$tool_path")"; then
echo "$tool $version" > "$LAST_OP_FILE"
return 0
fi
fi
return 1
}
create_backup()
{
local tool=$1
local version=$2
local backup_path="$BACKUP_DIR/${tool}_${version}_$(date +%Y%m%d_%H%M%S)"
local tool_path
tool_path=$(asdf where "$tool" "$version")
# Check backup directory permissions
if [[ ! -w $BACKUP_DIR ]]; then
debug "Backup directory not writable: $BACKUP_DIR"
return 1
fi
if [[ -d $tool_path ]]; then
debug "Creating backup of $tool $version"
log_to_file "INFO" "Creating backup of $tool $version"
if tar czf "$backup_path.tar.gz" -C "$(dirname "$tool_path")" "$(basename "$tool_path")"; then
# Verify backup integrity
if ! tar tzf "$backup_path.tar.gz" >/dev/null 2>&1; then
debug "Backup verification failed"
rm -f "$backup_path.tar.gz"
return 1
fi
echo "$tool $version" > "$LAST_OP_FILE"
return 0
fi
fi
return 1
}

Comment on lines +901 to +934
read_installed_versions()
{
local current_tool=""
local line
debug "Reading installed versions from asdf"

while IFS= read -r line; do
if [[ $line =~ ^[^[:space:]] ]]; then
current_tool=$(trim_whitespace "$line")
continue
fi

line=$(trim_whitespace "$line")
if [[ $line == "No versions installed" ]]; then
print_warning "No versions installed for $current_tool"
log_to_file "WARNING" "No versions installed for $current_tool"
continue
fi

# Extract version, removing the asterisk if present
local version
if [[ $line =~ ^\* ]]; then
version=$(trim_whitespace "${line#\*}")
keep_version["$current_tool $version"]=1
debug "Keeping version: $current_tool $version"
else
version=$(trim_whitespace "$line")
fi

installed_versions["$current_tool $version"]=1
debug "Added installed version: $current_tool $version"

done < <(asdf list)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for asdf command failures.

The read_installed_versions function should handle asdf command failures gracefully.

 read_installed_versions()
 {
   local current_tool=""
   local line
   debug "Reading installed versions from asdf"

+  # Capture asdf output and check for errors
+  local asdf_output
+  if ! asdf_output=$(asdf list 2>&1); then
+    print_error "Failed to read installed versions: $asdf_output"
+    log_to_file "ERROR" "Failed to read installed versions: $asdf_output"
+    return 1
+  fi

-  while IFS= read -r line; do
+  while IFS= read -r line || [[ -n $line ]]; do
     if [[ $line =~ ^[^[:space:]] ]]; then
       current_tool=$(trim_whitespace "$line")
       continue
     fi
     # ... rest of the function ...
-  done < <(asdf list)
+  done <<< "$asdf_output"
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
read_installed_versions()
{
local current_tool=""
local line
debug "Reading installed versions from asdf"
while IFS= read -r line; do
if [[ $line =~ ^[^[:space:]] ]]; then
current_tool=$(trim_whitespace "$line")
continue
fi
line=$(trim_whitespace "$line")
if [[ $line == "No versions installed" ]]; then
print_warning "No versions installed for $current_tool"
log_to_file "WARNING" "No versions installed for $current_tool"
continue
fi
# Extract version, removing the asterisk if present
local version
if [[ $line =~ ^\* ]]; then
version=$(trim_whitespace "${line#\*}")
keep_version["$current_tool $version"]=1
debug "Keeping version: $current_tool $version"
else
version=$(trim_whitespace "$line")
fi
installed_versions["$current_tool $version"]=1
debug "Added installed version: $current_tool $version"
done < <(asdf list)
}
read_installed_versions()
{
local current_tool=""
local line
debug "Reading installed versions from asdf"
# Capture asdf output and check for errors
local asdf_output
if ! asdf_output=$(asdf list 2>&1); then
print_error "Failed to read installed versions: $asdf_output"
log_to_file "ERROR" "Failed to read installed versions: $asdf_output"
return 1
fi
while IFS= read -r line || [[ -n $line ]]; do
if [[ $line =~ ^[^[:space:]] ]]; then
current_tool=$(trim_whitespace "$line")
continue
fi
line=$(trim_whitespace "$line")
if [[ $line == "No versions installed" ]]; then
print_warning "No versions installed for $current_tool"
log_to_file "WARNING" "No versions installed for $current_tool"
continue
fi
# Extract version, removing the asterisk if present
local version
if [[ $line =~ ^\* ]]; then
version=$(trim_whitespace "${line#\*}")
keep_version["$current_tool $version"]=1
debug "Keeping version: $current_tool $version"
else
version=$(trim_whitespace "$line")
fi
installed_versions["$current_tool $version"]=1
debug "Added installed version: $current_tool $version"
done <<< "$asdf_output"
}

Comment on lines +197 to +202
4. Run tests:

```bash
shellcheck x-asdf-cleanup
shfmt -d x-asdf-cleanup
```
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance testing framework

The current testing approach only covers linting. Consider adding:

  1. Unit tests for core functionality
  2. Integration tests for version management
  3. Test cases for error scenarios

Would you like me to help create a test framework with example test cases?

Comment on lines +5 to +16
## Features

- Scans for version files (`.tool-versions`, `.nvmrc`, `.python-version`)
- Detects installed versions that are no longer in use
- Supports dry-run mode for safe verification
- Parallel processing for better performance
- Built-in caching system
- Automatic backups before uninstallation
- Restore functionality for accidental removals
- Comprehensive logging
- Progress indication during operations
- Performance metrics
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add security considerations section

Consider adding a section on security that covers:

  • Risks of automatic version removal
  • Backup security and retention policy
  • Permission requirements
  • Safe handling of system-wide changes


```bash
mkdir -p ~/.local/bin
curl -o ~/.local/bin/x-asdf-cleanup https://raw.githubusercontent.com/yourusername/dotfiles/main/.dotfiles/local/bin/x-asdf-cleanup
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the installation URL placeholder

The curl command contains a placeholder URL that needs to be updated with the correct repository path.

-curl -o ~/.local/bin/x-asdf-cleanup https://raw.githubusercontent.com/yourusername/dotfiles/main/.dotfiles/local/bin/x-asdf-cleanup
+curl -o ~/.local/bin/x-asdf-cleanup https://raw.githubusercontent.com/ivuorinen/dotfiles/main/.dotfiles/local/bin/x-asdf-cleanup
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
curl -o ~/.local/bin/x-asdf-cleanup https://raw.githubusercontent.com/yourusername/dotfiles/main/.dotfiles/local/bin/x-asdf-cleanup
curl -o ~/.local/bin/x-asdf-cleanup https://raw.githubusercontent.com/ivuorinen/dotfiles/main/.dotfiles/local/bin/x-asdf-cleanup

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.

1 participant