diff --git a/.gitea/workflows/pull_request.yaml b/.gitea/workflows/pull_request.yaml new file mode 100644 index 0000000..a9599d0 --- /dev/null +++ b/.gitea/workflows/pull_request.yaml @@ -0,0 +1,35 @@ +name: Pull Request Checks +on: + pull_request: + branches: [main] +jobs: + checks: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v7 + - name: Install stylua + run: | + curl -L -o stylua.zip https://github.com/JohnnyMorganz/StyLua/releases/latest/download/stylua-linux-x86_64.zip + unzip -o stylua.zip + chmod +x stylua + mv stylua /usr/local/bin/ + - name: Install lua-language-server + run: | + LUA_LS_URL=$(curl -s https://api.github.com/repos/LuaLS/lua-language-server/releases/latest \ + | grep '"browser_download_url".*linux-x64' \ + | sed 's/.*"\(.*\)".*/\1/') + curl -L -o /tmp/lua-ls.tar.gz "$LUA_LS_URL" + mkdir -p /usr/local/lib/lua-language-server + tar -xzf /tmp/lua-ls.tar.gz -C /usr/local/lib/lua-language-server + ln -s /usr/local/lib/lua-language-server/bin/lua-language-server /usr/local/bin/lua-language-server + - name: Install neovim + run: | + curl -L -o /tmp/nvim.tar.gz https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz + tar -xzf /tmp/nvim.tar.gz -C /usr/local --strip-components=1 + - name: Format check + run: stylua --check . + - name: Lint + run: lua-language-server --check=. + - name: Test + run: nvim --headless -c "PlenaryBustedDirectory tests/watchexec/ {minimal_init = 'tests/minimal_init.lua'}" -c "q" diff --git a/.luarc.json b/.luarc.json index 281018d..324764d 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,13 +1,27 @@ { + "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", "compiler": { "verbosity": "Information" }, + "diagnostics": { + "globals": [ + "vim", + "describe", + "it", + "before_each", + "after_each", + "assert" + ] + }, "workspace": { + "checkThirdParty": false, "library": [ "$VIMRUNTIME/lua", "${3rd}/luv/library", "./.tests/vendor/plenary.nvim" ] - } + }, + "diagnostics.disable": [ + "undefined-field" + ] } - diff --git a/.stylua.toml b/.stylua.toml new file mode 100644 index 0000000..0435f67 --- /dev/null +++ b/.stylua.toml @@ -0,0 +1,2 @@ +indent_type = "Spaces" +indent_width = 2 diff --git a/lua/watchexec/health.lua b/lua/watchexec/health.lua new file mode 100644 index 0000000..3f41e54 --- /dev/null +++ b/lua/watchexec/health.lua @@ -0,0 +1,24 @@ +local M = {} + +function M.check() + if vim.fn.has("nvim-0.10") == 0 then + vim.health.error("Neovim 0.10 or higher is required", { "Please upgrade your Neovim installation to v0.10+" }) + return + end + + vim.health.start("watchexec.nvim diagnostics") + vim.health.ok("Neovim 0.10+ is installed") + + local bin_path = "watchexec" + + if vim.fn.executable(bin_path) == 1 then + vim.health.ok(string.format("Binary '%s' is installed and executable", bin_path)) + else + vim.health.error(string.format("Binary '%s' was not found in PATH", bin_path), { + "Install watchexec", + "Or verify your plugin configuration if using a custom binary path.", + }) + end +end + +return M diff --git a/lua/watchexec/init.lua b/lua/watchexec/init.lua index b09c92d..da825df 100644 --- a/lua/watchexec/init.lua +++ b/lua/watchexec/init.lua @@ -1,7 +1,7 @@ local M = {} M.config = { - greeting = "Hello from my plugin" + greeting = "Hello from my plugin", } function M.setup(opts) diff --git a/run_checks.ps1 b/run_checks.ps1 new file mode 100644 index 0000000..33614e5 --- /dev/null +++ b/run_checks.ps1 @@ -0,0 +1,35 @@ +$ErrorActionPreference = "Stop" + +Write-Host "=== Format check ===" +stylua --check . + +if ($LASTEXITCODE -ne 0) { + Write-Host "FAIL: Format check failed. Run 'stylua .' to fix." -ForegroundColor Red + exit 1 +} + +Write-Host "PASS" -ForegroundColor Green + +Write-Host "`n=== Lint ===" + +lua-language-server --check=. + +if ($LASTEXITCODE -ne 0) { + Write-Host "FAIL: Lint found issues." -ForegroundColor Red + exit 1 +} + +Write-Host "PASS" -ForegroundColor Green + +Write-Host "`n=== Test ===" + +nvim --headless -c "PlenaryBustedDirectory tests/watchexec/ {minimal_init = 'tests/minimal_init.lua'}" + +if ($LASTEXITCODE -ne 0) { + Write-Host "FAIL: Tests failed." -ForegroundColor Red + exit 1 +} + +Write-Host "PASS" -ForegroundColor Green + +Write-Host "`nAll checks passed!" -ForegroundColor Green diff --git a/tests/watchexec/health_spec.lua b/tests/watchexec/health_spec.lua new file mode 100644 index 0000000..89c8b52 --- /dev/null +++ b/tests/watchexec/health_spec.lua @@ -0,0 +1,73 @@ +local health = require("watchexec.health") +local stub = require("luassert.stub") + +describe("watchexec healthcheck", function() + local start_stub, ok_stub, error_stub + local has_stub, exec_stub + + before_each(function() + start_stub = stub(vim.health, "start") + ok_stub = stub(vim.health, "ok") + error_stub = stub(vim.health, "error") + end) + + after_each(function() + start_stub:revert() + ok_stub:revert() + error_stub:revert() + + if has_stub then + has_stub:revert() + end + + if exec_stub then + exec_stub:revert() + end + end) + + it("reports all checks as OK when environment is valid", function() + has_stub = stub(vim.fn, "has", function() + return 1 + end) + exec_stub = stub(vim.fn, "executable", function() + return 1 + end) + + health.check() + + assert.stub(start_stub).was_called_with("watchexec.nvim diagnostics") + assert.stub(ok_stub).was_called(2) + assert.stub(error_stub).was_called(0) + end) + + it("reports an error when watchexec is missing from PATH", function() + has_stub = stub(vim.fn, "has", function() + return 1 + end) + exec_stub = stub(vim.fn, "executable", function() + return 0 + end) + + health.check() + + assert.stub(ok_stub).was_called(1) + assert.stub(error_stub).was_called(1) + + assert.stub(error_stub).was_called_with( + "Binary 'watchexec' was not found in PATH", + { "Install watchexec", "Or verify your plugin configuration if using a custom binary path." } + ) + end) + + it("reports an error when using an outdated Neovim version", function() + has_stub = stub(vim.fn, "has", function() + return 0 + end) + + health.check() + + assert.stub(start_stub).was_called(0) + assert.stub(ok_stub).was_called(0) + assert.stub(error_stub).was_called(1) + end) +end) diff --git a/tests/watchexec/watchexec_spec.lua b/tests/watchexec/watchexec_spec.lua index 1c0ae9a..3eed771 100644 --- a/tests/watchexec/watchexec_spec.lua +++ b/tests/watchexec/watchexec_spec.lua @@ -1,17 +1,17 @@ local plugin = require("watchexec") describe("watchexec logic", function() - before_each(function() - plugin.setup({ - greeting = "Hello Test!" - }) - end) + before_each(function() + plugin.setup({ + greeting = "Hello Test!", + }) + end) - it("can be required without errors", function() - assert.not_nil(plugin) - end) + it("can be required without errors", function() + assert.not_nil(plugin) + end) - it("correctly applies user configuration", function() - assert.equals("Hello Test!", plugin.config.greeting) - end) + it("correctly applies user configuration", function() + assert.equals("Hello Test!", plugin.config.greeting) + end) end)