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 <user@example.com>
This commit is contained in:
+111
-26
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user