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
|
||||
|
||||
- Partial clones instead of shallow clones
|
||||
- Async
|
||||
- No need for compile
|
||||
- Fast
|
||||
- Correct sequencing of dependencies (deps should always be opt. Maybe make everything opt?)
|
||||
- [x] Partial clones instead of shallow clones
|
||||
- [x] waits till missing deps are installed (bootstrap Neovim and start using it right away)
|
||||
- [x] Async
|
||||
- [x] No need for compile
|
||||
- [x] Fast
|
||||
- [x] Correct sequencing of dependencies (deps should always be opt. Maybe make everything opt?)
|
||||
- [ ] Import specs from Packer
|
||||
- Config in multiple files
|
||||
- Patterns for local packages
|
||||
- [x] Config in multiple files
|
||||
- [x] Patterns for local packages
|
||||
- [x] Profiling
|
||||
- [ ] lockfile
|
||||
- [ ] check for updates
|
||||
- [ ] package.lua
|
||||
- [ ] package-lock.lua
|
||||
- [ ] tag/version support `git tag --sort version:refname`
|
||||
- [ ] auto-loading on completion for lazy-loaded commands
|
||||
- [ ] semver https://devhints.io/semver
|
||||
- [x] tag/version support `git tag --sort version:refname`
|
||||
- [x] auto-loading on completion for lazy-loaded commands
|
||||
- [x] semver https://devhints.io/semver
|
||||
https://semver.npmjs.com/
|
||||
|
||||
## ✅ 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)
|
||||
- [ ] migrate from Packer
|
||||
- [ ] auto lazy-loading of lua modules
|
||||
- [ ] use uv file watcher to check for config changes
|
||||
- [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
|
||||
- [ ] move tasks etc to Plugin.state
|
||||
- loaded
|
||||
- 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`
|
||||
- [x] move tasks etc to Plugin.state
|
||||
- [ ] allow setting up plugins through config
|
||||
|
|
|
@ -13,6 +13,7 @@ M.defaults = {
|
|||
},
|
||||
interactive = true,
|
||||
packpath = vim.fn.stdpath("data") .. "/site/pack/lazy",
|
||||
lockfile = vim.fn.stdpath("config") .. "/lazy-lock.json",
|
||||
view = {
|
||||
icons = {
|
||||
start = "",
|
||||
|
@ -23,6 +24,7 @@ M.defaults = {
|
|||
keys = " ",
|
||||
cmd = " ",
|
||||
ft = "",
|
||||
task = "✔ ",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@ M.dirty = false
|
|||
|
||||
---@class LazyPluginState
|
||||
---@field loaded? {[string]:string, time:number}
|
||||
---@field installed? boolean
|
||||
---@field installed boolean
|
||||
---@field tasks? LazyTask[]
|
||||
---@field dirty? boolean
|
||||
---@field updated? {from:string, to:string}
|
||||
---@field is_local? boolean
|
||||
---@field is_local boolean
|
||||
---@field is_symlink? boolean
|
||||
---@field cloned? boolean
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ function M.run(ropts, opts)
|
|||
if opts.wait then
|
||||
runner:wait()
|
||||
end
|
||||
return runner
|
||||
end
|
||||
|
||||
---@param opts? ManagerOpts
|
||||
|
@ -58,23 +59,26 @@ function M.install(opts)
|
|||
}, opts)
|
||||
end
|
||||
|
||||
---@param opts? ManagerOpts
|
||||
---@param opts? ManagerOpts|{lockfile?:boolean}
|
||||
function M.update(opts)
|
||||
opts = opts or {}
|
||||
M.run({
|
||||
pipeline = {
|
||||
"fs.symlink",
|
||||
"git.branch",
|
||||
"git.fetch",
|
||||
"git.checkout",
|
||||
{ "git.checkout", lockfile = opts.lockfile },
|
||||
"plugin.docs",
|
||||
"plugin.run",
|
||||
"wait",
|
||||
"plugin.run",
|
||||
{ "git.log", updated = true },
|
||||
},
|
||||
plugins = function(plugin)
|
||||
return plugin.uri and plugin._.installed
|
||||
end,
|
||||
}, opts)
|
||||
}, opts):wait(function()
|
||||
require("lazy.manage.lock").update()
|
||||
end)
|
||||
end
|
||||
|
||||
---@param opts? ManagerOpts
|
||||
|
@ -97,9 +101,11 @@ function M.clean(opts)
|
|||
end
|
||||
|
||||
function M.clear()
|
||||
Plugin.update_state(true)
|
||||
for _, plugin in pairs(Config.plugins) do
|
||||
-- clear updated status
|
||||
plugin._.updated = nil
|
||||
plugin._.cloned = nil
|
||||
plugin._.dirty = nil
|
||||
-- clear finished tasks
|
||||
if plugin._.tasks then
|
||||
---@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 Git = require("lazy.manage.git")
|
||||
local Lock = require("lazy.manage.lock")
|
||||
|
||||
---@type table<string, LazyTaskDef>
|
||||
local M = {}
|
||||
|
@ -118,11 +119,21 @@ M.checkout = {
|
|||
skip = function(plugin)
|
||||
return not plugin._.installed or plugin._.is_local
|
||||
end,
|
||||
run = function(self)
|
||||
---@param opts {lockfile?:boolean}
|
||||
run = function(self, opts)
|
||||
local info = assert(Git.info(self.plugin.dir))
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -131,7 +142,9 @@ M.checkout = {
|
|||
"--progress",
|
||||
}
|
||||
|
||||
if target.tag then
|
||||
if lock then
|
||||
table.insert(args, lock.commit)
|
||||
elseif target.tag then
|
||||
table.insert(args, "tags/" .. target.tag)
|
||||
elseif self.plugin.commit then
|
||||
table.insert(args, self.plugin.commit)
|
||||
|
|
|
@ -40,6 +40,9 @@ M.commands = {
|
|||
update = function()
|
||||
Manage.update({ clear = true, interactive = true })
|
||||
end,
|
||||
reset = function()
|
||||
Manage.update({ clear = true, interactive = true, lockfile = true })
|
||||
end,
|
||||
}
|
||||
|
||||
function M.setup()
|
||||
|
|
Loading…
Reference in New Issue