6e1b018adb
- treat `\` as a separator in safe_relative so `\abs` and `..\..\x` are refused - read zip symlink targets with `unzip -p` off the `unzip -Z -l` listing and reject escapes before unpacking
179 lines
7.8 KiB
Plaintext
179 lines
7.8 KiB
Plaintext
*vimpack.txt* Install Neovim plugins from archives on an artifact registry
|
|
|
|
==============================================================================
|
|
CONTENTS *vimpack-contents*
|
|
|
|
1. Introduction ............................. |vimpack-introduction|
|
|
2. Setup .................................... |vimpack-setup|
|
|
3. Plugin spec .............................. |vimpack-spec|
|
|
4. Registries ............................... |vimpack-registries|
|
|
5. Auth ..................................... |vimpack-auth|
|
|
6. Commands ................................. |vimpack-commands|
|
|
7. Layout ................................... |vimpack-layout|
|
|
8. Lua API .................................. |vimpack-api|
|
|
|
|
==============================================================================
|
|
1. INTRODUCTION *vimpack-introduction*
|
|
|
|
vimpack installs Neovim plugins from tarballs or zips served by an artifact
|
|
registry, at an explicit version, rather than by cloning git repositories.
|
|
Downloads are checksum-verified and swapped into place atomically, so a failed
|
|
install never leaves a half-written plugin behind.
|
|
|
|
Requirements: Neovim 0.10+, `curl`, and `tar` (plus `unzip` for .zip
|
|
archives).
|
|
|
|
==============================================================================
|
|
2. SETUP *vimpack-setup*
|
|
|
|
>lua
|
|
require('vimpack').setup({
|
|
registry = {
|
|
kind = 'artifactapi',
|
|
base_url = 'https://artifactapi.k8s.syd1.au.unkin.net',
|
|
repo = 'nvim-plugins',
|
|
auth = { env = 'ARTIFACTAPI_TOKEN' },
|
|
},
|
|
plugins = {
|
|
{ name = 'telescope.nvim', version = '0.1.8' },
|
|
{ name = 'vim-fugitive', version = '3.7', opt = true },
|
|
},
|
|
concurrency = 4,
|
|
timeout = 120000,
|
|
})
|
|
<
|
|
`setup()` validates the spec and returns the normalised config, or nil plus an
|
|
error message. Nothing is downloaded until |:VimpackInstall|.
|
|
|
|
Top-level options ~
|
|
|
|
registry default registry for every plugin (table, optional)
|
|
plugins list of plugin specs (list, default {})
|
|
concurrency maximum simultaneous downloads (number, default 4)
|
|
timeout per-download timeout in milliseconds (number, default 120000)
|
|
|
|
==============================================================================
|
|
3. PLUGIN SPEC *vimpack-spec*
|
|
|
|
name Plugin name. Required. Also the directory name under
|
|
pack/vimpack/{start,opt}/ unless dir_name overrides it.
|
|
version Required unless `url` is given. Passed to the resolver.
|
|
sha256 Expected digest of the archive. A mismatch aborts the install
|
|
and reports both the expected and the actual digest.
|
|
opt When true the plugin lands in opt/ for |:packadd|.
|
|
url Fully explicit archive URL; registry resolution is skipped.
|
|
ext Archive extension, default "tar.gz".
|
|
registry Per-plugin registry, overriding the top-level one.
|
|
dir_name On-disk directory name.
|
|
|
|
==============================================================================
|
|
4. REGISTRIES *vimpack-registries*
|
|
|
|
A registry maps (name, version) to a download URL. `kind` selects the
|
|
resolver; the default kind is "template".
|
|
|
|
template ~
|
|
|
|
Substitutes ${name}, ${version}, ${ext}, ${slug}, ${repo} and ${base_url} into
|
|
`url_template`. An unrecognised placeholder is reported as an error.
|
|
`filename_template` optionally names the cached archive.
|
|
>lua
|
|
registry = {
|
|
kind = 'template',
|
|
url_template = 'https://artifactory.example.com/artifactory/nvim-generic/'
|
|
.. '${name}/${version}/${name}-${version}.${ext}',
|
|
}
|
|
<
|
|
artifactapi ~
|
|
|
|
Builds ${base_url}/api/v2/remotes/${repo}/files/${path}. `path_template`
|
|
defaults to "${name}/${name}-${version}.${ext}".
|
|
>lua
|
|
registry = {
|
|
kind = 'artifactapi',
|
|
base_url = 'https://artifactapi.k8s.syd1.au.unkin.net',
|
|
repo = 'nvim-plugins',
|
|
}
|
|
<
|
|
custom ~
|
|
|
|
A resolver is `(spec, registry) -> resolved | nil, err`, where `resolved` is
|
|
`{ url, headers, filename, sha256? }`.
|
|
>lua
|
|
require('vimpack').register_resolver('mine', function(spec, registry)
|
|
return { url = registry.base_url .. '/' .. spec.name .. '-'
|
|
.. spec.version .. '.tar.gz', headers = {} }
|
|
end)
|
|
<
|
|
==============================================================================
|
|
5. AUTH *vimpack-auth*
|
|
|
|
Tokens are never stored in the config. `registry.auth` accepts:
|
|
|
|
env name of an environment variable holding the token
|
|
token_cmd command (list or shell string) that prints the token
|
|
header header name, default "Authorization"
|
|
prefix value prefix, default "Bearer " for Authorization
|
|
|
|
A literal `token` key is rejected at |vimpack-setup| time.
|
|
>lua
|
|
auth = { header = 'X-JFrog-Art-Api', prefix = '',
|
|
token_cmd = { 'pass', 'show', 'artifactory/api-key' } }
|
|
<
|
|
==============================================================================
|
|
6. COMMANDS *vimpack-commands*
|
|
|
|
*:VimpackInstall*
|
|
:VimpackInstall [{name}...]
|
|
Install plugins that are missing or whose installed version, digest or
|
|
start/opt placement has drifted from the spec. Up-to-date plugins are
|
|
skipped. With names, restrict the work to those plugins.
|
|
|
|
*:VimpackUpdate*
|
|
:VimpackUpdate [{name}...]
|
|
Re-fetch plugins whether or not the manifest says they are current.
|
|
|
|
*:VimpackClean*
|
|
:VimpackClean
|
|
Remove installed plugins and manifest entries that are no longer in the
|
|
spec.
|
|
|
|
*:VimpackStatus*
|
|
:VimpackStatus
|
|
Print wanted versus installed version per plugin, with a state of "ok",
|
|
"missing", "drift" or "orphan".
|
|
|
|
==============================================================================
|
|
7. LAYOUT *vimpack-layout*
|
|
|
|
stdpath('cache')/vimpack/archives/ downloaded archives
|
|
stdpath('data')/site/pack/vimpack/.vimpack-stage/ extraction staging area
|
|
stdpath('data')/vimpack/manifest.json installed name/version/sha256
|
|
stdpath('data')/site/pack/vimpack/start/<name>
|
|
stdpath('data')/site/pack/vimpack/opt/<name>
|
|
|
|
An install extracts to the staging area, hoists a single wrapper directory if
|
|
the archive has one, then renames into place after parking any previous tree
|
|
aside. If the rename fails the previous tree is restored. Staging sits under
|
|
the pack root so that rename stays on one filesystem.
|
|
|
|
Every member is listed and validated before extraction: absolute paths, `..`
|
|
and `..\` escapes, devices, fifos and links pointing out of the destination
|
|
are all refused. Zip symlink targets are read with `unzip -p` (stdout only,
|
|
nothing written) because the zip listing does not carry them.
|
|
|
|
Lazy loading is out of scope: `opt = true` only chooses the opt/ bucket.
|
|
|
|
==============================================================================
|
|
8. LUA API *vimpack-api*
|
|
|
|
require('vimpack').setup(opts) configure; returns cfg or nil,err
|
|
require('vimpack').install(names?) same as |:VimpackInstall|
|
|
require('vimpack').update(names?) same as |:VimpackUpdate|
|
|
require('vimpack').clean() same as |:VimpackClean|
|
|
require('vimpack').status() same as |:VimpackStatus|
|
|
require('vimpack').status_rows() status as a list of tables
|
|
require('vimpack').register_resolver(n, fn) add a registry resolver
|
|
|
|
vim:tw=78:ts=8:ft=help:norl:
|