So, there are two topics here that are both very interesting, in my opinion.

1. When publishing an app, you should freeze your dependencies to
something that you know works.  In varying degrees of frozenness, that
can be done via: a) checking node_modules into git, b) using npm
shrinkwrap, c) depending on explicit version numbers rather than
ranges.

However, when publishing a library or utility that depends on other
utilities and libraries, depending on explicit version numbers is
rather obnoxious.  It makes it harder than necessary to take in
bug-fixes.  Some packages are updated quite frequently to add minor
things in very safe ways that do not affect the api.

For example, the `mime` package gets a new version bump for each
mime-type that is added.  If your library depends on the api, but it
is unlikely that a new mime type will break your library, then fixing
the patch version is annoying.  Now, if I want to use your library,
and I need support for a mime-type that was added after you published,
I have to manually edit your package.json to loosen the constraint,
send you a pull request, wait for you to push an update, and then pull
in your update later maybe.  It adds ceremony and complexity.  Your
app isn't "about" mime-types, so having to push updates to support new
mime types is not the correct separation of concerns.

Dependency fixing should be done at the highest app level, not at the
library/util level.  Library modules should be as broad as is
"reasonable", and the value of "reasonable" is dependent on context
(see below.)

This has been our experience so far, and I haven't yet seen any
significant exceptions to that rule.


2. There are open questions about exactly what semantics we're meaning
to communicate with our semantic versions.

At the rudimentary level, package versions must be parseable by the
node semver package.  In other words, npm package versions must be
version numbers complying with the npm package version scheme,
parseable by the npm package version parser.  (The first rule of
taugology club is the first rule of tautology club...)  There are some
ideas about what *should* be communicated with our semantic versions.
One interesting model is that proposed by semver.org, but it's clearly
not the only thing that can be implied.

npm itself gives you the tools to communicate using version numbers,
but it does not stipulate what that communication must be, except to
specify the ordering of version numbers, and some special syntax for
specifying ranges of acceptable versions.  That's it.

For some authors, 0.x means "I am going to break this thing, don't
rely on it."  For others, 0.0.x means that, but 0.1.x means "You can
rely on this, at least up to 0.2.x", and for others, it means "You can
rely on this, at least up to 1.x."  In node-core, 0.x means "unstable"
if x%2, and I don't know of any npm package that uses that pattern.

Ultimately, using someone else's code is a bond of trust between you
and them.  You need to learn their mind a little bit.  You need to
read their docs, run their tests, and probably will end up fixing some
of their bugs.  Part of this process is accepting that their
versioning scheme might not be 100% the same as yours, or that they
might make a mistake (gosh!) and publish a change that violates their
own versioning pattern in some unexpected way.

Part of the problem here is that we're not the borg, and we don't all
think the same.  When faced with semantic ambiguities, some nerds
think, "I know, I'll use a specification!"  I'd tell you how many
problems you'd now have, but the specification for how to count
problems is ambiguous.

In this case, I think it's best to just admit that what's best for one
package might not be best for another.  Evaluating dependencies is
part of the craft of making software.  You can't solve this problem
with math.  (Or at least, trying to solve it with math thus far has
been unsuccessful, and is probably more work than just using your
human brain to figure out which version to use, or what range is
acceptable.)

For what it's worth, here's the scheme I use in my packages:

1. If there's a major architecture/semantic change in program
behavior, almost certain to break programs using it today, then bump
the major version.  (Ie, npm 0.x to npm 1.x.)
2. If there's a potentially breaking api change, which is likely to be
safe for most users, and doesn't change the nature of the program too
considerably, then bump the minor version.
3. Any other change, bugfix, etc., bump the patch version.

Other perfectly valid schemes:

1. Bump the major when any breaking API change is made.
2. Bump the minor when any API change at all is made.
3. Bump the patch when any API-compatible change is made.

1. Bump the major when there is an API change.
2. Bump the minor when a bug is fixed that touches any underlying code.
3. Bump the patch when a new data record is added.  (Ie, in the mime
case above.)

1. Bump the major from 0 to 1 when it's considered feature complete,
and again for major re-architectures.
2. Bump the minor from 0 to 1 when it's passing tests, and again for
any API changes.
3. Bump the patch for API additions prior to 0.1.x, and for bugfixes after.
4. Bump the build for bugfixes prior to 0.1.x, and never again afterwards.

The possibilities are endless.

Culturally, node is the sort of place where those in power try to
dictate as little as necessary.  Semantics are something that come out
of communication, not something that ought to be injected into it.

What I've observed in practice, and what we've made the default for
the `--save` behavior in npm, is that people tend to be a bit
suspicious of 0.0.x packages -- if it works, great, but I don't trust
that 0.0.x+1 will still work -- and are a bit more trusting of
versions >=0.1.0.  So, when you do `--save` or `--save-dev` in npm,
it'll put the ~ in front of versions that don't start with 0.0.


The point of Austin's OP, which some have echoed in this thread,
seemed to be: "Starting with a 0 is not a license to publish bugs."  I
agree with him, but in the other direction ;)  You don't need a
license to publish bugs.  Just change the version number, and it's a
different thing, go crazy.  Publish all the bugs you want.

However, recognize that your credibility suffers, and that the bond
between author and user is a bond of trust, so taking it lightly will
lead to you losing face in the hearts and minds of your peers.
Reputations are long-lived, and can have social and financial
consequences long into the future.  So, it's in your best interest to
try to be responsible, and do your best to communicate where a project
is in its development.  If 0.x means "This is going to break
repeatedly", well, ok... you should probably also mention that in the
readme.  There's certainly nothing wrong with experimentation, but
people tend to get upset when they're surprised.


On Thu, Sep 20, 2012 at 6:51 PM, Alan Gutierrez <[email protected]> wrote:
> On 9/20/12 2:30 PM, Scott González wrote:
>>
>> On Thu, Sep 20, 2012 at 2:27 PM, Austin William Wright
>> <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>>     The problem comes in when I or other developers want to /use/ those
>>
>>     libraries, and keep them up-to-date. You can't use features like "~1".
>>
>>
>> You know when you're using a module that's in a 0.x release cycle, so
>> just use ~0.y.z and you'll be fine.
>
>
> While I'm developing a library, I use 0.0.x as pre-release, where API
> breaking updates occur at every revision. From Timezone:
>
> "On the 0.0.x branch, API changes may break applications. Please use an
> absolute version number in your package.json to hold onto a version Timezone
> that works for you. When 0.0.x development is done, I'll create an 0.2.0
> branch for application use and a 0.1.0 for any further development. The
> 0.2.0 branch will be an API freeze."
>
> https://github.com/bigeasy/timezone/issues/41
>
> So, like Scott says, but with no tilde. Each upgrade requires your
> attention.
>
> Thus, I'm not following the semvar document, but I'm adhering to the notion
> that semvar helps you manage API instabilities, documenting my reasoning.
>
> 0.0.x is pre-release for the intrepid.
>
> --
> Alan Gutierrez - http://github.com/bigeasy - http://twitter.com/bigeasy
>
>
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to