This started as a idea's discussion post. Creating a feature issue instead to make it an actual feature request.
Describe the feature
Like many other users I store my neovim's configuration in source control. I can use my configuration on many different
systems. The problem is that my configuration can only be validated to work with my local plugins at their current git
revisions. The state of the local plugins should also be commitable. As neovim's ecosystem is constantly changing this
would prevent an update from breaking my config and causing me to maintain it. Now I can choose when I have time to
maintain my config.
Why not snapshots?
- Setting
snapshot config option calls snapshot rollup every time neovim start
- This preforms a git fetch every for every plugin in the snapshot file ever time neovim is started
- Not integrated into packer commands like
install and update
- Snapshot file not formatted for diffing changes and not sorted (not idempotent).
- Having an
PackerSnapshotDone autocmd would at least let us call jq to sort and pretty print.
This would make snapshot's diff understandable and idempotent.
Snapshots feel more like a git stash. A way of taking a temporary snapshot of my current state while experimenting.
Something that I will eventually throw away. It is it's own system tacked onto packer and not integrated into it.
Proposal
Packer should provide a lockfile option. When enabled, packer would apply this lockfile to git plugin type's
installer and updater functions. This would integrate the lockfile (if enabled) into the commands install,
update and sync.
The lockfile is a lua file that returns a table mapping plugins to their commit hashes. The lockfile entries are also
sorted so that multiple calls are idempotent.
Configuration
local config_defaults = {
-- ...
lockfile = {
-- Apply lockfile on packer commands (Defaults to false for an opt-in feature)
enable = false,
-- Default lockfile filepath. Defaults to config location as it should be commited into dotfiles
path = join_paths(stdpath("config"), "lockfile.lua"),
-- Update lockfile after an upgrade call
update_on_upgrade = true,
},
}
Commands
A new command would be added called upgrade. This would temporally disable the lockfile and then execute an update.
Once the update is finished the lockfile will also be updated if update_on_upgrade is enabled.
The other new command that would be added is lockfile. This command will update the lockfile with the current state of
your local plugins. The internal lockfile table would also be re-loaded. This is useful is someone sets
update_on_upgrade to false and only wants to update the lockfile once they have tested the upgrade is stable. If it is
not then they can just call update and the lockfile will be reapplied.
Applying lockfile
The lockfile is applied if:
- The plugin name is found in lockfile table
- The plugin is a
git type (not local)
- There is no
tag key
The lockfile is also checked and applied to any plugin spec defined in requires key.
Updating lockfile
Since local plugin types are ignored by the lockfile, if an entry exists in the current lockfile that value is reused.
Example lockfile
-- Automatically generated by packer.nvim
return {
["LuaSnip"] = { commit = "c599c56", date = "1659863559" },
["alpha-nvim"] = { commit = "d688f46", date = "1658591867" },
["cmp-buffer"] = { commit = "62fc67a", date = "1655319089" },
["cmp-emoji"] = { commit = "19075c3", date = "1632834658" },
["cmp-nvim-lsp"] = { commit = "affe808", date = "1652705110" },
["cmp-nvim-lua"] = { commit = "d276254", date = "1633919304" },
}
Commit dates
With the lockfile applied to both the install and update commands we can take advantage of actually knowing the
commit we want. Along with the commit hash we can also save the commit's date. This would then allow the use of
--shallow-since instead of --depth 999999. This makes clones and updates of repositories leaner both on
network and diskspace. Getting the commit's date in unix time is simple:
git show -s --format="%ct" HEAD
Additional thoughts
- Should the
upgrade command perform the same operations as update or sync?
- Should this be controlled with a config option? (should it call
compile?)
This started as a idea's discussion post. Creating a feature issue instead to make it an actual feature request.
Describe the feature
Like many other users I store my neovim's configuration in source control. I can use my configuration on many different
systems. The problem is that my configuration can only be validated to work with my local plugins at their current git
revisions. The state of the local plugins should also be commitable. As neovim's ecosystem is constantly changing this
would prevent an
updatefrom breaking my config and causing me to maintain it. Now I can choose when I have time tomaintain my config.
Why not snapshots?
snapshotconfig option calls snapshot rollup every time neovim startinstallandupdatePackerSnapshotDoneautocmd would at least let us calljqto sort and pretty print.This would make snapshot's diff understandable and idempotent.
Snapshots feel more like a git
stash. A way of taking a temporarysnapshotof my current state while experimenting.Something that I will eventually throw away. It is it's own system tacked onto packer and not integrated into it.
Proposal
Packer should provide a
lockfileoption. When enabled, packer would apply this lockfile togitplugin type'sinstallerandupdaterfunctions. This would integrate the lockfile (if enabled) into the commandsinstall,updateandsync.The lockfile is a lua file that returns a table mapping plugins to their commit hashes. The lockfile entries are also
sorted so that multiple calls are idempotent.
Configuration
Commands
A new command would be added called
upgrade. This would temporally disable the lockfile and then execute anupdate.Once the update is finished the lockfile will also be updated if
update_on_upgradeis enabled.The other new command that would be added is
lockfile. This command will update the lockfile with the current state ofyour local plugins. The internal lockfile table would also be re-loaded. This is useful is someone sets
update_on_upgradeto false and only wants to update the lockfile once they have tested the upgrade is stable. If it isnot then they can just call
updateand the lockfile will be reapplied.Applying lockfile
The lockfile is applied if:
gittype (notlocal)tagkeyThe lockfile is also checked and applied to any plugin spec defined in
requireskey.Updating lockfile
Since
localplugin types are ignored by the lockfile, if an entry exists in the current lockfile that value is reused.Example lockfile
Commit dates
With the lockfile applied to both the
installandupdatecommands we can take advantage of actually knowing thecommit we want. Along with the
commithash we can also save the commit'sdate. This would then allow the use of--shallow-since instead of
--depth 999999. This makes clones and updates of repositories leaner both onnetwork and diskspace. Getting the commit's date in unix time is simple:
git show -s --format="%ct" HEADAdditional thoughts
upgradecommand perform the same operations asupdateorsync?compile?)