Skip to content

Commit

Permalink
feat!: severely refactor internal logic, add support for updating plu…
Browse files Browse the repository at this point in the history
…gins
  • Loading branch information
vhyrro committed Aug 19, 2023
1 parent ae7aca1 commit 44d8070
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 81 deletions.
42 changes: 0 additions & 42 deletions lua/rocks/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
--
--- Code:

local global_config = require("rocks.config")
local constants = require("rocks.constants")
local fs = require("rocks.fs")
local state = require("rocks.state")

--- rocks.nvim configuration
---@type table
Expand All @@ -35,44 +31,6 @@ local config = {
config_path = vim.fs.joinpath(vim.fn.stdpath("config"), "rocks.toml"),
}

function config.read(location)
-- Read or create a new config file and decode it
local user_config = require("toml").decode(fs.read_or_create(global_config.config_path, constants.DEFAULT_CONFIG))

-- Merge `rocks` and `plugins` fields as they are just an eye-candy separator for clarity purposes
local rocks = vim.tbl_deep_extend("force", user_config.rocks, user_config.plugins)
local installed_rocks =

--- Operations process ---
--------------------------
-- ops structure:
-- {
-- install = {
-- foo = "version"
-- },
-- remove = {
-- "bar",
-- "fizzbuzz",
-- }
-- }
local ops = {
install = {},
remove = {},
}
for rock, metadata in pairs(rocks) do
if not vim.tbl_contains(installed_rock_names, rock) then
ops.install[rock] = metadata
end
end
for _, installed_rock in ipairs(installed_rock_names) do
-- FIXME: this seems to be removing rocks that are dependencies of some plugins as they are not listed
-- explicitly in the `rocks.toml` file. We have to fix this as soon as possible.
if not vim.tbl_contains(vim.tbl_keys(config_rocks), installed_rock) then
ops.remove[#ops.remove + 1] = installed_rock
end
end
end

return config

--- config.lua ends here
88 changes: 88 additions & 0 deletions lua/rocks/operations.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,94 @@
--
--- Code:

local constants = require("rocks.constants")
local fs = require("rocks.fs")
local config = require("rocks.config")
local state = require("rocks.state")

local operations = {}

function operations.install(name, version, callback)
-- TODO(vhyrro): Input checking on name and version
vim.system({ "luarocks", "--lua-version=" .. constants.LUA_VERSION, "--tree=" .. config.rocks_path, "install", name, version }, function(obj)
callback(obj.code, obj.stderr)
end)
end

function operations.sync(location)
-- Read or create a new config file and decode it
local user_config = require("toml").decode(fs.read_or_create(location or config.config_path, constants.DEFAULT_CONFIG))

-- Merge `rocks` and `plugins` fields as they are just an eye-candy separator for clarity purposes
local user_rocks = vim.tbl_deep_extend("force", user_config.rocks, user_config.plugins)

-- TODO: change this to look for plugins that are not installed yet, also
-- invoke the update command at the end
state.installed_rocks(function(rocks)
local counter = #vim.tbl_keys(rocks)

if counter == 0 then
vim.print("Nothing new to install!")
return
end

for name, data in pairs(rocks) do
operations.install(name, data.version, function(code, err)
counter = counter - 1

if code == 0 then
vim.print("Successfully updated '" .. name .. "'!")
else
vim.print("Failed to update '" .. name .. "'!")
vim.print("Error trace below:")
vim.print(err)
vim.print("Run :messages for full stacktrace.")
return
end

if counter == 0 then
vim.print("Everything is now in-sync!")
end
end)
end
end)

operations.update()
end

function operations.update()
vim.api.nvim_echo({{"Checking for updates..."}}, false, {})

state.outdated_rocks(function(rocks)
local counter = #vim.tbl_keys(rocks)

if counter == 0 then
vim.print("Nothing to update!")
return
end

for name, data in pairs(rocks) do
vim.print("New version for '" .. name .. "': " .. data.version .. " -> " .. data.target_version)

operations.install(name, data.target_version, function(code, err)
counter = counter - 1

if code == 0 then
vim.print("Successfully updated '" .. name .. "'!")
else
vim.print("Failed to update '" .. name .. "'!")
vim.print("Error trace below:")
vim.print(err)
vim.print("Run :messages for full stacktrace.")
return
end

if counter == 0 then
vim.print("Everything is now up-to-date!")
end
end)
end
end)
end

return operations
61 changes: 25 additions & 36 deletions lua/rocks/setup.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,35 @@

local setup = {}

local constants = require("rocks.constants")
local operations = require("rocks.operations")
-- local constants = require("rocks.constants")
-- local operations = require("rocks.operations")
local config = require("rocks.config")

--- Add luarocks Neovim tree paths to LUA_PATH and LUA_CPATH and download required rocks to work
---@private
local function bootstrap()
local cfg = _G.__rocks_config

-- First set up the paths then check if toml rock is installed or not
local luarocks_path = {
vim.fs.joinpath(cfg.rocks_path, "share", "lua", "5.1", "?.lua"),
vim.fs.joinpath(cfg.rocks_path, "share", "lua", "5.1", "?", "init.lua"),
}
package.path = package.path .. ";" .. table.concat(luarocks_path, ";")

local luarocks_cpath = {
vim.fs.joinpath(cfg.rocks_path, "lib", "lua", "5.1", "?.so"),
vim.fs.joinpath(cfg.rocks_path, "lib64", "lua", "5.1", "?.so"),
}
package.cpath = package.cpath .. ";" .. table.concat(luarocks_cpath, ";")

-- Is toml rock installed? No? Well let's install it now!
local is_toml_installed, _ = pcall(require, "toml")

if not is_toml_installed then
vim.notify("Installing 'toml' dependency by using luarocks. This requires compiling C++ code so it may take a while, please wait ...")

operations.install("toml", "0.3.0-0")
operations.install("nui.nvim", "0.1.0-0")
end
end

--- Initialize rocks.nvim
--- Add luarocks Neovim tree paths to LUA_PATH and LUA_CPATH and download required rocks to work
function setup.init()
-- Run bootstrap process, install dependencies if required
bootstrap()

-- Read configuration file and proceed with any task that has to be done with the plugins
local config =
-- First set up the paths then check if toml rock is installed or not
local luarocks_path = {
vim.fs.joinpath(config.rocks_path, "share", "lua", "5.1", "?.lua"),
vim.fs.joinpath(config.rocks_path, "share", "lua", "5.1", "?", "init.lua"),
}
package.path = package.path .. ";" .. table.concat(luarocks_path, ";")

local luarocks_cpath = {
vim.fs.joinpath(config.rocks_path, "lib", "lua", "5.1", "?.so"),
vim.fs.joinpath(config.rocks_path, "lib64", "lua", "5.1", "?.so"),
}
package.cpath = package.cpath .. ";" .. table.concat(luarocks_cpath, ";")

-- Is toml rock installed? No? Well let's install it now!
local is_toml_installed, _ = pcall(require, "toml")

if not is_toml_installed then
vim.notify("Installing 'toml' dependency by using luarocks. This requires compiling C++ code so it may take a while, please wait ...")

-- operations.install("toml", "0.3.0-0")
-- operations.install("nui.nvim", "0.1.0-0")
end
end

return setup
Expand Down
52 changes: 49 additions & 3 deletions lua/rocks/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,58 @@ local state = {}
local constants = require("rocks.constants")
local config = require("rocks.config")

---@alias Rock { name: string, version: string, target_version?: string }

---
---@param callback fun(installed: string[])
---@param callback fun(installed: {[string]: Rock})
function state.installed_rocks(callback)
vim.system({"luarocks", "--lua-version=" .. constants.LUA_VERSION, "--tree=" .. config.rocks_path, "list", "--porcelain"}, function(obj)
local _callback = function(obj)
---@type {[string]: Rock}
local rocks = {}

for name, version in obj.stdout:gmatch("([^%s]+)%s+(%d+%.%d+%.%d+%-%d+)%s+installed%s+[^%s]+") do
rocks[name] = { name = name, version = version }
end

if callback then
callback(rocks)
else
return rocks
end
end

if callback then
vim.system({"luarocks", "--lua-version=" .. constants.LUA_VERSION, "--tree=" .. config.rocks_path, "list", "--porcelain"}, _callback)
else
local rocklist = vim.system({"luarocks", "--lua-version=" .. constants.LUA_VERSION, "--tree=" .. config.rocks_path, "list", "--porcelain"}):wait()
return _callback(rocklist)
end
end

---@param callback fun(installed: {[string]: Rock})
function state.outdated_rocks(callback)
local _callback = function(obj)
---@type {[string]: Rock}
local rocks = {}

vim.print(obj.stdout)
for name, version, target_version in obj.stdout:gmatch("([^%s]+)%s+(%d+%.%d+%.%d+%-%d+)%s+(%d+%.%d+%.%d+%-%d+)%s+[^%s]+") do
rocks[name] = { name = name, version = version, target_version = target_version }
end

if callback then
callback(rocks)
else
return rocks
end
end

end)
if callback then
vim.system({"luarocks", "--lua-version=" .. constants.LUA_VERSION, "--tree=" .. config.rocks_path, "list", "--porcelain", "--outdated"}, _callback)
else
local rocklist = vim.system({"luarocks", "--lua-version=" .. constants.LUA_VERSION, "--tree=" .. config.rocks_path, "list", "--porcelain", "--outdated"}):wait()
return _callback(rocklist)
end
end

return state

0 comments on commit 44d8070

Please sign in to comment.