Skip to content

Commit 085a0ca

Browse files
committed
pkg.json "pivot"
part of #41
1 parent 36fddbe commit 085a0ca

File tree

4 files changed

+202
-150
lines changed

4 files changed

+202
-150
lines changed

Diff for: README.md

+38-145
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
# pkg.json
22

3+
`pkg.json` is a wild-west "package" format for defining packages without a package system.
4+
It's a (very) limited subset of NPM's `package.json` that allows any project to declare dependencies on arbitrary URLs.
5+
6+
The initial use-case is for Vim and Emacs plugins (which can be downloaded from anywhere), but the format is designed to be generic.
7+
8+
## Example
9+
10+
```
11+
{
12+
"name" : "lspconfig", // OPTIONAL cosmetic name, not used for resolution nor filesystem locations.
13+
"description" : "Quickstart configurations for the Nvim-lsp client", // OPTIONAL
14+
"engines": {
15+
"nvim": "^0.10.0",
16+
"vim": "^9.1.0"
17+
},
18+
"repository": { // REQUIRED
19+
"type": "git", // reserved for future use
20+
"url": "https://github.com/neovim/nvim-lspconfig"
21+
},
22+
"dependencies" : { // OPTIONAL
23+
"https://github.com/neovim/neovim" : "0.6.1",
24+
"https://github.com/lewis6991/gitsigns.nvim" : "0.3"
25+
},
26+
}
27+
```
28+
29+
## Overview
30+
331
- `pkg.json` is just a way to declare dependencies on URLs and versions
432
- Decentralized ("federated", omg)
533
- Subset of `package.json`
@@ -26,153 +54,18 @@
2654

2755
## What about LuaRocks?
2856

29-
LuaRocks is a natural as the Nvim plugin manager, but defining a ~~"plugin spec"~~ "federated package spec" also makes sense because:
57+
LuaRocks is a natural choice as the Nvim plugin manager, but defining a "federated package spec" also makes sense because:
3058

31-
- There is no "federated" plugin spec (corrections welcome!). LuaRocks is a "centralized" approach.
32-
- LuaRocks + Nvim is starting to see real progress in the form of https://github.com/nvim-neorocks , but thus far has not gained momentum. A decentralized, lowest-common-denominator, "infectious" approach is high-leverage, while work continues on the centralized LuaRocks approach at its own pace.
33-
- There's no central _asset_ registry, just a bunch of URLs.
34-
- Could have a central _list_ of plugins, but not assets.
35-
- We can do both, at low cost. `pkg.json` is a fairly "cheap" approach. LuaRocks
59+
- We can do both, at low cost. `pkg.json` is a fairly "cheap" approach.
60+
- LuaRocks is a "centralized" approach that requires active participation from many plugins.
61+
In contrast, `pkg.json` is a decentralized, "infectious" approach that is useful at the "leaf nodes":
62+
it only requires the consumer to provide a `pkg.json`, the upstream dependencies don't need to be "compliant" or participate in any way.
63+
- LuaRocks + Nvim is starting to see [progress](https://github.com/nvim-neorocks), but momentum will take time.
64+
A decentralized, lowest-common-denominator, "infectious" approach can be tried without losing much time or effort.
65+
- There's no central _asset registry_, just a bunch of URLs. (Though "aggregators" are possible and welcome.)
66+
- LuaRocks has 10x more scope than `pkg.json` and 100x more [unresolved edge cases](https://github.com/luarocks/luarocks/issues/905).
67+
`pkg.json` side-steps all of that by punting the ecosystem-dependent questions to the ecosystem-dependent package manager client.
3668

3769
## Release
3870

3971
TBD
40-
41-
---
42-
43-
# OLD
44-
45-
The neovim package specification consists of three components:
46-
1. Guidelines which provide guidance to package authors,
47-
2. the `packspec` file format, and
48-
3. guidelines for `packspec`-compatible plugin manager implementers
49-
50-
# Guidelines for plugin authors
51-
52-
### Semantic versioning
53-
54-
All Neovim packages should be [semantically versioned](https://semver.org/). While other versioning schema have uses, semver allows for plugin managers to provide smart dependency resolution.
55-
56-
# The `packspec` file
57-
The Neovim package specification supports a single, top-level package metadata file. This file can be *either* 'packspec.lua' or 'packspec.json'. The format is loosely based on the [Rockspec Format](https://github.com/luarocks/luarocks/wiki/Rockspec-format) and can contain the following fields:
58-
59-
* `package` (String) the name of the package
60-
61-
* `version` (String) the version of the package. Should obey semantic versioning conventions, for example `0.1.0`. Plugins should have a git commit with a `tag` matching this version. For all version identifiers, implementation should check for a `version` prefixed with `v` in the git repository, as this is a common convention.
62-
63-
* `packspec` (String) the current specification version. (0.1.0) at this time.
64-
65-
* `source` (String) The URL of the package source archive. Examples: "http://github.com/downloads/keplerproject/wsapi/wsapi-1.3.4.tar.gz", "git://github.com/keplerproject/wsapi.git". Different protocols are supported:
66-
67-
* `file://` - for URLs in the local filesystem (note that for Unix paths, the root slash is the third slash, resulting in paths like "file:///full/path/filename"
68-
* `git://` - for the Git source control manager
69-
* `git+https://` - for the Git source control manager when using repositories that need https:// URLs
70-
* `git+ssh://` - for the Git source control manager when using repositories that need SSH login, such as [email protected]/myrepo
71-
* `http://` - for HTTP URLs
72-
* `https://` - for HTTPS URLs
73-
* `luarocks://` - for Luarocks packages
74-
75-
* `description` (Table) the description is a table that includes the following nested fields:
76-
* `summary` (String) a short description of the package, typically less than 100 character long.
77-
* `detailed` (String) a long-form description of the package, this should convey the package's principal functionality to the user without being as detailed as the package readme.
78-
* `homepage` (String) This is the homepage of the package, which in most cases will be the GitHub URL.
79-
* `license` (String) This is [SPDX](https://spdx.org/licenses/) license identifier. Dual licensing is indicated via joining the relevant licenses via `/`.
80-
81-
* `dependencies` (List[Table]) A list of tables describing the package dependencies. Each entry in the table has the following, only `source` is mandatory:
82-
* `version` (String) The version constraints on the package.
83-
* Accepted operators are the relational operators of Lua: == \~= < > <= >= , as well as a special operator, \~>, inspired by the "pessimistic operator" of RubyGems ("\~> 2" means ">= 2, < 3"; "~> 2.4" means ">= 2.4, < 2.5"). No operator means an implicit == (i.e., "lfs 1.0" is the same as "lfs == 1.0"). "lua" is an special dependency name; it matches not a rock, but the version of Lua in use. Multiple version constraints can be joined with a `comma`, e.g. `"neovim >= 5.0, < 7.0"`.
84-
* If no version is specified, then HEAD is assumed valid.
85-
* If no upper bound is specified, then any commit after the tag corresponding to the lower bound is assumed valid. The commit chosen is up to the plugin manager's discretion, but implementers are strongly encouraged to always use the latest valid commit.
86-
* If an upper bound is specified, then the the tag corresponding to that upper bound is the latest commit that is valid
87-
88-
* `source` (String) The source of the dependency. See previous `source` description.
89-
* `releases_only` (Boolean) Whether the package manager should only resolve version constraints to include tagged releases.
90-
91-
92-
* `external_dependencies` (Table) Like dependencies, this specifies packages which are required for the package but should *not* be managed by the Neovim package manager, such as `gcc` or `cmake`. Package managers are encouraged to provide a notification to the user if the dependency is not available.
93-
* `version` (String) same as `dependencies`
94-
95-
# Example
96-
97-
```lua
98-
package = "lspconfig"
99-
version = "0.1.2"
100-
specification_version = "0.1.0"
101-
source = "git://github.com/neovim/nvim-lspconfig.git",
102-
description = {
103-
summary = "Quickstart configurations for the Nvim-lsp client",
104-
detailed = [[
105-
lspconfig is a set of configurations for language servers for use with Neovim's built-in language server client. Lspconfig handles configuring, launching, and attaching language servers.
106-
]],
107-
homepage = "git://github.com/neovim/nvim-lspconfig/",
108-
license = "Apache-2.0"
109-
}
110-
dependencies = {
111-
neovim = {
112-
version = ">= 0.6.1",
113-
source = "git://github.com/neovim/neovim.git"
114-
},
115-
gitsigns = {
116-
version = "> 0.3",
117-
source = "git://github.com/lewis6991/gitsigns.nvim.git"
118-
}
119-
}
120-
external_dependencies = {
121-
git = {
122-
version = ">= 1.6.0",
123-
},
124-
}
125-
```
126-
127-
And in json format
128-
```json
129-
{
130-
"package" : "lspconfig",
131-
"version" : "0.1.2",
132-
"specification_version" : "0.1.0",
133-
"source" : "git://github.com/neovim/nvim-lspconfig.git",
134-
"description" : {
135-
"summary" : "Quickstart configurations for the Nvim-lsp client",
136-
"detailed" : "lspconfig is a set of configurations for language servers for use with Neovim's built-in language server client. Lspconfig handles configuring, launching, and attaching language servers",
137-
"homepage" : "https://github.com/neovim/nvim-lspconfig/",
138-
"license" : "Apache-2.0"
139-
},
140-
"dependencies" : {
141-
"neovim" : {
142-
"version" : ">= 0.6.1",
143-
"source" : "git://github.com/neovim/neovim.git"
144-
},
145-
"gitsigns" : {
146-
"version" : "> 0.3",
147-
"source" : "git://github.com/lewis6991/gitsigns.nvim.git"
148-
}
149-
},
150-
"external_dependencies" : {
151-
"git" : {
152-
"version" : ">= 1.6.0",
153-
},
154-
}
155-
}
156-
```
157-
158-
# Guidelines for `packspec` implementers
159-
160-
The main features that must be implemented to be considered `packspec`-compatible are:
161-
162-
## Managing package versions
163-
- Must be able to fetch and parse `packspec.json` files
164-
- Must be able to use `git` to retrieve and manipulate package sources
165-
- Must be able to fetch tagged commits for specified package versions
166-
- Must be able to check for updated `packspec.json` files
167-
168-
## Managing Neovim dependencies
169-
170-
- Must be able to check the current version of `Neovim` and warn on incompatibility
171-
- Must be able to retrieve and manage the specified versions of dependencies transitively, starting from user-specified packages
172-
- Must either be able to solve for compatible versions of dependency packages across all dependency relationships, or warn users if using a potentially inconsistent version resolution strategy (e.g. picking the first specified version of a dependency).
173-
- [optional] remove dependencies when they are no longer required (transitively) by any user-specified packages
174-
175-
## Managing external dependencies
176-
177-
- Must be able to check for the existence of a corresponding executable on the user's system
178-
- [optional] check the version constraints and warn the user if the external dependency are incompatible

Diff for: docs/README.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ a formalized way to list dependencies by URL.
2222
- [lazy.nvim](https://github.com/folke/lazy.nvim/)
2323
- TBD
2424

25-
# Client requirements
25+
# Package requirements
2626

27-
- `git` (packages can live at any git URL)
28-
- JSON parser
29-
30-
# Package server requirements
27+
The [package specification](./spec.md) specifies the structure of a package and the `pkg.json` format.
3128

3229
- Dependency URLs are expected to be git repos.
3330
- TODO: support other kinds of artifacts, like zip archives or binaries.
3431

32+
# Client requirements
33+
34+
- `git` (packages can live at any git URL)
35+
- JSON parser
36+
- [client guidelines](./client-spec.md)
37+
3538
# Design
3639

3740
1. Support _all "assets" or "artifacts" of any kind_.
@@ -47,5 +50,6 @@ a formalized way to list dependencies by URL.
4750
# References
4851

4952
- https://json-schema.org/
53+
- https://github.com/luarocks/luarocks/wiki/Rockspec-format
5054
- lazy.nvim [pkg.json impl](https://github.com/folke/lazy.nvim/pull/910/files#diff-eeb8f2e48ace6e2f4c40bf159b7f59e5eb1208e056a3f9f1b9cc6822ecb45371)
5155
- [A way for artifacts to depend on other artifacts.](https://sink.io/jmk/artifact-system)

Diff for: docs/client-spec.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# pkg.json client specification
2+
3+
_Work-in-progress: These guideliens are subject to change._
4+
5+
pkg.json clients...
6+
7+
## Fetching dependencies
8+
9+
- MUST be able to fetch and parse `pkg.json` files
10+
- MUST be able to use `git` to clone dependencies and query git repo info
11+
- MUST be able to fetch tagged commits for specified package versions
12+
- MUST be able to check for updated `pkg.json` files
13+
14+
## Resolving dependencies
15+
16+
- MUST be able to check the current version of `Neovim` and warn on incompatibility
17+
- MUST be able to fetch and manage the specified versions of dependencies transitively: if dependencies have `pkg.json`, read it and process it, recursively.
18+
- MUST either be able to solve for compatible versions of dependency packages across all dependency relationships, or warn users if using a potentially inconsistent version resolution strategy (e.g. picking the first specified version of a dependency).
19+
- MAY remove dependencies when they are no longer required (transitively) by any user-specified packages

0 commit comments

Comments
 (0)