From 1af2b4cc7d3d06d5d3029d18793df2cdbc3e5013 Mon Sep 17 00:00:00 2001 From: User Date: Sat, 11 Oct 2025 19:03:11 +0000 Subject: [PATCH] refactor: enhance polish.lua with comprehensive documentation, security validation, and improved error handling - Add LuaDoc annotations and type definitions for better code documentation - Implement package name validation to prevent command injection attacks - Improve error handling with proper notifications and graceful failure handling - Remove debug prints and make code production-ready - Add proper module exports for better code organization - Clean up obsolete lazy_lock_files/vue.json file Signed-off-by: User --- lazy_lock_files/vue.json | 56 ---------------- lua/polish.lua | 137 +++++++++++++++++++++++++++++++-------- 2 files changed, 111 insertions(+), 82 deletions(-) delete mode 100644 lazy_lock_files/vue.json diff --git a/lazy_lock_files/vue.json b/lazy_lock_files/vue.json deleted file mode 100644 index f03aec4..0000000 --- a/lazy_lock_files/vue.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "AstroNvim": { "branch": "main", "commit": "55a2b084eabe880c4ffa377f82bb972caec57e09" }, - "Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" }, - "LuaSnip": { "branch": "master", "commit": "458560534a73f7f8d7a11a146c801db00b081df0" }, - "aerial.nvim": { "branch": "master", "commit": "6ab1a0ce4874d21610fc5a67a6c82c7b943c635b" }, - "astrocommunity": { "branch": "main", "commit": "378c6d88f6648475057992709594b0ff5419c083" }, - "astrocore": { "branch": "main", "commit": "c797dd5a592e2bd154f2503e231b8a4083659534" }, - "astrolsp": { "branch": "main", "commit": "0befe28a4ea96e46b7f7c01e4a634c04225ba55a" }, - "astrotheme": { "branch": "main", "commit": "4a2af93815e4e6adfe69c836e46047a9451de858" }, - "astroui": { "branch": "main", "commit": "4943abbd42674b43249313afe83b91065a40e4be" }, - "better-escape.nvim": { "branch": "master", "commit": "199dcc2643dec5d8dbdab4ec672cf405224dcb3b" }, - "blink.cmp": { "branch": "main", "commit": "327fff91fe6af358e990be7be1ec8b78037d2138" }, - "blink.compat": { "branch": "main", "commit": "2ed6d9a28b07fa6f3bface818470605f8896408c" }, - "cmp-dap": { "branch": "master", "commit": "ea92773e84c0ad3288c3bc5e452ac91559669087" }, - "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, - "gitsigns.nvim": { "branch": "main", "commit": "7010000889bfb6c26065e0b0f7f1e6aa9163edd9" }, - "guess-indent.nvim": { "branch": "main", "commit": "84a4987ff36798c2fc1169cbaff67960aed9776f" }, - "heirline.nvim": { "branch": "master", "commit": "fae936abb5e0345b85c3a03ecf38525b0828b992" }, - "lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" }, - "lazydev.nvim": { "branch": "main", "commit": "f59bd14a852ca43db38e3662395354cb2a9b13e0" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "1a31f824b9cd5bc6f342fc29e9a53b60d74af245" }, - "mason-null-ls.nvim": { "branch": "main", "commit": "2b8433f76598397fcc97318d410e0c4f7a4bea6a" }, - "mason-nvim-dap.nvim": { "branch": "main", "commit": "4c2cdc69d69fe00c15ae8648f7e954d99e5de3ea" }, - "mason-tool-installer.nvim": { "branch": "main", "commit": "517ef5994ef9d6b738322664d5fdd948f0fdeb46" }, - "mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" }, - "mini.icons": { "branch": "main", "commit": "397ed3807e96b59709ef3292f0a3e253d5c1dc0a" }, - "neo-tree.nvim": { "branch": "main", "commit": "4c60a198e3f92098778a32a1c76d2bd7ba46a3b5" }, - "neoconf.nvim": { "branch": "main", "commit": "7a8d7fd36f95f5cbbf57d4a5c463f6c54ad54cd3" }, - "none-ls.nvim": { "branch": "main", "commit": "6617d47fbf275d197e3335022a3d33ff310a4b93" }, - "nui.nvim": { "branch": "main", "commit": "f535005e6ad1016383f24e39559833759453564e" }, - "nvim-autopairs": { "branch": "master", "commit": "23320e75953ac82e559c610bec5a90d9c6dfa743" }, - "nvim-dap": { "branch": "master", "commit": "7367cec8e8f7a0b1e4566af9a7ef5959d11206a7" }, - "nvim-dap-ui": { "branch": "master", "commit": "cf91d5e2d07c72903d052f5207511bf7ecdb7122" }, - "nvim-highlight-colors": { "branch": "main", "commit": "e0c4a58ec8c3ca7c92d3ee4eb3bc1dd0f7be317e" }, - "nvim-lsp-file-operations": { "branch": "master", "commit": "9744b738183a5adca0f916527922078a965515ed" }, - "nvim-lspconfig": { "branch": "master", "commit": "fa2662510d30b06168b6e2e6915518decde6bbac" }, - "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, - "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, - "nvim-treesitter-textobjects": { "branch": "master", "commit": "71385f191ec06ffc60e80e6b0c9a9d5daed4824c" }, - "nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" }, - "nvim-ts-context-commentstring": { "branch": "main", "commit": "cb064386e667def1d241317deed9fd1b38f0dc2e" }, - "nvim-ufo": { "branch": "main", "commit": "61463090a4f55f5d080236ea62f09d1cd8976ff3" }, - "nvim-vtsls": { "branch": "main", "commit": "0b5f73c9e50ce95842ea07bb3f05c7d66d87d14a" }, - "nvim-window-picker": { "branch": "main", "commit": "6382540b2ae5de6c793d4aa2e3fe6dbb518505ec" }, - "package-info.nvim": { "branch": "master", "commit": "a1de9eb91fa52ab8361f0c05032673670a3d10ff" }, - "pendulum-nvim": { "branch": "main", "commit": "c129ae3d69f164b3e51e067b0eca45a8d3da29ee" }, - "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, - "resession.nvim": { "branch": "master", "commit": "cc819b0489938d03e4f3532a583354f0287c015b" }, - "smart-splits.nvim": { "branch": "master", "commit": "ddb23c1a1cf1507bda487cda7f6e4690965ef9f5" }, - "snacks.nvim": { "branch": "main", "commit": "da230e3ca8146da4b73752daaf0a1d07d343c12d" }, - "todo-comments.nvim": { "branch": "main", "commit": "304a8d204ee787d2544d8bc23cd38d2f929e7cc5" }, - "toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" }, - "tsc.nvim": { "branch": "main", "commit": "8c1b4ec6a48d038a79ced8674cb15e7db6dd8ef0" }, - "vim-illuminate": { "branch": "master", "commit": "0d1e93684da00ab7c057410fecfc24f434698898" }, - "which-key.nvim": { "branch": "main", "commit": "fcbf4eea17cb299c02557d576f0d568878e354a4" } -} diff --git a/lua/polish.lua b/lua/polish.lua index 1fe0947..0476742 100644 --- a/lua/polish.lua +++ b/lua/polish.lua @@ -1,8 +1,19 @@ --- This will run last in the setup process. --- This is just pure lua so anything that doesn't --- fit in the normal config locations above can go here +--- @meta --- Framework-specific tool configurations +--- Framework-specific tool configurations and installation utilities for Neovim. +--- This module provides automatic installation of language servers and tools +--- based on the current development framework environment. +--- It reads the FRAMEWORK environment variable to determine which tools to install. + +--- @alias FrameworkName "python"|"vue"|string + +--- @class FrameworkTools +--- @field python string[] Python development tools and LSP servers including formatters, linters, and type checkers +--- @field vue string[] Vue.js development tools and LSP servers including JavaScript/TypeScript tools and CSS utilities + +--- Framework-specific tool configurations +--- Maps framework names to their respective tool lists +--- @type FrameworkTools local FRAMEWORK_TOOLS = { python = { "black", @@ -27,50 +38,124 @@ local FRAMEWORK_TOOLS = { }, } ---- Retrieves the appropriate tool set based on the current framework environment ---- @return table List of tools to install for the detected framework +--- Retrieves the appropriate tool set based on the current framework environment. +--- This function checks the FRAMEWORK environment variable and returns the corresponding +--- tool list from FRAMEWORK_TOOLS. If no framework is set or the framework is not recognized, +--- returns an empty table. +--- @return string[] tools List of tools to install for the detected framework, or empty table if no framework is set local function get_framework_tools() - local current_framework = os.getenv "FRAMEWORK" - print("[DEBUG] Current FRAMEWORK environment variable: " .. tostring(current_framework)) + local current_framework = os.getenv("FRAMEWORK") if current_framework then - print("[DEBUG] Available frameworks: " .. vim.inspect(vim.tbl_keys(FRAMEWORK_TOOLS))) local tools = FRAMEWORK_TOOLS[current_framework] - print("[DEBUG] Tools for framework '" .. current_framework .. "': " .. vim.inspect(tools)) return tools or {} else - print "[DEBUG] No FRAMEWORK environment variable set, returning empty list" return {} end end --- Функция для установки списка пакетов Mason +--- Validates if a package name is safe to install. +--- This function performs basic security validation to prevent command injection +--- and ensures package names follow expected patterns. +--- @param package_name string The package name to validate +--- @return boolean is_valid True if the package name is valid, false otherwise +local function is_valid_package_name(package_name) + -- Basic validation: package names should only contain alphanumeric characters, hyphens, and dots + -- This prevents command injection attacks + if type(package_name) ~= "string" or package_name == "" then + return false + end + + -- Additional security: check for potentially dangerous patterns + local dangerous_patterns = { + "%.%.%/", -- Path traversal + "%;", -- Command separator + "%|", -- Pipe + "%&", -- Background process + "%`", -- Command substitution + "%$", -- Variable expansion + "%!" -- History expansion + } + + for _, pattern in ipairs(dangerous_patterns) do + if string.match(package_name, pattern) then + return false + end + end + + -- Check for valid characters: alphanumeric, hyphen, dot, underscore + local valid_pattern = "^[%w%-%.%_]+$" + return string.match(package_name, valid_pattern) ~= nil +end + +--- Checks if Mason is available and ready for package installation. +--- @return boolean is_available True if Mason is available, false otherwise +local function is_mason_available() + local mason_ok, _ = pcall(require, "mason") + return mason_ok +end + + +--- Installs Mason packages based on the current framework environment. +--- This function retrieves the appropriate tool set and installs them one by one +--- to handle individual failures gracefully. Each package installation is wrapped +--- in a protected call to prevent one failure from stopping the entire process. +--- @return nil function InstallMyMasonPackages() - print "[DEBUG] Starting InstallMyMasonPackages function" + -- Check if Mason is available first + if not is_mason_available() then + vim.notify("Mason is not available. Please install Mason first.", vim.log.levels.ERROR) + return + end + local packages = get_framework_tools() - print("[DEBUG] Packages to install: " .. vim.inspect(packages)) if #packages > 0 then + local installed_count = 0 + local failed_count = 0 + -- Install packages one by one to handle individual failures for _, package in ipairs(packages) do - print("[DEBUG] Installing package: " .. package) - local success, result = pcall(function() vim.cmd("MasonInstall " .. package) end) - - if not success then - print("[WARNING] Failed to install " .. package .. ": " .. tostring(result)) + -- Validate package name for security + if not is_valid_package_name(package) then + vim.notify("Skipping invalid package name: " .. package, vim.log.levels.WARN) + failed_count = failed_count + 1 else - print("[DEBUG] Successfully installed " .. package) + local success, result = pcall(function() + vim.cmd("MasonInstall " .. package) + end) + + if success then + installed_count = installed_count + 1 + vim.notify("Successfully installed: " .. package, vim.log.levels.INFO) + else + failed_count = failed_count + 1 + vim.notify("Failed to install " .. package .. ": " .. tostring(result), vim.log.levels.WARN) + end end end - print "[DEBUG] MasonInstall process completed" + + -- Provide summary + if failed_count == 0 then + vim.notify("Framework-specific packages installation completed successfully. Installed: " .. installed_count .. " packages", vim.log.levels.INFO) + else + vim.notify("Framework-specific packages installation completed with " .. failed_count .. " failures. Successfully installed: " .. installed_count .. " packages", vim.log.levels.WARN) + end else - print "[DEBUG] No packages to install, skipping MasonInstall" + vim.notify("No framework detected or no packages to install", vim.log.levels.INFO) end end --- Создание пользовательской команды +-- Create user command for Mason installation vim.api.nvim_create_user_command( - "MasonInstallR", -- Имя команды - InstallMyMasonPackages, -- Вызываемая функция - { nargs = 0 } -- Команда не принимает аргументов + "MasonInstallR", -- Command name + InstallMyMasonPackages, -- Function to call + { nargs = 0 } -- Command takes no arguments ) + +-- Module exports +return { + FRAMEWORK_TOOLS = FRAMEWORK_TOOLS, + get_framework_tools = get_framework_tools, + InstallMyMasonPackages = InstallMyMasonPackages, +}