build: replace luacheck with selene, add nix devshell and pre-commit (#20)
* build: replace luacheck with selene Problem: luacheck is unmaintained (last release 2018) and required suppressing four warning classes to avoid false positives. It also lacks first-class vim/neovim awareness. Solution: switch to selene with std='vim' for vim-aware linting. Replace the luacheck CI job with selene, update the Makefile lint target, and delete .luacheckrc. * build: add nix devshell and pre-commit hooks Problem: oil.nvim had no reproducible dev environment. The .envrc set up a Python venv for the now-removed docgen pipeline, and there were no pre-commit hooks for local formatting checks. Solution: add flake.nix with stylua, selene, and prettier in the devshell. Replace the stale Python .envrc with 'use flake'. Add .pre-commit-config.yaml with stylua and prettier hooks matching other plugins in the repo collection. * fix: format with stylua * build(selene): configure lints and add inline suppressions Problem: selene fails on 5 errors and 3 warnings from upstream code patterns that are intentional (mixed tables in config API, unused callback parameters, identical if branches for readability). Solution: globally allow mixed_table and unused_variable (high volume, inherent to the codebase design). Add inline selene:allow directives for the 8 remaining issues: if_same_then_else (4), mismatched_arg_count (1), empty_if (2), global_usage (1). Remove .envrc from tracking. * build: switch typecheck action to mrcjkb/lua-typecheck-action Problem: oil.nvim used stevearc/nvim-typecheck-action, which required cloning the action repo locally for the Makefile lint target. All other plugins in the collection use mrcjkb/lua-typecheck-action. Solution: swap to mrcjkb/lua-typecheck-action@v0 for consistency. Remove the nvim-typecheck-action git clone from the Makefile and .gitignore. Drop LuaLS from the local lint target since it requires a full language server install — CI handles it.
This commit is contained in:
parent
df53b172a9
commit
86f553cd0a
72 changed files with 2762 additions and 2649 deletions
|
|
@ -1,8 +1,8 @@
|
|||
local SSHConnection = require("oil.adapters.ssh.connection")
|
||||
local cache = require("oil.cache")
|
||||
local constants = require("oil.constants")
|
||||
local permissions = require("oil.adapters.files.permissions")
|
||||
local util = require("oil.util")
|
||||
local SSHConnection = require('oil.adapters.ssh.connection')
|
||||
local cache = require('oil.cache')
|
||||
local constants = require('oil.constants')
|
||||
local permissions = require('oil.adapters.files.permissions')
|
||||
local util = require('oil.util')
|
||||
|
||||
---@class (exact) oil.sshFs
|
||||
---@field new fun(url: oil.sshUrl): oil.sshFs
|
||||
|
|
@ -13,13 +13,13 @@ local FIELD_TYPE = constants.FIELD_TYPE
|
|||
local FIELD_META = constants.FIELD_META
|
||||
|
||||
local typechar_map = {
|
||||
l = "link",
|
||||
d = "directory",
|
||||
p = "fifo",
|
||||
s = "socket",
|
||||
["-"] = "file",
|
||||
c = "file", -- character special file
|
||||
b = "file", -- block special file
|
||||
l = 'link',
|
||||
d = 'directory',
|
||||
p = 'fifo',
|
||||
s = 'socket',
|
||||
['-'] = 'file',
|
||||
c = 'file', -- character special file
|
||||
b = 'file', -- block special file
|
||||
}
|
||||
---@param line string
|
||||
---@return string Name of entry
|
||||
|
|
@ -27,11 +27,11 @@ local typechar_map = {
|
|||
---@return table Metadata for entry
|
||||
local function parse_ls_line(line)
|
||||
local typechar, perms, refcount, user, group, rem =
|
||||
line:match("^(.)(%S+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(.*)$")
|
||||
line:match('^(.)(%S+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(.*)$')
|
||||
if not typechar then
|
||||
error(string.format("Could not parse '%s'", line))
|
||||
end
|
||||
local type = typechar_map[typechar] or "file"
|
||||
local type = typechar_map[typechar] or 'file'
|
||||
|
||||
local meta = {
|
||||
user = user,
|
||||
|
|
@ -40,26 +40,26 @@ local function parse_ls_line(line)
|
|||
refcount = tonumber(refcount),
|
||||
}
|
||||
local name, size, date, major, minor
|
||||
if typechar == "c" or typechar == "b" then
|
||||
major, minor, date, name = rem:match("^(%d+)%s*,%s*(%d+)%s+(%S+%s+%d+%s+%d%d:?%d%d)%s+(.*)")
|
||||
if typechar == 'c' or typechar == 'b' then
|
||||
major, minor, date, name = rem:match('^(%d+)%s*,%s*(%d+)%s+(%S+%s+%d+%s+%d%d:?%d%d)%s+(.*)')
|
||||
if name == nil then
|
||||
major, minor, date, name =
|
||||
rem:match("^(%d+)%s*,%s*(%d+)%s+(%d+%-%d+%-%d+%s+%d%d:?%d%d)%s+(.*)")
|
||||
rem:match('^(%d+)%s*,%s*(%d+)%s+(%d+%-%d+%-%d+%s+%d%d:?%d%d)%s+(.*)')
|
||||
end
|
||||
meta.major = tonumber(major)
|
||||
meta.minor = tonumber(minor)
|
||||
else
|
||||
size, date, name = rem:match("^(%d+)%s+(%S+%s+%d+%s+%d%d:?%d%d)%s+(.*)")
|
||||
size, date, name = rem:match('^(%d+)%s+(%S+%s+%d+%s+%d%d:?%d%d)%s+(.*)')
|
||||
if name == nil then
|
||||
size, date, name = rem:match("^(%d+)%s+(%d+%-%d+%-%d+%s+%d%d:?%d%d)%s+(.*)")
|
||||
size, date, name = rem:match('^(%d+)%s+(%d+%-%d+%-%d+%s+%d%d:?%d%d)%s+(.*)')
|
||||
end
|
||||
meta.size = tonumber(size)
|
||||
end
|
||||
meta.iso_modified_date = date
|
||||
if type == "link" then
|
||||
if type == 'link' then
|
||||
local link
|
||||
name, link = unpack(vim.split(name, " -> ", { plain = true }))
|
||||
if vim.endswith(link, "/") then
|
||||
name, link = unpack(vim.split(name, ' -> ', { plain = true }))
|
||||
if vim.endswith(link, '/') then
|
||||
link = link:sub(1, #link - 1)
|
||||
end
|
||||
meta.link = link
|
||||
|
|
@ -94,7 +94,7 @@ end
|
|||
---@param callback fun(err: nil|string)
|
||||
function SSHFS:chmod(value, path, callback)
|
||||
local octal = permissions.mode_to_octal_str(value)
|
||||
self.conn:run(string.format("chmod %s %s", octal, shellescape(path)), callback)
|
||||
self.conn:run(string.format('chmod %s %s', octal, shellescape(path)), callback)
|
||||
end
|
||||
|
||||
function SSHFS:open_terminal()
|
||||
|
|
@ -114,24 +114,24 @@ function SSHFS:realpath(path, callback)
|
|||
return callback(err)
|
||||
end
|
||||
assert(lines)
|
||||
local abspath = table.concat(lines, "")
|
||||
local abspath = table.concat(lines, '')
|
||||
-- If the path was "." then the abspath might be /path/to/., so we need to trim that final '.'
|
||||
if vim.endswith(abspath, ".") then
|
||||
if vim.endswith(abspath, '.') then
|
||||
abspath = abspath:sub(1, #abspath - 1)
|
||||
end
|
||||
self.conn:run(
|
||||
string.format("LC_ALL=C ls -land --color=never %s", shellescape(abspath)),
|
||||
string.format('LC_ALL=C ls -land --color=never %s', shellescape(abspath)),
|
||||
function(ls_err, ls_lines)
|
||||
local type
|
||||
if ls_err then
|
||||
-- If the file doesn't exist, treat it like a not-yet-existing directory
|
||||
type = "directory"
|
||||
type = 'directory'
|
||||
else
|
||||
assert(ls_lines)
|
||||
local _
|
||||
_, type = parse_ls_line(ls_lines[1])
|
||||
end
|
||||
if type == "directory" then
|
||||
if type == 'directory' then
|
||||
abspath = util.addslash(abspath)
|
||||
end
|
||||
callback(nil, abspath)
|
||||
|
|
@ -146,13 +146,13 @@ local dir_meta = {}
|
|||
---@param path string
|
||||
---@param callback fun(err?: string, entries?: oil.InternalEntry[], fetch_more?: fun())
|
||||
function SSHFS:list_dir(url, path, callback)
|
||||
local path_postfix = ""
|
||||
if path ~= "" then
|
||||
path_postfix = string.format(" %s", shellescape(path))
|
||||
local path_postfix = ''
|
||||
if path ~= '' then
|
||||
path_postfix = string.format(' %s', shellescape(path))
|
||||
end
|
||||
self.conn:run("LC_ALL=C ls -lan --color=never" .. path_postfix, function(err, lines)
|
||||
self.conn:run('LC_ALL=C ls -lan --color=never' .. path_postfix, function(err, lines)
|
||||
if err then
|
||||
if err:match("No such file or directory%s*$") then
|
||||
if err:match('No such file or directory%s*$') then
|
||||
-- If the directory doesn't exist, treat the list as a success. We will be able to traverse
|
||||
-- and edit a not-yet-existing directory.
|
||||
return callback()
|
||||
|
|
@ -165,12 +165,12 @@ function SSHFS:list_dir(url, path, callback)
|
|||
local entries = {}
|
||||
local cache_entries = {}
|
||||
for _, line in ipairs(lines) do
|
||||
if line ~= "" and not line:match("^total") then
|
||||
if line ~= '' and not line:match('^total') then
|
||||
local name, type, meta = parse_ls_line(line)
|
||||
if name == "." then
|
||||
if name == '.' then
|
||||
dir_meta[url] = meta
|
||||
elseif name ~= ".." then
|
||||
if type == "link" then
|
||||
elseif name ~= '..' then
|
||||
if type == 'link' then
|
||||
any_links = true
|
||||
end
|
||||
local cache_entry = cache.create_entry(url, name, type)
|
||||
|
|
@ -184,19 +184,19 @@ function SSHFS:list_dir(url, path, callback)
|
|||
-- If there were any soft links, then we need to run another ls command with -L so that we can
|
||||
-- resolve the type of the link target
|
||||
self.conn:run(
|
||||
"LC_ALL=C ls -naLl --color=never" .. path_postfix .. " 2> /dev/null",
|
||||
'LC_ALL=C ls -naLl --color=never' .. path_postfix .. ' 2> /dev/null',
|
||||
function(link_err, link_lines)
|
||||
-- Ignore exit code 1. That just means one of the links could not be resolved.
|
||||
if link_err and not link_err:match("^1:") then
|
||||
if link_err and not link_err:match('^1:') then
|
||||
return callback(link_err)
|
||||
end
|
||||
assert(link_lines)
|
||||
for _, line in ipairs(link_lines) do
|
||||
if line ~= "" and not line:match("^total") then
|
||||
if line ~= '' and not line:match('^total') then
|
||||
local ok, name, type, meta = pcall(parse_ls_line, line)
|
||||
if ok and name ~= "." and name ~= ".." then
|
||||
if ok and name ~= '.' and name ~= '..' then
|
||||
local cache_entry = entries[name]
|
||||
if cache_entry[FIELD_TYPE] == "link" then
|
||||
if cache_entry[FIELD_TYPE] == 'link' then
|
||||
cache_entry[FIELD_META].link_stat = {
|
||||
type = type,
|
||||
size = meta.size,
|
||||
|
|
@ -217,40 +217,40 @@ end
|
|||
---@param path string
|
||||
---@param callback fun(err: nil|string)
|
||||
function SSHFS:mkdir(path, callback)
|
||||
self.conn:run(string.format("mkdir -p %s", shellescape(path)), callback)
|
||||
self.conn:run(string.format('mkdir -p %s', shellescape(path)), callback)
|
||||
end
|
||||
|
||||
---@param path string
|
||||
---@param callback fun(err: nil|string)
|
||||
function SSHFS:touch(path, callback)
|
||||
self.conn:run(string.format("touch %s", shellescape(path)), callback)
|
||||
self.conn:run(string.format('touch %s', shellescape(path)), callback)
|
||||
end
|
||||
|
||||
---@param path string
|
||||
---@param link string
|
||||
---@param callback fun(err: nil|string)
|
||||
function SSHFS:mklink(path, link, callback)
|
||||
self.conn:run(string.format("ln -s %s %s", shellescape(link), shellescape(path)), callback)
|
||||
self.conn:run(string.format('ln -s %s %s', shellescape(link), shellescape(path)), callback)
|
||||
end
|
||||
|
||||
---@param path string
|
||||
---@param callback fun(err: nil|string)
|
||||
function SSHFS:rm(path, callback)
|
||||
self.conn:run(string.format("rm -rf %s", shellescape(path)), callback)
|
||||
self.conn:run(string.format('rm -rf %s', shellescape(path)), callback)
|
||||
end
|
||||
|
||||
---@param src string
|
||||
---@param dest string
|
||||
---@param callback fun(err: nil|string)
|
||||
function SSHFS:mv(src, dest, callback)
|
||||
self.conn:run(string.format("mv %s %s", shellescape(src), shellescape(dest)), callback)
|
||||
self.conn:run(string.format('mv %s %s', shellescape(src), shellescape(dest)), callback)
|
||||
end
|
||||
|
||||
---@param src string
|
||||
---@param dest string
|
||||
---@param callback fun(err: nil|string)
|
||||
function SSHFS:cp(src, dest, callback)
|
||||
self.conn:run(string.format("cp -r %s %s", shellescape(src), shellescape(dest)), callback)
|
||||
self.conn:run(string.format('cp -r %s %s', shellescape(src), shellescape(dest)), callback)
|
||||
end
|
||||
|
||||
function SSHFS:get_dir_meta(url)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue