mirror of https://github.com/folke/lazy.nvim.git
feat: added lockfile support
This commit is contained in:
parent
bbad0cb891
commit
4384d0e6d9
54
README.md
54
README.md
|
@ -2,51 +2,37 @@
|
||||||
|
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
|
|
||||||
- Partial clones instead of shallow clones
|
- [x] Partial clones instead of shallow clones
|
||||||
- Async
|
- [x] waits till missing deps are installed (bootstrap Neovim and start using it right away)
|
||||||
- No need for compile
|
- [x] Async
|
||||||
- Fast
|
- [x] No need for compile
|
||||||
- Correct sequencing of dependencies (deps should always be opt. Maybe make everything opt?)
|
- [x] Fast
|
||||||
|
- [x] Correct sequencing of dependencies (deps should always be opt. Maybe make everything opt?)
|
||||||
- [ ] Import specs from Packer
|
- [ ] Import specs from Packer
|
||||||
- Config in multiple files
|
- [x] Config in multiple files
|
||||||
- Patterns for local packages
|
- [x] Patterns for local packages
|
||||||
|
- [x] Profiling
|
||||||
- [ ] lockfile
|
- [ ] lockfile
|
||||||
|
- [ ] check for updates
|
||||||
- [ ] package.lua
|
- [ ] package.lua
|
||||||
- [ ] package-lock.lua
|
- [ ] package-lock.lua
|
||||||
- [ ] tag/version support `git tag --sort version:refname`
|
- [x] tag/version support `git tag --sort version:refname`
|
||||||
- [ ] auto-loading on completion for lazy-loaded commands
|
- [x] auto-loading on completion for lazy-loaded commands
|
||||||
- [ ] semver https://devhints.io/semver
|
- [x] semver https://devhints.io/semver
|
||||||
https://semver.npmjs.com/
|
https://semver.npmjs.com/
|
||||||
|
|
||||||
## ✅ TODO
|
## ✅ TODO
|
||||||
|
|
||||||
- [ ] show time taken for op in view
|
- [ ] view keybindings for update/clean/...
|
||||||
|
- [ ] add profiler to view
|
||||||
|
- [ ] add buttons for actions
|
||||||
|
- [x] show time taken for op in view
|
||||||
- [ ] package meta index (package.lua cache for all packages)
|
- [ ] package meta index (package.lua cache for all packages)
|
||||||
- [ ] migrate from Packer
|
- [ ] migrate from Packer
|
||||||
- [ ] auto lazy-loading of lua modules
|
- [ ] auto lazy-loading of lua modules
|
||||||
- [ ] use uv file watcher to check for config changes
|
- [ ] use uv file watcher to check for config changes
|
||||||
- [x] clear errors
|
- [x] clear errors
|
||||||
- [ ] add support for versions `git tag --sort v:refname`
|
- [x] add support for versions `git tag --sort v:refname`
|
||||||
- [ ] rename requires to deps
|
- [ ] rename requires to deps
|
||||||
- [ ] move tasks etc to Plugin.state
|
- [x] move tasks etc to Plugin.state
|
||||||
- loaded
|
- [ ] allow setting up plugins through config
|
||||||
- installed
|
|
||||||
- updated
|
|
||||||
- changed: just installed or updated (dirty)
|
|
||||||
- is_local
|
|
||||||
https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
|
|
||||||
|
|
||||||
## 🖥️ Git Operations
|
|
||||||
|
|
||||||
1. **install**:
|
|
||||||
|
|
||||||
- run `git clone` with given `branch`,`--single-branch`, `filter=blob:none`
|
|
||||||
and `--no-checkout`
|
|
||||||
- run `git checkout` with correct `branch`, `tag` or `commit`
|
|
||||||
|
|
||||||
2. **update**:
|
|
||||||
|
|
||||||
- if branch is missing `git remote set-branches --add origin MISSING_BRANCH`
|
|
||||||
- `git switch MISSING_BRANCH`
|
|
||||||
- run `git fetch`
|
|
||||||
- run `git checkout` with correct `branch`, `tag` or `commit`
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ M.defaults = {
|
||||||
},
|
},
|
||||||
interactive = true,
|
interactive = true,
|
||||||
packpath = vim.fn.stdpath("data") .. "/site/pack/lazy",
|
packpath = vim.fn.stdpath("data") .. "/site/pack/lazy",
|
||||||
|
lockfile = vim.fn.stdpath("config") .. "/lazy-lock.json",
|
||||||
view = {
|
view = {
|
||||||
icons = {
|
icons = {
|
||||||
start = "",
|
start = "",
|
||||||
|
@ -23,6 +24,7 @@ M.defaults = {
|
||||||
keys = " ",
|
keys = " ",
|
||||||
cmd = " ",
|
cmd = " ",
|
||||||
ft = "",
|
ft = "",
|
||||||
|
task = "✔ ",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@ M.dirty = false
|
||||||
|
|
||||||
---@class LazyPluginState
|
---@class LazyPluginState
|
||||||
---@field loaded? {[string]:string, time:number}
|
---@field loaded? {[string]:string, time:number}
|
||||||
---@field installed? boolean
|
---@field installed boolean
|
||||||
---@field tasks? LazyTask[]
|
---@field tasks? LazyTask[]
|
||||||
---@field dirty? boolean
|
---@field dirty? boolean
|
||||||
---@field updated? {from:string, to:string}
|
---@field updated? {from:string, to:string}
|
||||||
---@field is_local? boolean
|
---@field is_local boolean
|
||||||
---@field is_symlink? boolean
|
---@field is_symlink? boolean
|
||||||
---@field cloned? boolean
|
---@field cloned? boolean
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ function M.run(ropts, opts)
|
||||||
if opts.wait then
|
if opts.wait then
|
||||||
runner:wait()
|
runner:wait()
|
||||||
end
|
end
|
||||||
|
return runner
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param opts? ManagerOpts
|
---@param opts? ManagerOpts
|
||||||
|
@ -58,23 +59,26 @@ function M.install(opts)
|
||||||
}, opts)
|
}, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param opts? ManagerOpts
|
---@param opts? ManagerOpts|{lockfile?:boolean}
|
||||||
function M.update(opts)
|
function M.update(opts)
|
||||||
|
opts = opts or {}
|
||||||
M.run({
|
M.run({
|
||||||
pipeline = {
|
pipeline = {
|
||||||
"fs.symlink",
|
"fs.symlink",
|
||||||
"git.branch",
|
"git.branch",
|
||||||
"git.fetch",
|
"git.fetch",
|
||||||
"git.checkout",
|
{ "git.checkout", lockfile = opts.lockfile },
|
||||||
"plugin.docs",
|
"plugin.docs",
|
||||||
"plugin.run",
|
|
||||||
"wait",
|
"wait",
|
||||||
|
"plugin.run",
|
||||||
{ "git.log", updated = true },
|
{ "git.log", updated = true },
|
||||||
},
|
},
|
||||||
plugins = function(plugin)
|
plugins = function(plugin)
|
||||||
return plugin.uri and plugin._.installed
|
return plugin.uri and plugin._.installed
|
||||||
end,
|
end,
|
||||||
}, opts)
|
}, opts):wait(function()
|
||||||
|
require("lazy.manage.lock").update()
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param opts? ManagerOpts
|
---@param opts? ManagerOpts
|
||||||
|
@ -97,9 +101,11 @@ function M.clean(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.clear()
|
function M.clear()
|
||||||
|
Plugin.update_state(true)
|
||||||
for _, plugin in pairs(Config.plugins) do
|
for _, plugin in pairs(Config.plugins) do
|
||||||
-- clear updated status
|
|
||||||
plugin._.updated = nil
|
plugin._.updated = nil
|
||||||
|
plugin._.cloned = nil
|
||||||
|
plugin._.dirty = nil
|
||||||
-- clear finished tasks
|
-- clear finished tasks
|
||||||
if plugin._.tasks then
|
if plugin._.tasks then
|
||||||
---@param task LazyTask
|
---@param task LazyTask
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
local Config = require("lazy.core.config")
|
||||||
|
local Git = require("lazy.manage.git")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
---@type table<string, {commit:string, branch:string}>
|
||||||
|
M.lock = {}
|
||||||
|
M._loaded = false
|
||||||
|
|
||||||
|
function M.update()
|
||||||
|
local f = assert(io.open(Config.options.lockfile, "w"))
|
||||||
|
f:write("{\n")
|
||||||
|
M.lock = {}
|
||||||
|
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
local plugins = vim.tbl_filter(function(plugin)
|
||||||
|
return not plugin._.is_local and plugin._.installed
|
||||||
|
end, Config.plugins)
|
||||||
|
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
---@type string[]
|
||||||
|
local names = vim.tbl_map(function(plugin)
|
||||||
|
return plugin.name
|
||||||
|
end, plugins)
|
||||||
|
table.sort(names)
|
||||||
|
|
||||||
|
for n, name in ipairs(names) do
|
||||||
|
local plugin = Config.plugins[name]
|
||||||
|
if not plugin._.is_local and plugin._.installed then
|
||||||
|
local info = assert(Git.info(plugin.dir))
|
||||||
|
if not info.branch then
|
||||||
|
local branch = assert(Git.get_branch(plugin))
|
||||||
|
info.branch = branch.branch
|
||||||
|
end
|
||||||
|
info.commit = info.commit
|
||||||
|
-- f:write(([[ [%q] = { branch = %q, commit = %q },]]):format(name, info.branch, info.commit) .. "\n")
|
||||||
|
f:write(([[ %q: { "branch": %q, "commit": %q }]]):format(name, info.branch, info.commit))
|
||||||
|
if n ~= #names then
|
||||||
|
f:write(",\n")
|
||||||
|
end
|
||||||
|
---@diagnostic disable-next-line: assign-type-mismatch
|
||||||
|
M.lock[plugin.name] = info
|
||||||
|
end
|
||||||
|
end
|
||||||
|
f:write("\n}")
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.load()
|
||||||
|
M.lock = {}
|
||||||
|
M._loaded = true
|
||||||
|
local f = io.open(Config.options.lockfile, "r")
|
||||||
|
if f then
|
||||||
|
---@type string
|
||||||
|
local data = f:read("*a")
|
||||||
|
local ok, lock = pcall(vim.json.decode, data)
|
||||||
|
if ok then
|
||||||
|
M.lock = lock
|
||||||
|
end
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
---@return {commit:string, branch:string}
|
||||||
|
function M.get(plugin)
|
||||||
|
if not M._loaded then
|
||||||
|
M.load()
|
||||||
|
end
|
||||||
|
return M.lock[plugin.name]
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
|
@ -1,5 +1,6 @@
|
||||||
local Util = require("lazy.util")
|
local Util = require("lazy.util")
|
||||||
local Git = require("lazy.manage.git")
|
local Git = require("lazy.manage.git")
|
||||||
|
local Lock = require("lazy.manage.lock")
|
||||||
|
|
||||||
---@type table<string, LazyTaskDef>
|
---@type table<string, LazyTaskDef>
|
||||||
local M = {}
|
local M = {}
|
||||||
|
@ -118,11 +119,21 @@ M.checkout = {
|
||||||
skip = function(plugin)
|
skip = function(plugin)
|
||||||
return not plugin._.installed or plugin._.is_local
|
return not plugin._.installed or plugin._.is_local
|
||||||
end,
|
end,
|
||||||
run = function(self)
|
---@param opts {lockfile?:boolean}
|
||||||
|
run = function(self, opts)
|
||||||
local info = assert(Git.info(self.plugin.dir))
|
local info = assert(Git.info(self.plugin.dir))
|
||||||
local target = assert(Git.get_target(self.plugin))
|
local target = assert(Git.get_target(self.plugin))
|
||||||
|
|
||||||
if not self.plugin._.cloned and info.commit == target.commit then
|
local lock
|
||||||
|
if opts.lockfile then
|
||||||
|
lock = Lock.get(self.plugin)
|
||||||
|
if lock then
|
||||||
|
---@diagnostic disable-next-line: cast-local-type
|
||||||
|
target = lock
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self.plugin._.cloned and info.commit == target.commit and info.branch == target.branch then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -131,7 +142,9 @@ M.checkout = {
|
||||||
"--progress",
|
"--progress",
|
||||||
}
|
}
|
||||||
|
|
||||||
if target.tag then
|
if lock then
|
||||||
|
table.insert(args, lock.commit)
|
||||||
|
elseif target.tag then
|
||||||
table.insert(args, "tags/" .. target.tag)
|
table.insert(args, "tags/" .. target.tag)
|
||||||
elseif self.plugin.commit then
|
elseif self.plugin.commit then
|
||||||
table.insert(args, self.plugin.commit)
|
table.insert(args, self.plugin.commit)
|
||||||
|
|
|
@ -40,6 +40,9 @@ M.commands = {
|
||||||
update = function()
|
update = function()
|
||||||
Manage.update({ clear = true, interactive = true })
|
Manage.update({ clear = true, interactive = true })
|
||||||
end,
|
end,
|
||||||
|
reset = function()
|
||||||
|
Manage.update({ clear = true, interactive = true, lockfile = true })
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
function M.setup()
|
function M.setup()
|
||||||
|
|
Loading…
Reference in New Issue