Packages 1.0 comments

95 views
Skip to first unread message

Mikeal Rogers

unread,
Mar 22, 2010, 2:13:27 PM3/22/10
to comm...@googlegroups.com
Comments on Packages/1.0 ( BTW, I apologize for sending two large emails back to back, I spent all morning in the Jury Duty waiting room and these are the fruits of my labor )

A few general comments.

This is a great specification. My main concern is that it's a bit large, especially in regard to the amount of required properties. IMHO required properties should be limited to information installers, managers and package registries MUST have in order to properly maintain, store, and install packages.

Along with the current big package.json example I'd like to add an example of a very small package.json file to give an impression of what the minimum required attributes are. Any objections?

Inline Comments:

bugs - URL for submitting bugs. Can be mailto or http.

I don't see why this is a required field. Not everyone who creates a package wants to either setup a bug tracker or encourage bugs be sent to their personal email.

I do think that it's a good idea to specify a bugs property, I think that in the future we could include links to standard bug tracker APIs which would allow package registries to show bug information alongside packages. I just don't think this should be required.

licenses property

I'm a little concerned about the licenses attribute. For one thing, defining this attribute is not a sufficient declaration by itself to license the package under a particular license(s). Most people already understand this but the fact that the attribute is required might lead some to believe it is legally binding. At the very least I think we need a strong note in the documentation that this is not legally binding and encourage package installers to check the license information and warn the user if they have not included a LICENSE file or proper license headers in their source files when required by that license.

repositories property

I love that this attribute is specified but it shouldn't be required. Not all packages will have a public source repository.

dependencies property

This should not be required when there are no dependencies. I would also love to see specification of ">=", "<=", ">", "<" version declarations like npm (Node Package Manager) provides.

"builtin"- Boolean value indicating the package is built in as a standard component of the underlying platform

If an installer is performing a package installation of a 3rd party package are they required to modify the package.json on installation to set the value to false?

directories - Object hash of package directories. Typical directories include "lib", "src", "doc", "jars", "test" and "bin". Package manager tools must use these directory definitions to find various package components.

I don't think that this definition is sufficient for package managers. When defined, does this attribute mean to exclude any directories/subdirectories that are not in the list? If not are package managers required to recursively parse all subdirectories?

Binary files should be in the "bin" directory,

It's entirely possible to have a module that when run by itself is a bin but when required is a reusable library. Is there a reason we are trying to discourage this?

The following fields are reserved for future expansion: build, default, email, external, files, imports, maintainer, paths, platform, require, summary, test, using, downloads, uid, type

I would like to add that properties beginning with "_" are reserved for package registries. I'd also like the top level type attribute to be reserved for package registries. JSON databases tend to reserve _ properties and it's very common for applications to use the type attribute when storing JSON, I'd like package.json files to be easily storable by JSON databases without modification.



Daniel Friesen

unread,
Mar 22, 2010, 2:41:40 PM3/22/10
to comm...@googlegroups.com
Mikeal Rogers wrote:
> ...

>
> The following fields are reserved for future expansion: build,
> default, email, external, files, imports, maintainer, paths,
> platform, require, summary, test, using, downloads, uid, type
>
>
> I would like to add that properties beginning with "_" are reserved
> for package registries. I'd also like the top level type attribute to
> be reserved for package registries. JSON databases tend to reserve _
> properties and it's very common for applications to use the type
> attribute when storing JSON, I'd like package.json files to be easily
> storable by JSON databases without modification.
How about also reserving $ properties. Storing packages in MongoDB would
be very interesting.

~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]

Ash Berlin

unread,
Mar 22, 2010, 2:44:18 PM3/22/10
to comm...@googlegroups.com
On 22 Mar 2010, at 18:13, Mikeal Rogers wrote:
Comments on Packages/1.0 ( BTW, I apologize for sending two large emails back to back, I spent all morning in the Jury Duty waiting room and these are the fruits of my labor )

A few general comments.

This is a great specification. My main concern is that it's a bit large, especially in regard to the amount of required properties. IMHO required properties should be limited to information installers, managers and package registries MUST have in order to properly maintain, store, and install packages.

Along with the current big package.json example I'd like to add an example of a very small package.json file to give an impression of what the minimum required attributes are. Any objections?

Inline Comments:

bugs - URL for submitting bugs. Can be mailto or http.

I don't see why this is a required field. Not everyone who creates a package wants to either setup a bug tracker or encourage bugs be sent to their personal email.

I do think that it's a good idea to specify a bugs property, I think that in the future we could include links to standard bug tracker APIs which would allow package registries to show bug information alongside packages. I just don't think this should be required.

Agreed. Can you add this to a new section on the http://wiki.commonjs.org/wiki/Packages page for things to incorporate (or at least discus) for the next revision.


licenses property

I'm a little concerned about the licenses attribute. For one thing, defining this attribute is not a sufficient declaration by itself to license the package under a particular license(s). Most people already understand this but the fact that the attribute is required might lead some to believe it is legally binding. At the very least I think we need a strong note in the documentation that this is not legally binding and encourage package installers to check the license information and warn the user if they have not included a LICENSE file or proper license headers in their source files when required by that license.

Agreed, this might not define the license of the package in the legal sense (it could, IANAL etc.), but it does provide a way for package registries (CPAN, pypi, rubyforge etc) to display what license a package claims to be under.

The check steps seem difficult to do reliably as there are many many ways you could specify a license in the source files.

repositories property

I love that this attribute is specified but it shouldn't be required. Not all packages will have a public source repository.

Shame on that author then ;) Add it to the wiki

dependencies property

This should not be required when there are no dependencies.

The argument for making this required was to make case no dependancies explicit. I don't mind either way on this one.


I would also love to see specification of ">=", "<=", ">", "<" version declarations like npm (Node Package Manager) provides.

I have argued against this because I want to foster a culture where back-compat in a major version (X.*.* in the semver) is paramount. If you embrace semvar fully then >= is the only case you need: "2.0.3" means ">= 2.0.3 and < 3"


"builtin"- Boolean value indicating the package is built in as a standard component of the underlying platform

If an installer is performing a package installation of a 3rd party package are they required to modify the package.json on installation to set the value to false?

You'd have to ask the narwhal guys about this one - I think it came from them (Kris Kowal or Christopher Dorn)

directories - Object hash of package directories. Typical directories include "lib", "src", "doc", "jars", "test" and "bin". Package manager tools must use these directory definitions to find various package components.

I don't think that this definition is sufficient for package managers. When defined, does this attribute mean to exclude any directories/subdirectories that are not in the list? If not are package managers required to recursively parse all subdirectories?


The wording of "typical" there makes me read it as "these are the common ones, but the exact meaning is up to the package installer".

Binary files should be in the "bin" directory,

It's entirely possible to have a module that when run by itself is a bin but when required is a reusable library. Is there a reason we are trying to discourage this?

No reason to discourage it, but the bin/ folder is for things that are explicitly not modules you can require. 

The following fields are reserved for future expansion: build, default, email, external, files, imports, maintainer, paths, platform, require, summary, test, using, downloads, uid, type

I would like to add that properties beginning with "_" are reserved for package registries. I'd also like the top level type attribute to be reserved for package registries. JSON databases tend to reserve _ properties and it's very common for applications to use the type attribute when storing JSON, I'd like package.json files to be easily storable by JSON databases without modification.

Could you expand on this more? Mainly why would registries be changing the package.json for a package? And what do you mean by 'top level type attribute to be reserved' Restricting keys to not start with "_" is sensible.

-ash

Mikeal Rogers

unread,
Mar 22, 2010, 4:35:46 PM3/22/10
to comm...@googlegroups.com
On Mon, Mar 22, 2010 at 11:44 AM, Ash Berlin <ash_flu...@firemirror.com> wrote:
On 22 Mar 2010, at 18:13, Mikeal Rogers wrote:
Comments on Packages/1.0 ( BTW, I apologize for sending two large emails back to back, I spent all morning in the Jury Duty waiting room and these are the fruits of my labor )

A few general comments.

This is a great specification. My main concern is that it's a bit large, especially in regard to the amount of required properties. IMHO required properties should be limited to information installers, managers and package registries MUST have in order to properly maintain, store, and install packages.

Along with the current big package.json example I'd like to add an example of a very small package.json file to give an impression of what the minimum required attributes are. Any objections?

Inline Comments:

bugs - URL for submitting bugs. Can be mailto or http.

I don't see why this is a required field. Not everyone who creates a package wants to either setup a bug tracker or encourage bugs be sent to their personal email.

I do think that it's a good idea to specify a bugs property, I think that in the future we could include links to standard bug tracker APIs which would allow package registries to show bug information alongside packages. I just don't think this should be required.

Agreed. Can you add this to a new section on the http://wiki.commonjs.org/wiki/Packages page for things to incorporate (or at least discus) for the next revision.

done.
 


licenses property

I'm a little concerned about the licenses attribute. For one thing, defining this attribute is not a sufficient declaration by itself to license the package under a particular license(s). Most people already understand this but the fact that the attribute is required might lead some to believe it is legally binding. At the very least I think we need a strong note in the documentation that this is not legally binding and encourage package installers to check the license information and warn the user if they have not included a LICENSE file or proper license headers in their source files when required by that license.

Agreed, this might not define the license of the package in the legal sense (it could, IANAL etc.), but it does provide a way for package registries (CPAN, pypi, rubyforge etc) to display what license a package claims to be under.

Added to the new section.
 

The check steps seem difficult to do reliably as there are many many ways you could specify a license in the source files.

Correct, but some licenses require you put the license block in every file. Packagers can help you find places where you've neglected to properly license code under the intended license and provide feedback but I don't expect them to do 100% validation.
 

repositories property

I love that this attribute is specified but it shouldn't be required. Not all packages will have a public source repository.

Shame on that author then ;) Add it to the wiki

added
 

dependencies property

This should not be required when there are no dependencies.

The argument for making this required was to make case no dependancies explicit. I don't mind either way on this one.


I would also love to see specification of ">=", "<=", ">", "<" version declarations like npm (Node Package Manager) provides.

I have argued against this because I want to foster a culture where back-compat in a major version (X.*.* in the semver) is paramount. If you embrace semvar fully then >= is the only case you need: "2.0.3" means ">= 2.0.3 and < 3"

I like this idea but it needs to be a little more explicit in the docs. Right now there isn't any easy way for me to tell that 3 and 3.0.0 are actually different declarations.
 


"builtin"- Boolean value indicating the package is built in as a standard component of the underlying platform

If an installer is performing a package installation of a 3rd party package are they required to modify the package.json on installation to set the value to false?

You'd have to ask the narwhal guys about this one - I think it came from them (Kris Kowal or Christopher Dorn)

directories - Object hash of package directories. Typical directories include "lib", "src", "doc", "jars", "test" and "bin". Package manager tools must use these directory definitions to find various package components.

I don't think that this definition is sufficient for package managers. When defined, does this attribute mean to exclude any directories/subdirectories that are not in the list? If not are package managers required to recursively parse all subdirectories?


The wording of "typical" there makes me read it as "these are the common ones, but the exact meaning is up to the package installer".

I'm not worried about installers much, they will probably just copy the directories over directly, but for a packager (something that is building a tarball and excluding unnecessary files) I would like a definition that could ensure interoperability.
 

Binary files should be in the "bin" directory,

It's entirely possible to have a module that when run by itself is a bin but when required is a reusable library. Is there a reason we are trying to discourage this?

No reason to discourage it, but the bin/ folder is for things that are explicitly not modules you can require.

got it.
 
 

The following fields are reserved for future expansion: build, default, email, external, files, imports, maintainer, paths, platform, require, summary, test, using, downloads, uid, type

I would like to add that properties beginning with "_" are reserved for package registries. I'd also like the top level type attribute to be reserved for package registries. JSON databases tend to reserve _ properties and it's very common for applications to use the type attribute when storing JSON, I'd like package.json files to be easily storable by JSON databases without modification.

Could you expand on this more? Mainly why would registries be changing the package.json for a package? And what do you mean by 'top level type attribute to be reserved' Restricting keys to not start with "_" is sensible.

Ideally package registries wont be modifying the package.json in order to store it but in order to do that we'll need to add a couple restrictions like _ and $ prefix reservations for CouchDB and MongoDB respectively. The "type" property is very commonly used when writing applications in a JSON store, it's the property you are normally encouraged to use to tell different objects apart which is why I'd like to leave it alone in order to avoid conflicts.

-Mikeal

Irakli Gozalishvili

unread,
Mar 23, 2010, 4:44:59 PM3/23/10
to comm...@googlegroups.com
BTW I wanted to propose something for package.json as well. What if we say that all the non pseudo namespaced keys in JSON is reserved for a possible future extension by commonjs.

by pseudo namespaced keys I meant something like "namespace:key". in Example it will be


{
   "moz:app": "myapp",
"moz:type": "extension",
"bespin:type": "plugin",
"narwhal:dependencies": ["xulrunner"],
"name": "mypackage",
"version": "0.7.0",
"description": "Sample package for CommonJS. This package demonstrates the required elements of a CommonJS package.",
"keywords": [
"package",
"example"
],
"maintainers": [
{
"name": "Bill Smith",
"email": "bi...@example.com",
"web": "http://www.example.com"
}
],
"contributors": [
{
"name": "Mary Brown",
"email": "ma...@embedthis.com",
"web": "http://www.embedthis.com"
}
],
"bugs": {
"mail": "d...@example.com",
"web": "http://www.example.com/bugs"
},
"licenses": [
{
"type": "GPLv2",
"url": "http://www.example.org/licenses/gpl.html"
}
],
"repositories": [
{
"type": "git",
"url": "http://hg.example.com/mypackage.git"
}
],
"dependencies": {
"webkit": "1.2",
"ssl": {
"gnutls": ["1.0", "2.0"],
"openssl": "0.9.8"
}
},
"implements": ["cjs-module-0.3", "cjs-jsgi-0.1"],
"os": ["linux", "macos", "win"],
"cpu": ["x86", "ppc", "x86_64"],
"engines": ["v8", "ejs", "node", "rhino"],
"scripts": {
"install": "install.js",
"uninstall": "uninstall.js",
"build": "build.js",
"test": "test.js"
},
"directories": {
"lib": "src/lib",
"bin": "local/binaries",
"jars": "java"
}
}


you might noticed "moz:*" , "bespin:*" "narwhal:*" keys in json. I can imagine that commonjs package can be an extension to firefox / jetpack or and plugin for bespin while being a regular commonjs lib package and all this at the same time. In order to avoid all kinds of conflicts between platforms that package is targeting we could recommend this sort of a namespacing and forbid any other additional keys.


--
Irakli Gozalishvili
Web: http://rfobic.wordpress.com/
Phone: +31 614 205275
Address: Taksteeg 3 - 4, 1012PB Amsterdam, Netherlands


--
You received this message because you are subscribed to the Google Groups "CommonJS" group.
To post to this group, send email to comm...@googlegroups.com.
To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.

Kris Kowal

unread,
Mar 23, 2010, 5:28:16 PM3/23/10
to comm...@googlegroups.com
On Tue, Mar 23, 2010 at 1:44 PM, Irakli Gozalishvili <rfo...@gmail.com> wrote:
> by pseudo namespaced keys I meant something like "namespace:key". in Example
> it will be

I highly discourage borrowing this idea from XML. It is *completely*
adequate to use an object for name spacing.

{
"moz": {},
"bespin": {},
"narwhal": {},
"karma": {}
}

I really don't want to go down the road of creating heavy libraries
for namespace scraping when simple property access would do the job.

Kris Kowal

Mikeal Rogers

unread,
Mar 23, 2010, 5:47:03 PM3/23/10
to comm...@googlegroups.com
I agree with Kris that an object is adequate but we should specify a reserved property for this and how it's supposed to be used.

Something like:

{
  "specific": { "engine_name": { "depedencies":[]}}
}

Where each attribute would fully override the top level property for that engine.

-Mikeal

Daniel Friesen

unread,
Mar 23, 2010, 6:09:20 PM3/23/10
to comm...@googlegroups.com
{ "vendor": , { "vendors": , { "vnd": , { "x": , { "-": , { ":": , {
"ext": , { "env": , { "environment":, { "environments": ...
^_^ Take your pick, we've done this kind of thing over and over.

~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]

> <mailto:comm...@googlegroups.com>.


> To unsubscribe from this group, send email to
> commonjs+u...@googlegroups.com

> <mailto:commonjs%2Bunsu...@googlegroups.com>.

Kris Kowal

unread,
Mar 23, 2010, 6:18:23 PM3/23/10
to comm...@googlegroups.com
On Tue, Mar 23, 2010 at 2:47 PM, Mikeal Rogers <mikeal...@gmail.com> wrote:
> {
>   "specific": { "engine_name": { "depedencies":[]}}
> }

This is interesting, and solves a different issue than pure
name-spacing; this implies predicated overlays, which could be a much
more general idea, and raise more questions than they answer. For
example, is the innermost object a simple or deep update? How is the
deep update performed? Would a JSON-patch of some kind be more
expressive? Would it be better to provide a more general form of
predicate than just engine/vendor name matching?

A lot of these questions melt away if you've got a specific use-case.

Also, I'm for the xVendorPrefix notation instead of blacklisting
future reserved names, if everyone can stomach it. The xVendorPrefix
notation stopped the embrace+extend browser wars, which I think is a
generally applicable lesson for any standards compliance effort.

Kris Kowal

Irakli Gozalishvili

unread,
Mar 23, 2010, 6:41:55 PM3/23/10
to comm...@googlegroups.com
I'm not married with "vendor:key" approach either, but I think none except `vendor` should care of the prefixed keys, therefor no heavy libraries are needed. it can be "-moz-key" if you like CSS way more :) just kidding

Seriously I do think we should at least specify expected prefix behavior ( lets say for platform specific properties create a platform subtree and store everything there)

@Mikael I think it's very wrong to specify what or how platform specific things behave, let's leave this up to the platform itself. If they need to override things let them decide how cause most likely they will deal with it :)

Here is two real life examples of current package.json usage which I do consider to be incorrect:

It's plugin.json but I believe they will eventually move to package.json since it makes sense cause some commonjs packages can easily serve as bespin plugins.
https://bespin.mozillalabs.com/docs/pluginguide/index.html

Jetpack is using package.json for jetpacks. Even though on a link it's nicely links to the specs existing packages have non prefixed extensions to the package.json
https://jetpack.mozillalabs.com/sdk/0.1/docs/#guide/packaging


--
Irakli Gozalishvili
Web: http://rfobic.wordpress.com/
Phone: +31 614 205275
Address: Taksteeg 3 - 4, 1012PB Amsterdam, Netherlands



Kris Kowal

Mikeal Rogers

unread,
Mar 23, 2010, 7:49:07 PM3/23/10
to comm...@googlegroups.com
On Tue, Mar 23, 2010 at 3:18 PM, Kris Kowal <cowber...@gmail.com> wrote:
On Tue, Mar 23, 2010 at 2:47 PM, Mikeal Rogers <mikeal...@gmail.com> wrote:
> {
>   "specific": { "engine_name": { "depedencies":[]}}
> }

This is interesting, and solves a different issue than pure
name-spacing; this implies predicated overlays, which could be a much
more general idea, and raise more questions than they answer. For
example, is the innermost object a simple or deep update?

So far the packages specification limits itself to defining top level properties (even if it sometimes specifies what goes in those properties). At this time there is nothing specified that can live inside some other nested structure which is not defined in the spec so I think it's fair/safe to say that each attribute defined for a given "vendor" is used as a replacement for the top level attribute.
 
How is the
deep update performed?

for (key in package.vendor.node) {
  package[key] = package.vendor.node[key];
}
 
Would a JSON-patch of some kind be more
expressive? Would it be better to provide a more general form of
predicate than just engine/vendor name matching?

I think it's best to only define suggestions for vendor definitions. There are two overlapping consumers; engines and package installers. For instance I could see something like:

{"vendor":{"node":{"dependencies":[...]},
                 "npm":{"scripts":{"install":"./npm-install.sh"}}
}

When npm installs this package it would need to replace both the node and npm attributes in an order it's decided is sane.

I think the usage and specification remains simple if you:

a) Treat each vendor property as a top level replacement
b) Refrain from specifying the different vendor keys and allow engines and installers to work that out among themselves.
 
Also, I'm for the xVendorPrefix notation instead of blacklisting
future reserved names, if everyone can stomach it. The xVendorPrefix
notation stopped the embrace+extend browser wars, which I think is a
generally applicable lesson for any standards compliance effort.

I think we *still* need this in the case that a vendor has a specific attribute that does not overlap with the other defined attributes in the packages specification. BUT, I think if we add x- and/or prefixes without giving a simpler way to override properties then it's going to lead to this:

{"dependencies":[...],
 "x-node-dependencies":[.....],
 "x-npm-dependencies":[....],
}

In this case the installer is actually not following the specification (using the "dependencies" property) and will have it's own code to override properties using x-. Even worse, while some installers may decide that x-npm-dependencies overrides x-node-dependencies entirely others may decide that x- declarations concatenate the two values together which would be really annoying.

-Mikeal


Kris Kowal

unread,
Mar 23, 2010, 8:01:47 PM3/23/10
to comm...@googlegroups.com
On Tue, Mar 23, 2010 at 4:49 PM, Mikeal Rogers <mikeal...@gmail.com> wrote:
>> How is the
>> deep update performed?
>
> for (key in package.vendor.node) {
>   package[key] = package.vendor.node[key];
> }

Ok. Shallow copy is fine.

>> Would a JSON-patch of some kind be more
>> expressive? Would it be better to provide a more general form of
>> predicate than just engine/vendor name matching?
>
> I think it's best to only define suggestions for vendor definitions. There
> are two overlapping consumers; engines and package installers. For instance
> I could see something like:
>
> {"vendor":{"node":{"dependencies":[...]},
>                  "npm":{"scripts":{"install":"./npm-install.sh"}}
> }

Okay.

> When npm installs this package it would need to replace both the node and
> npm attributes in an order it's decided is sane.
>
> I think the usage and specification remains simple if you:
>
> a) Treat each vendor property as a top level replacement
> b) Refrain from specifying the different vendor keys and allow engines and
> installers to work that out among themselves.

Okay.

>> Also, I'm for the xVendorPrefix notation instead of blacklisting
>> future reserved names, if everyone can stomach it. The xVendorPrefix
>> notation stopped the embrace+extend browser wars, which I think is a
>> generally applicable lesson for any standards compliance effort.
>
> I think we *still* need this in the case that a vendor has a specific
> attribute that does not overlap with the other defined attributes in the
> packages specification. BUT, I think if we add x- and/or prefixes without
> giving a simpler way to override properties then it's going to lead to this:
>
> {"dependencies":[...],
>  "x-node-dependencies":[.....],
>  "x-npm-dependencies":[....],
> }
>
> In this case the installer is actually not following the specification
> (using the "dependencies" property) and will have it's own code to override
> properties using x-. Even worse, while some installers may decide that
> x-npm-dependencies overrides x-node-dependencies entirely others may decide
> that x- declarations concatenate the two values together which would be
> really annoying.

Alright, I'll buy that. I even like the color.

Kris Kowal

Isaac Z. Schlueter

unread,
Mar 23, 2010, 9:14:43 PM3/23/10
to CommonJS
1. Please let's not repeat the mistakes of our ancestors by using the
word "vendor" here. A vendor is one who vends, ie, sells something.
Node and Narwhal and npm aren't "vendors". I'd much prefer "env" or
"context" for this key, as in "when being read in the context of the
Narwhal environment, this package should have the following fields
override what's specified at the top level".

This is awesome:


> > for (key in package.vendor.node) {
> > package[key] = package.vendor.node[key];
> > }

But this would be even awesomer:
> > for (key in package.env.node) {


> > package[key] = package.vendor.node[key];
> > }

Lets not do the "xNodeDependencies" or "node:dependencies" or any
other string-namespace malarky. JSON has objects, they're for this
purpose, let's use them.

Then it's up to package managers to deal with it how they see fit, or
ignore it. If another package management program comes along that
decides it's just like narwhal, it can take the narwhal context vars
along with its own, etc. It's explicit, and wonderful. Best of all,
we don't have to agree, we just have to agree how we're going to go
about disagreeing, which is a MUCH easier thing to get resolution on.

I'm going to add support for this in npm right now, that's how hard I
love it.

If I'm the minority here, and you all decide to stick with misguided
tradition and use "vendor", then that's cool. It's just one key in
the code to change :) Naming stuff is hard, and "vendor" certainly
isn't the worst choice.


2. The reason why npm uses the ><= chars on the version number, and
takes "1.2.3" to mean "exactly equal to 1.2.3" is twofold:
(a) Installing multiple versions of the same package is trivial and
doesn't clobber anything, so there's no reason not to. If you've
tested with 1.2.3 and you know it works with 1.2.3, then by golly,
I'll give you 1.2.3 if you say you want that.
(b) As much as we all may say we're going to, almost no one actually
follows semver's rules, or even really fully understands them. I have
some pretty strong objections to relying on semver in any serious way.

The jump from 0.1.2 to 0.2.0 is often much greater than the jump from
1.1.2 to 1.2.0, according to the semantics of semver. And in fact,
node regularly makes non-backward-compatible changes in the API all
the time, and it's at version 0.1.33 right now.

It's not uncommon for a project to break those rules, even given the
best intentions of the authors. Sometimes, for various social or
marketing reasons, it makes more sense to say "Feature X will be in
version 1.2.0", and then not bump the mid-version until you get that
feature done, even if a lot of non-compatible API changes come between
now and then.

Programs should not try to be clever. Being clever is wrong, it's
bad, and it leads to all kinds of trouble. It's the worst thing a
program can do. It's better to be stupid and predictable and just get
a simple job done in a clear and reliable way, because that's what
computers are good at. A package manager should manage packages
reliably, and let package authors specify their needs explicitly,
rather than trying to guess.

If you tell npm that you want version 1.2.3, then that's the version
you're getting. Not 1.3.0, not 1.2.4, nothing else. if you tell it
you want something at least version 1.2.3 but less than 1.3.0, then
you can tell it that, and it'll make sure that's what you get. You
can tell it that by writing ">=1.2.3 <1.3.0" in the dependency field.
I'm not going to ruin my program with unnecessary cleverness just to
save a few bytes in a package.json file, on the foolhardy faith that
anyone actually uses semver the way they're "supposed" to.


3. Regarding the various "required" fields. As Mikeal pointed out
initially, I think most of these really don't need to be required, per
se. npm doesn't require anything more than a name and version.
Maybe, rather than having a spec which requires a bunch of fields, we
should just clarify which package managers require which fields, and
that might make it more clear.

4. Regarding reserving $ and _ properties for package.json
repositories: +1. Any fields starting with _ or $, and the "type" and
"id" fields, should be reserved for use by package json registries.

--i

Kris Kowal

unread,
Mar 23, 2010, 9:29:52 PM3/23/10
to comm...@googlegroups.com
On Tue, Mar 23, 2010 at 6:14 PM, Isaac Z. Schlueter <i...@foohack.com> wrote:
> 1. Please let's not repeat the mistakes of our ancestors by using the
> word "vendor" here.  A vendor is one who vends, ie, sells something.
> Node and Narwhal and npm aren't "vendors".  I'd much prefer "env" or
> "context" for this key, as in "when being read in the context of the
> Narwhal environment, this package should have the following fields
> override what's specified at the top level".

I see your "env" and raise you "overlay".

Kris Kowal

Mikeal Rogers

unread,
Mar 23, 2010, 9:31:07 PM3/23/10
to comm...@googlegroups.com

I like!

Mikeal Rogers

unread,
Mar 23, 2010, 9:40:10 PM3/23/10
to comm...@googlegroups.com

If this was the intention of the semver usage then I would have the same objections but I don't think it is.

I read this as:

1.2.4 === (install 1.2.4 and use 1.24, no other version)

1.2 === (install 1.2.x at the highest available version, use best available version)

Which has the somewhat confusing impact of meaning that in definition terms:

1.2.0 !== 1.2
 
This does NOT allow anyone to do ranges between 1.1 and 1.4, but if the intention is to encourage people to use proper semver then I'm all for it. I think there are some rough edges, and a few things that can't actually be defined in this scheme that are useful (a bug was fixed in 1.3.4 that I step on, I'd like 1.3.4 or newer) but it's all about tradeoffs.



3. Regarding the various "required" fields.  As Mikeal pointed out
initially, I think most of these really don't need to be required, per
se.  npm doesn't require anything more than a name and version.
Maybe, rather than having a spec which requires a bunch of fields, we
should just clarify which package managers require which fields, and
that might make it more clear.

I think it's fair to say "almost all package managers will need at least these properties" so that the vast majority of package managers can work with any package that conforms to the spec. The point of the spec is to encourage compatibility, if we leave it bare we're insuring that there won't be any.
 

4. Regarding reserving $ and _ properties for package.json
repositories: +1.  Any fields starting with _ or $, and the "type" and
"id" fields, should be reserved for use by package json registries.

Yeah, i don't know any JSON database that currently reserves "id" but it seems like it would be good to reserve it just in case.

-Mikeal

Dean Landolt

unread,
Mar 23, 2010, 9:45:35 PM3/23/10
to comm...@googlegroups.com
jsDB IIRC

Isaac Z. Schlueter

unread,
Mar 23, 2010, 11:02:30 PM3/23/10
to CommonJS

> On Tue, Mar 23, 2010 at 9:40 PM, Mikeal Rogers <mikeal.rog...@gmail.com>wrote:
> > I read this as:
>
> > 1.2.4 === (install 1.2.4 and use 1.24, no other version)
>
> > 1.2 === (install 1.2.x at the highest available version, use best available
> > version)
>
> > Which has the somewhat confusing impact of meaning that in definition
> > terms:
>
> > 1.2.0 !== 1.2
>
> > This does NOT allow anyone to do ranges between 1.1 and 1.4, but if the
> > intention is to encourage people to use proper semver then I'm all for it. I
> > think there are some rough edges, and a few things that can't actually be
> > defined in this scheme that are useful (a bug was fixed in 1.3.4 that I step
> > on, I'd like 1.3.4 or newer) but it's all about tradeoffs.

These are all great points, and all the more reason why we should just
use the extra characters and make package maintainers specific exactly
what they want, rather than having any non-obvious implications that
leave room for guesswork.

Let's be less clever.


> > Yeah, i don't know any JSON database that currently reserves "id" but it
> > seems like it would be good to reserve it just in case.

Dude, the js-registry we wrote has that and npm is using it :P

@kriskowal
Sure, overlay works, too. I'll add that to the list of extender keys
npm is aware of.

--i

Mikeal Rogers

unread,
Mar 23, 2010, 11:08:42 PM3/23/10
to comm...@googlegroups.com

it's using "_id" not "id".

apparently jsDB uses "id" so I'm +1 for reserving it as well.

-Mikeal

Ash Berlin

unread,
Mar 24, 2010, 8:00:52 AM3/24/10
to comm...@googlegroups.com
Then you read it wrong. Someone adds a new feature in 1.2.4 that doesn't break back-compat. So no need to go to 1.3.0. Giving me 1.2.0 when i want this new feature is no good.

And with regard to how node manages its version number: I've already ranted about this in a number of places. In short its horrendously wrong and the version number provides no clue as to how big the change was, and Ryan needs to just admit he was wrong/change his mind about his '0.2 will be (more) stable API' statement. I'm aware that I seem to be the only one who cares about this - but it's all about who can shout the loudest, right? ;)

I don't nave any problems with having relational operators (tho I'd prefer to not have to do string parsing to pull the stuff out) -- I just think the default should be a semver-like "x.y.z" means ">= x.y.z && < (x+1)".

"module": [ "==", "1.2.3" ]
"module": { "==": "1.2.3" }
"module": [ ">=": "1.2.3", "<", "2"]

Is relying on implicit ordering of {} asking for trouble? Dos ordering even matter?

-ash

Isaac Z. Schlueter

unread,
Mar 24, 2010, 1:54:10 PM3/24/10
to CommonJS
On Mar 24, 5:00 am, Ash Berlin <ash_flusspf...@firemirror.com> wrote:
> Then you read it wrong. Someone adds a new feature in
> 1.2.4 that doesn't break back-compat.
Unless adding that feature changed the behavior of something that
depended on that feature being absent.

Semver's semantics are great for expressing intention, and people
should use them to express their intentions. But wishes don't build
bridges. Relying on version semantics puts the decision in the wrong
hands. Now, if I push a new minor version of my package, I might be
responsible for breaking your stuff; if the versions are explicit,
then it's your responsibility to make sure your stuff continues to
work.

> And with regard to how node manages its version number: I've already ranted
> about this in a number of places. In short its horrendously wrong and the version
> number provides no clue as to how big the change was, and Ryan needs to just
> admit he was wrong/change his mind about his '0.2 will be (more) stable API'
> statement.

He has admitted that it was a mistake, at least twice in IRC, and I
believe on the mailing list as well, but I don't have a link. The
problem is that a lot of people saw the jsconf.eu vid, and expect
0.2.0 to be stable, so that's where we're at.

But yes, "stable API" is the job for a 1.0.0, not a 0.2.0. Shame on
Ryan for making an off-the-cuff comment while being videotaped. But
node is hardly the only project to violate the rules of semver.

> I don't nave any problems with having relational operators (tho I'd prefer to
> not have to do string parsing to pull the stuff out)

> "module": [ "==", "1.2.3" ]
> "module": { "==": "1.2.3" }
> "module": [ ">=": "1.2.3", "<", "2"]
>
> Is relying on implicit ordering of {} asking for trouble? Dos ordering even matter?

No, ordering doesn't matter, because all conditions must pass, and &&
is commutative. I'm cool with this:

"foo" : { ">=" : "1.2.3", "<" : "2.0.0" }

as long as we specify that all version keys must be semver, and that
"foo":"1.2.3" is equivalent to "foo":{"=":"1.2.3"}. npm will crash if
it sees "1.2", and the js-registry won't let you publish a weirdo
monkeyversion like that.

The string parsing is pretty simple, though. It allows specifying a
range like "1.0.2 - 2.3.4". If you strip the tests out, it's only
about 75 lines of JS:
http://github.com/isaacs/npm/blob/master/lib/utils/semver.js

--i

Zachary Carter

unread,
Mar 24, 2010, 2:03:43 PM3/24/10
to comm...@googlegroups.com
On Wed, Mar 24, 2010 at 1:54 PM, Isaac Z. Schlueter <i...@foohack.com> wrote:
But yes, "stable API" is the job for a 1.0.0, not a 0.2.0.  Shame on
Ryan for making an off-the-cuff comment while being videotaped.  But
node is hardly the only project to violate the rules of semver.
 
Just to be clear, semver makes no conjectures about an API before it reaches 1.0, so there are no rules being violated here (or with other projects before 1.0).

--
Zach Carter

Kris Kowal

unread,
Mar 24, 2010, 3:35:32 PM3/24/10
to comm...@googlegroups.com
I don't mind using the version notation Isaac's proposing, and I don't
mind parsing it. My only concern, and one I don't require this list
to ameliorate, is that it will be an alarming O(!!!) algorithm to
properly find the most recent internally consistent group of packages
from a catalog with a version history. I'm okay with going along for
the ride, but version control Hell is just around the corner.

Kris Kowal

Christoph Dorn

unread,
Mar 24, 2010, 3:49:58 PM3/24/10
to comm...@googlegroups.com
Isaac Z. Schlueter wrote:
>> On Tue, Mar 23, 2010 at 9:40 PM, Mikeal Rogers <mikeal.rog...@gmail.com>wrote:
>>> I read this as:
>>> 1.2.4 === (install 1.2.4 and use 1.24, no other version)
>>> 1.2 === (install 1.2.x at the highest available version, use best available
>>> version)
>>> Which has the somewhat confusing impact of meaning that in definition
>>> terms:
>>> 1.2.0 !== 1.2
>>> This does NOT allow anyone to do ranges between 1.1 and 1.4, but if the
>>> intention is to encourage people to use proper semver then I'm all for it. I
>>> think there are some rough edges, and a few things that can't actually be
>>> defined in this scheme that are useful (a bug was fixed in 1.3.4 that I step
>>> on, I'd like 1.3.4 or newer) but it's all about tradeoffs.
>
> These are all great points, and all the more reason why we should just
> use the extra characters and make package maintainers specific exactly
> what they want, rather than having any non-obvious implications that
> leave room for guesswork.
>
> Let's be less clever.

Please consider the following in relation to adopting semver without
range qualifiers:

* At the time of publishing the package you only know for sure what
versions work based on the versions you have tested. Thus you can
reliably specify the mimimum version you know works. Specifying a range
into the future is a prediction.

* We don't want to have to re-publish a package to update the version
range of a dependency.

* The norm in a stable package ecosystem is backwards compatibility
and with a community that desires compatibility I think semver is a
great choice. I do see that semvers < 1 pose a bit of a problem here as
we cannot break the API for minor versions. One solution would be to
extend semver and state that for versions < 1 the API compatibility is
based on the minor version to allow more iteration with the same
benefits until 1.0 is reached.

* Dud versions of dependencies should be fixed and re-released
(according to semver) or dropped from the distribution system to never
make it to the package installer. Everyone will have the same issue with
the dependency so it is in everyone's interest for this to happen.

* The fewer different versions of packages run in a system the better.
Semver the way we have it specified ensures everyone is always using the
latest versions with all the latest security fixes etc... CommonJS
modules are singletons. If you want to share data this way everyone
using that module as a dependency must get the same version. Having the
runtime do magic in computing a compatible version for everyone to use
is less ideal. Relying on the semver major version to attach the
singleton is a convention you can code against reliably.

* There will be two types of CommonJS packages. System and
using-packages (or whatever they will be called). System packages are
tightly coupled with the runtime and should only be installed once and
at the most one version per major API version. Using-packages are used
to compose programs where packages can share the same dependencies and
want to share objects between each other's modules. When two packages
declare dependency on versions 1.3.4 and 1.6.7 you need to get version
1.6.7 modules from both packages to be able to share objects with the
latest/same API.

Introducing version ranges because of fear, prior art or comfort would
be a huge mistake I believe. I think we owe it to ourselves to explore
an ecosystem that treats backwards compatibility and a consistent
versioning story as a fundamental principle to make all our lives
easier. If we do discover we need more control I would like to see other
solution be entertained than reverting back to version ranges which are
in many cases incorrect as soon as the package is published.

>>> Yeah, i don't know any JSON database that currently reserves "id" but it
>>> seems like it would be good to reserve it just in case.
>
> Dude, the js-registry we wrote has that and npm is using it :P
>
> @kriskowal
> Sure, overlay works, too. I'll add that to the list of extender keys
> npm is aware of.


We have a property called "implements" that I have been using for a lot
more than what is currently specified.

package.json ~ {
"implements": {
"<string>": {
}
}
}

Where <string> can be sectioned names or URLs pointing to a JSON
schemas, namespace identifiers or anything else. It provides a way to
include extra meta data in a way that does not interfere with common
properties. I would like to see extra properties added this way. It
makes it very easy to see what extensions each system makes and how
these can be combined to form additional standards. If "implements" is
the wrong property name let's change that or add an additional property.

Christoph

Ash Berlin

unread,
Mar 24, 2010, 7:19:36 PM3/24/10
to comm...@googlegroups.com

The above matches my views and expectations exactly, and is better written than I could manage. I also thing the extension for major-ver < 1 makes sense and can be adopted/encouraged irrespective of what *projects* do for modules.

-ash


Charles Jolley

unread,
Mar 24, 2010, 7:35:42 PM3/24/10
to comm...@googlegroups.com
I wonder if part of the semver confusion could be alleviated with better tools. For example, if the package manager did:

seed push --patch > bumps patch number
seed push --feature > bumps minor version
seed push --incompatible > bumps major version

then it would help to guarantee that semver is respected. Also, package managers should not allow a particular version of a package to be uploaded more than once.

-Charles

Kris Kowal

unread,
Mar 24, 2010, 7:38:41 PM3/24/10
to comm...@googlegroups.com
On Wed, Mar 24, 2010 at 4:35 PM, Charles Jolley <cha...@sproutit.com> wrote:
> I wonder if part of the semver confusion could be alleviated with better tools.  For example, if the package manager did:
>
> seed push --patch  > bumps patch number
> seed push --feature > bumps minor version
> seed push --incompatible > bumps major version
>
> then it would help to guarantee that semver is respected.  Also, package managers should not allow a particular version of a package to be uploaded more than once.

I *really* like this idea.

Kris Kowal

Mikeal Rogers

unread,
Mar 24, 2010, 7:41:12 PM3/24/10
to comm...@googlegroups.com
I have been think about this with npm + js-registry, something like a tag-and-release directive that.

- updates version
- commits
- tags
- pushes tag
- pushes release to js-registry
- marks version as stable in js-registry

-Mikeal

Daniel Friesen

unread,
Mar 24, 2010, 10:30:33 PM3/24/10
to comm...@googlegroups.com
And if the package is of a pre-existing library ported to CommonJS which
has it's own version numbers?

~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]

Christoph Dorn

unread,
Mar 25, 2010, 3:23:54 AM3/25/10
to comm...@googlegroups.com
Daniel Friesen wrote:
> And if the package is of a pre-existing library ported to CommonJS which
> has it's own version numbers?

I think you try and map them as best as you can after you have
identified where in their versioning scheme backwards compatibility is
broken.

Existing users of the library may be used to specifying versions but
users coming from a semver perspective will expect to be able to code
against a major version API that grows over time without breaking
backwards compatibility.

Christoph

Daniel Friesen

unread,
Mar 25, 2010, 4:57:02 AM3/25/10
to comm...@googlegroups.com
Christoph Dorn wrote:
> Daniel Friesen wrote:
>> And if the package is of a pre-existing library ported to CommonJS
>> which has it's own version numbers?
>
> I think you try and map them as best as you can after you have
> identified where in their versioning scheme backwards compatibility is
> broken.
>
> Existing users of the library may be used to specifying versions but
> users coming from a semver perspective will expect to be able to code
> against a major version API that grows over time without breaking
> backwards compatibility.
>
> Christoph
Except a good large number of users are probably NOT coming from a
semver perspective. And maintaining two conflicting sets of versions
does little but cause confusion and convolutes using existing
documentation that refers to the versioning that the source library uses.

Semantic Versioning support is a nice feature, and it's a nice thing to
encourage developers to consider migrating to it. But mandating that
external software MUST follow semver, or forcing a conflicting version
scheme is not the right way to encourage people to adopt semver. ((Would
the right analogy here be something like "You catch more bulls with a
red cloth than with a club"?))

I'll flow with anything that encourages things like semver, and +1
anything that makes good ideals convenient (be it shortcuts that make
specifying a SemVer simpler than specifying other vers, or tools that
make it easier to publish your own stuff using semver), but if I see
anything that arbitrarily forces external things into one mold, or is at
odds with existing reasonable patterns, I'll come up with some
non-portable extension or alternative that will give users a choice to
what they find reasonable. After all, my design already floats around
support for both require/exports and classic load style code.

Frankly I'm not entirely bought on Semantic Versioning. It could be
nice, it's probably a good ideal. But I don't like blindly rushing into
something this young and mandating it as the only tool.
So far the only info I found on SemVer is the spec (which is in it's
closed off world), the usual slew of mad blog posts pointing to
something new and interesting, and this post
http://rwec.co.uk/blog/2010/02/golden-rules-of-version-naming/ CommonJS
has been hyped, debated, cross-referenced, examined, and spoken about by
multiple sides of the line more than SemVer has, and CommonJS is even
still young at that.

((I'm standing on both sides of the line... I wonder if I should make
the thoughts from the other side of the line more publicly available))

Zachary Carter

unread,
Mar 25, 2010, 10:53:25 AM3/25/10
to comm...@googlegroups.com


On Thu, Mar 25, 2010 at 4:57 AM, Daniel Friesen <nadir.s...@gmail.com> wrote:
....
Frankly I'm not entirely bought on Semantic Versioning. It could be nice, it's probably a good ideal. But I don't like blindly rushing into something this young and mandating it as the only tool.
So far the only info I found on SemVer is the spec (which is in it's closed off world), the usual slew of mad blog posts pointing to something new and interesting, and this post http://rwec.co.uk/blog/2010/02/golden-rules-of-version-naming/


Actually, SemVer is not new. There are many other schemes that are almost identical and have been in wide use[1]. 


--
Zach Carter

Christoph Dorn

unread,
Mar 25, 2010, 1:11:30 PM3/25/10
to comm...@googlegroups.com
Daniel Friesen wrote:
> Christoph Dorn wrote:
>> Daniel Friesen wrote:
>>> And if the package is of a pre-existing library ported to CommonJS
>>> which has it's own version numbers?
>>
>> I think you try and map them as best as you can after you have
>> identified where in their versioning scheme backwards compatibility is
>> broken.
>>
>> Existing users of the library may be used to specifying versions but
>> users coming from a semver perspective will expect to be able to code
>> against a major version API that grows over time without breaking
>> backwards compatibility.
>>
> Except a good large number of users are probably NOT coming from a
> semver perspective. And maintaining two conflicting sets of versions
> does little but cause confusion and convolutes using existing
> documentation that refers to the versioning that the source library uses.

I don't see semver as conflicting with any other versioning scheme. All
projects grow and get more mature and their versions follow. The only
difference I see is that semver versions may increment faster to follow
the strict conventions and that dependencies are specified via min semver.

As for documentation, when you specify a dependency via semver you
simply look at the latest documentation available assuming the port of
the library you are using is actively maintained.


> Semantic Versioning support is a nice feature, and it's a nice thing to
> encourage developers to consider migrating to it. But mandating that
> external software MUST follow semver, or forcing a conflicting version
> scheme is not the right way to encourage people to adopt semver. ((Would
> the right analogy here be something like "You catch more bulls with a
> red cloth than with a club"?))

External software does not need to follow semver. If by external you
mean libraries that need porting, the port will do the version mapping
if it is not a one to one. The important think to remember is that once
you use semver and declare your dependencies that way you can forget
about minor and patch versions unless you are working on the edge.


> I'll flow with anything that encourages things like semver, and +1
> anything that makes good ideals convenient (be it shortcuts that make
> specifying a SemVer simpler than specifying other vers, or tools that
> make it easier to publish your own stuff using semver), but if I see
> anything that arbitrarily forces external things into one mold, or is at
> odds with existing reasonable patterns, I'll come up with some

I don't see it as forcing. As part of the port of the library you port
the code and map the versioning schemes. Nobody cares except for the
community following semver which will embrace the port because it
seamlessly plugs into an ecosystem of packages.

How is semver at odds with reasonable patterns?


> non-portable extension or alternative that will give users a choice to
> what they find reasonable. After all, my design already floats around
> support for both require/exports and classic load style code.
>
> Frankly I'm not entirely bought on Semantic Versioning. It could be
> nice, it's probably a good ideal. But I don't like blindly rushing into
> something this young and mandating it as the only tool.
> So far the only info I found on SemVer is the spec (which is in it's
> closed off world), the usual slew of mad blog posts pointing to
> something new and interesting, and this post
> http://rwec.co.uk/blog/2010/02/golden-rules-of-version-naming/ CommonJS
> has been hyped, debated, cross-referenced, examined, and spoken about by
> multiple sides of the line more than SemVer has, and CommonJS is even
> still young at that.

The core conventions behind semver have been in use by many schemes in
some form or another for a long time. Semver simply condenses and
specifies these to encourage wider adoption.

We can add to semver to fix holes (by adding "=" for instance) but we
can never go from specifying version ranges to semver. So I say start
with semver and add what is missing than forgo all the benefits it
provides in fear that some people will be alienated.

Christoph

Reply all
Reply to author
Forward
0 new messages