From 022ae346367a11ad28bc3348fba1a73c390f2553 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Wed, 10 Jun 2026 07:31:34 +0000 Subject: [PATCH 1/3] refactor(runner): simplify queue filtering --- lua/glaze/runner.lua | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lua/glaze/runner.lua b/lua/glaze/runner.lua index 1d2ae10..d438aac 100644 --- a/lua/glaze/runner.lua +++ b/lua/glaze/runner.lua @@ -166,18 +166,12 @@ local function run(names, mode, opts) for _, name in ipairs(names) do local binary = glaze._binaries[name] - if binary then - if existing_names[name] then - -- Already queued or running, skip - elseif mode == "install" and glaze.is_installed(name) then - -- Skip already installed - else - table.insert(binaries, binary) - end - else + if not binary then if not opts.silent then vim.notify("Unknown binary: " .. name, vim.log.levels.WARN) end + elseif not existing_names[name] and not (mode == "install" and glaze.is_installed(name)) then + table.insert(binaries, binary) end end From 7985c0dcbcb52b78054719c35a3a0a7a04a1d7e2 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Sun, 12 Jul 2026 06:33:22 +0000 Subject: [PATCH 2/3] fix(runner): handle failed job starts --- lua/glaze/runner.lua | 9 +++++++++ tests/run.lua | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lua/glaze/runner.lua b/lua/glaze/runner.lua index d438aac..219cf3c 100644 --- a/lua/glaze/runner.lua +++ b/lua/glaze/runner.lua @@ -111,6 +111,15 @@ local function run_task(task) M._process_queue() end, }) + + if task.job_id <= 0 then + task.end_time = vim.uv.hrtime() + task.status = "error" + table.insert(task.output, "Failed to start command: " .. table.concat(cmd, " ")) + task.job_id = nil + M._notify() + vim.schedule(M._process_queue) + end end ---@private diff --git a/tests/run.lua b/tests/run.lua index 36ad265..7b14534 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -107,6 +107,31 @@ test("register merges duplicate plugin registrations without duplicates", functi assert_eq(binary.plugins[2], "freeze.nvim") end) +test("runner marks failed job starts as errors", function() + local glaze = reset_glaze() + local runner = require("glaze.runner") + local original_jobstart = vim.fn.jobstart + + glaze.setup({ auto_check = { enabled = false }, auto_install = { enabled = false } }) + glaze.register("fake-glaze-binary", "example.com/fake/glaze") + glaze.is_installed = function() + return false + end + vim.fn.jobstart = function() + return -1 + end + + runner.install({ "fake-glaze-binary" }, { silent = true }) + vim.wait(100) + vim.fn.jobstart = original_jobstart + + local tasks = runner.tasks() + assert_eq(#tasks, 1, "failed job start should create one task") + assert_eq(tasks[1].status, "error", "failed job start should mark task as error") + assert_truthy(tasks[1].output[1]:match("Failed to start command"), "failed job start should keep output") + assert_eq(runner.is_running(), false, "failed job start should drain the runner") +end) + for _, case in ipairs(results) do local ok, err = pcall(case.fn) if not ok then From 04d8b562eaf441b27563f4498e6fb069584ca4f4 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Sun, 26 Jul 2026 18:05:33 -0400 Subject: [PATCH 3/3] fix(runner): notify callbacks with false on failed job start Failed jobstart previously marked the task as error but never fired registered completion callbacks, leaving dependent plugins waiting indefinitely. Mirror the on_exit callback dispatch and cover it in tests. --- lua/glaze/runner.lua | 10 ++++++++++ tests/run.lua | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lua/glaze/runner.lua b/lua/glaze/runner.lua index 219cf3c..11f672d 100644 --- a/lua/glaze/runner.lua +++ b/lua/glaze/runner.lua @@ -117,6 +117,16 @@ local function run_task(task) task.status = "error" table.insert(task.output, "Failed to start command: " .. table.concat(cmd, " ")) task.job_id = nil + + -- Call all registered callbacks with failure + if task.binary.callbacks then + vim.schedule(function() + for _, cb in pairs(task.binary.callbacks) do + cb(false) + end + end) + end + M._notify() vim.schedule(M._process_queue) end diff --git a/tests/run.lua b/tests/run.lua index 7b14534..ed1db52 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -112,8 +112,14 @@ test("runner marks failed job starts as errors", function() local runner = require("glaze.runner") local original_jobstart = vim.fn.jobstart + local callback_result = "unset" glaze.setup({ auto_check = { enabled = false }, auto_install = { enabled = false } }) - glaze.register("fake-glaze-binary", "example.com/fake/glaze") + glaze.register("fake-glaze-binary", "example.com/fake/glaze", { + plugin = "fake.nvim", + callback = function(success) + callback_result = success + end, + }) glaze.is_installed = function() return false end @@ -130,6 +136,7 @@ test("runner marks failed job starts as errors", function() assert_eq(tasks[1].status, "error", "failed job start should mark task as error") assert_truthy(tasks[1].output[1]:match("Failed to start command"), "failed job start should keep output") assert_eq(runner.is_running(), false, "failed job start should drain the runner") + assert_eq(callback_result, false, "failed job start should notify callbacks with false") end) for _, case in ipairs(results) do