Skip to content

Commit b8a6940

Browse files
authored
Proposal for packages.json file
1 parent 88eda00 commit b8a6940

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Dart Package Configuration File v2.0
2+
Author: [email protected]<br>
3+
Version: 0.1
4+
5+
Dart currently uses a `.packages` file to configure *package URI resolution* (converting a package URI to a file name). The file uses a `.ini` file-like format with package names as keys and URI references as values. The URI references generated by Pub are always absolute or relative paths, so third-party users of the file tend to see them as paths, not URI.
6+
7+
For the *language versioning* feature, we have proposed extending the format by adding fragments to the URI references and an entry with the empty string as key. This is a breaking change (the empty key was not previously accepted) and even more breaking for tools which assume the values are paths.
8+
9+
Instead of breaking the existing file users, we will instead introduce a *new* file containing the information that we intended to store in the `.packages` file. This fill will use a (more) structured format which allows extending it with further information in the future. We will still generate the `.packages` file for now, allowing users of the file to continue working until they can migrate to using the new file.
10+
11+
## New File Contents
12+
13+
The file will contain the information that was planned for the `.packages` file:
14+
15+
- A *default package* specified by its package name.
16+
- A list of *packages*, each with:
17+
- A *package name*.
18+
- A *path* or *location URI*.
19+
- A *language version* (major/minor version number)
20+
21+
On top of that, we also add extra metadata which allows us to version the format and attach information about when and how the file was created.
22+
23+
We use JSON for the format. JSON has parsers available for most languages (not all Dart tools are written in Dart) and it is standardized and efficiently parsable. JSON is *not* easy to write by hand (but doable), and it does not allow comments, but this is a machine generated file that will hardly ever be edited by hand.
24+
25+
## New File Format
26+
27+
The new file will be called `.packages.json` and stored in the same directory as the `.packages` file. The format is JSON text describing is a single JSON object.
28+
29+
That object has, at least, the following properties:
30+
31+
- `apiVersion`: A single integer marking the version of this format, currently `2` (counting `.packages` as the first). Tools should refuse to work on files with a larger version number than the ones they are aware of. Incremental changes will not require increasing the version, so new versions are not expected any time soon, but code should still prepare for it.
32+
33+
- `defaultPackage`: A string containing a package name.
34+
- `packages`: A list of packages, each with the following properties:
35+
- `name`: A string containing a package name.
36+
- either `path`: A string containing a relative or absolute path using `/` as separator. Every character other than `/` is used verbatim. If the path starts with a `/` or with a DOS/Windows drive letter (a single letter followed by `:/`), then it is considered absolute. If not, the path is relative to the directory of the `.packages.json` file.
37+
- or `uri`: A URI reference. This is resolved relative to the (likely `file:`) URI referencing the `.package.json` file. If the URI reference has no scheme, or if it has a `file:` scheme, it is recommended to use the `path` instead.
38+
- `languageVersion`: Optional. A string containing a language version (major.minor).
39+
40+
Tools should ignore properties that they don't recognize. This will allow us to add more properties in the future, but not to remove properties or change the meaning of existing properties.
41+
42+
If we remove a property that tools rely on, change the meaning of an existing property, or add more information that is *required* for resolving and understanding Dart source files, it is a breaking change&mdash;tools expecting the previously available data will no longer understand the whole picture. Such changes will require increasing the `apiVersion` number.
43+
44+
The following properties allows the generator to specify metadata about the file:
45+
46+
- `generated`: A string containing an ISO-8601 timestamp for when the file was generated.
47+
- `generator`: An object containing at last the following properties:
48+
- `name`: Name of the generator. Likely `pub`.
49+
- `version`: The version of the generator. A Semantic Version, or a prefix of such (major version only, or major/minor version only are also accepted). Pub can probably use the SDK version.
50+
51+
These are all optional, but if they are present, they should have the expected format.
52+
53+
If a tool wants to store extra information in the `.packages.json` file, they can do so under a key prefixed by `toolname:`, so if Pub wanted to store more information on a package, say the package version, it could do so as `"pub:pkgVersion": "1.16.0"` in the package entry. Keys containing `:` are reserved for custom tool-specific properties. This feature can only really be used by the tool generating the file (as a generated file, it may be overwritten at any time), and it should be used sparingly since unknown properties are just overhead for all other users of the file.
54+
55+
### Package Names
56+
57+
Some properties are specified as being "package names".
58+
59+
A package name is used as both a URI path segment and a directory name. To ensure this is possible, we define a package name as a string containing:
60+
61+
- Only [URI path characters](https://www.ietf.org/rfc/rfc3986.txt) (RFC 3986 "pchar"),
62+
- but no `\`, `:` or `%`,
63+
- and containing at least one non-`.` character.
64+
65+
This avoids the characters `/`, `\` and `:` which are meaningful in paths on various operating systems, as well as the strings `.` and `..`, and it ensures that the remaining characters are valid in a URI path and not the empty string.
66+
67+
## Possible Extensions
68+
69+
We can consider already adding more features to the format. These features should be ones that are of relevance to compilers reading source files, since that is the goal of the file.
70+
71+
Any such extensions would need to be added by the generator, so in practice they must come from `pubspec.yaml` to begin with. If the Pub tool wants to support these, it is possible.
72+
73+
### Experiments
74+
75+
Maybe you can enable experiments for a specific package by adding, for example:
76+
77+
```json
78+
"experiments": ["non-nullabe"]
79+
```
80+
81+
to a single package entry, or add it in the outer object to enable it for all compatible packages.
82+
83+
### Environment Variables
84+
85+
Maybe you can hard-code some environment variables by adding, for example:
86+
87+
```json
88+
"environment": {
89+
"myFlag": "true",
90+
"logLevel": "verbose"
91+
}
92+
```
93+
94+
in the outer object.
95+
96+
## Summary
97+
98+
A file, `.packages.json` will coexist with `.packages` until `.packages` can be phased out.
99+
100+
The format will look like:
101+
102+
```json
103+
{
104+
"apiVersion": 2,
105+
"defaultPackage": "myPackage",
106+
"packages": [
107+
{
108+
"name": "myPackage",
109+
"path": "lib/",
110+
"languageVersion": "2.6"
111+
},
112+
{
113+
"name": "myHelperPackage",
114+
"path": "../myHelperPackage/lib/",
115+
"languageVesion": "2.5"
116+
},
117+
{
118+
"name": "test",
119+
"path": "/users/myself/.pubcache/test-1.16.0/lib/",
120+
"languageVersion": "2.5"
121+
},
122+
...
123+
],
124+
"generated": "2019-09-12T12:13:14",
125+
"generator": {
126+
"name": "pub",
127+
"version": "2.6.0-dev.0.2"
128+
}
129+
}
130+
```

0 commit comments

Comments
 (0)