RejectedSoftware Forums

Sign up

Pages: 1 2 3

Improving the ~branch vs. vX.Y.Z version situation

DUB supports two kinds of schemata for selecting package versions:

  1. SemVer based version identifiers (e.g. ">=1.0.0")
  2. Selection of a specific branch HEAD using the "~" prefix (e.g. "~master")

The rationale for supporting the latter is improving the situation for library developers. In particular it allows library developers to have their library checked out locally and be able to make and commit changes to the library while testing those changes in the context of a separate application package. Usually this would require making a new version tag for each change, which is not really practical. By referencing a certain branch of the library instead, this isn't necessary and development can happen nicely without unnecessary overhead. So far, so good.

However, all this has some unfortunate side effects. First, due to laziness or missing awareness many packages in the registry have no version tags at all, and, partially because of that, many public packages reference their dependencies by branch instead of by version. What this means is that any change on a branch of such a package can break an unknown amount of external code with no possibility for external packages to at least stay at a particular working commit.

The second issue is that this is prone to introducing version conflicts. If some library A correctly references library B by version (say >=1.0.3) and now the developer wants to develop library B in the context of some application A. To do so, application A, which also uses library A, references library B as ~master and the developer checks out the git repository of B and calls dub add-local on it. But now there is a conflict that generally cannot be easily or unambiguously resolved. Should the branch or the version constraint have precedence? Should this work for just ~master or any branch? What happens with >=1.0.0 vs. a ~2.0.x branch? There are arguments for and against either way - but no solution we encountered so far was ideal.

What finally occurred to us was the following simple, radical solution:

  1. Deprecate ~branch style dependencies and at some point finally completely remove support for them
  2. From now on, accept only packages for the registry if they contain at least a single version tag
  3. To still properly support development, allow the developer to override locally that a branch should be used for certain packages instead of the tagged version that would usually be used (either system globally for all projects, or on a per project basis)

Obligatory quote: Destroy!

Re: Improving the ~branch vs. vX.Y.Z version situation

On Wed, 12 Feb 2014 13:01:43 GMT, Sönke Ludwig wrote:

DUB supports two kinds of schemata for selecting package versions:

  1. SemVer based version identifiers (e.g. ">=1.0.0")
  2. Selection of a specific branch HEAD using the "~" prefix (e.g. "~master")

The rationale for supporting the latter is improving the situation for library developers. In particular it allows library developers to have their library checked out locally and be able to make and commit changes to the library while testing those changes in the context of a separate application package. Usually this would require making a new version tag for each change, which is not really practical. By referencing a certain branch of the library instead, this isn't necessary and development can happen nicely without unnecessary overhead. So far, so good.

However, all this has some unfortunate side effects. First, due to laziness or missing awareness many packages in the registry have no version tags at all, and, partially because of that, many public packages reference their dependencies by branch instead of by version. What this means is that any change on a branch of such a package can break an unknown amount of external code with no possibility for external packages to at least stay at a particular working commit.

The second issue is that this is prone to introducing version conflicts. If some library A correctly references library B by version (say >=1.0.3) and now the developer wants to develop library B in the context of some application A. To do so, application A, which also uses library A, references library B as ~master and the developer checks out the git repository of B and calls dub add-local on it. But now there is a conflict that generally cannot be easily or unambiguously resolved. Should the branch or the version constraint have precedence? Should this work for just ~master or any branch? What happens with >=1.0.0 vs. a ~2.0.x branch? There are arguments for and against either way - but no solution we encountered so far was ideal.

What finally occurred to us was the following simple, radical solution:

  1. Deprecate ~branch style dependencies and at some point finally completely remove support for them
  2. From now on, accept only packages for the registry if they contain at least a single version tag
  3. To still properly support development, allow the developer to override locally that a branch should be used for certain packages instead of the tagged version that would usually be used (either system globally for all projects, or on a per project basis)

Please elaborate more, how would this be formulated in the dub.json? "Local" means it would just work for packages that I fork/download and have locally on my machine or would dub still be able to fetch it?

Obligatory quote: Destroy!

All in all it sounds good to me.

Re: Improving the ~branch vs. vX.Y.Z version situation

Am 12.02.2014 14:45, schrieb Stephan Dilly:

On Wed, 12 Feb 2014 13:01:43 GMT, Sönke Ludwig wrote:

  1. Deprecate ~branch style dependencies and at some point finally completely remove support for them
  2. From now on, accept only packages for the registry if they contain at least a single version tag
  3. To still properly support development, allow the developer to override locally that a branch should be used for certain packages instead of the tagged version that would usually be used (either system globally for all projects, or on a per project basis)

Please elaborate more, how would this be formulated in the dub.json? "Local" means it would just work for packages that I fork/download and have locally on my machine or would dub still be able to fetch it?

The current idea is to store a mapping in either
~/.dub/local-packages.json or in .dub/branch-map.json of each package
(exact naming subject to change). Those files would contain something
along the lines of either:

{
   "vibe-d": "~master",
   "ddox": "~2.0"
}

or with the possibility to be more precise like this:

[
   {
     "package": "vibe-d",
     "version": ">=0.7.18",
     "branch": "~master"
   },
   {
     "package": "ddox",
     "version": ">=2.0.0 <3.0.0",
     "branch": "~2.0"
   }
]

That and the CLI that controls this still needs to be worked out.

But the dub.json/package.json of each package wouldn't be affected as
per the current plan. But thinking about it, there would be another
possible way that provides a little less flexibility in what can be
overridden, but avoids duplicate setup work in case of multiple
developers. For that idea, the dependencies in the package description
could be written like this:

{
   "name": "somepack",
   "dependencies": {
     "vibe-d": {
       "version": ">=0.7.18",
       "branch": "~master"
     }
   }
}

If the user then has vibe-d checked out on master, DUB would use that.
Without the "branch" entry, it would always use a tagged version.

Thoughts?

Re: Improving the ~branch vs. vX.Y.Z version situation

On 2014-02-12 14:01, Sönke Ludwig wrote:

DUB supports two kinds of schemata for selecting package versions:

  1. SemVer based version identifiers (e.g. ">=1.0.0")
  2. Selection of a specific branch HEAD using the "~" prefix (e.g. "~master")

The rationale for supporting the latter is improving the situation for library developers. In particular it allows library developers to have their library checked out locally and be able to make and commit changes to the library while testing those changes in the context of a separate application package. Usually this would require making a new version tag for each change, which is not really practical. By referencing a certain branch of the library instead, this isn't necessary and development can happen nicely without unnecessary overhead. So far, so good.

However, all this has some unfortunate side effects. First, due to laziness or missing awareness many packages in the registry have no version tags at all, and, partially because of that, many public packages reference their dependencies by branch instead of by version. What this means is that any change on a branch of such a package can break an unknown amount of external code with no possibility for external packages to at least stay at a particular working commit.

The second issue is that this is prone to introducing version conflicts. If some library A correctly references library B by version (say >=1.0.3) and now the developer wants to develop library B in the context of some application A. To do so, application A, which also uses library A, references library B as ~master and the developer checks out the git repository of B and calls dub add-local on it. But now there is a conflict that generally cannot be easily or unambiguously resolved. Should the branch or the version constraint have precedence? Should this work for just ~master or any branch? What happens with >=1.0.0 vs. a ~2.0.x branch? There are arguments for and against either way - but no solution we encountered so far was ideal.

What finally occurred to us was the following simple, radical solution:

  1. Deprecate ~branch style dependencies and at some point finally completely remove support for them
  2. From now on, accept only packages for the registry if they contain at least a single version tag

Finally.

  1. To still properly support development, allow the developer to override locally that a branch should be used for certain packages instead of the tagged version that would usually be used (either system globally for all projects, or on a per project basis)

Obligatory quote: Destroy!

Personally I would just allow to specify a git repository. A couple of
options would be good like, hash, branch and so on.

/Jacob Carlborg

Re: Improving the ~branch vs. vX.Y.Z version situation

Am 12.02.2014 21:20, schrieb Jacob Carlborg:

On 2014-02-12 14:01, Sönke Ludwig wrote:

DUB supports two kinds of schemata for selecting package versions:

  1. SemVer based version identifiers (e.g. ">=1.0.0")
  2. Selection of a specific branch HEAD using the "~" prefix (e.g.
    "~master")

The rationale for supporting the latter is improving the situation for
library developers. In particular it allows library developers to have
their library checked out locally and be able to make and commit
changes to the library while testing those changes in the context of a
separate application package. Usually this would require making a new
version tag for each change, which is not really practical. By
referencing a certain branch of the library instead, this isn't
necessary and development can happen nicely without unnecessary
overhead. So far, so good.

However, all this has some unfortunate side effects. First, due to
laziness or missing awareness many packages in the registry have no
version tags at all, and, partially because of that, many public
packages reference their dependencies by branch instead of by version.
What this means is that any change on a branch of such a package can
break an unknown amount of external code with no possibility for
external packages to at least stay at a particular working commit.

The second issue is that this is prone to introducing version
conflicts. If some library A correctly references library B by version
(say >=1.0.3) and now the developer wants to develop library B in
the context of some application A. To do so, application A, which also
uses library A, references library B as ~master and the developer
checks out the git repository of B and calls dub add-local on it.
But now there is a conflict that generally cannot be easily or
unambiguously resolved. Should the branch or the version constraint
have precedence? Should this work for just ~master or any branch?
What happens with >=1.0.0 vs. a ~2.0.x branch? There are arguments
for and against either way - but no solution we encountered so far was
ideal.

What finally occurred to us was the following simple, radical solution:

  1. Deprecate ~branch style dependencies and at some point finally
    completely remove support for them
  2. From now on, accept only packages for the registry if they contain
    at least a single version tag

Finally.

I knew you would be happy to hear that ;)

Yeah, what was missing so far was really just a better alternative. It
took quite a while to switch to a different mindset to get to this
alternative solution.

  1. To still properly support development, allow the developer to
    override locally that a branch should be used for certain packages
    instead of the tagged version that would usually be used (either
    system globally for all projects, or on a per project basis)

Obligatory quote: Destroy!

Personally I would just allow to specify a git repository. A couple of
options would be good like, hash, branch and so on.

Or a path to a cloned git repository where the developer can check out
and branch/revision that fits?

Re: Improving the ~branch vs. vX.Y.Z version situation

Am 12.02.2014 17:05, schrieb Sönke Ludwig:

But the dub.json/package.json of each package wouldn't be affected as
per the current plan. But thinking about it, there would be another
possible way that provides a little less flexibility in what can be
overridden, but avoids duplicate setup work in case of multiple
developers. For that idea, the dependencies in the package description
could be written like this:

{
   "name": "somepack",
   "dependencies": {
     "vibe-d": {
       "version": ">=0.7.18",
       "branch": "~master"
     }
   }
}

If the user then has vibe-d checked out on master, DUB would use that.
Without the "branch" entry, it would always use a tagged version.

Thoughts?

Okay, this has the drawback of being less flexible. For example, if a
new feature is to be developed in a new feature branch, then the setting
in the dub.json would get in the way.

Re: Improving the ~branch vs. vX.Y.Z version situation

On 2014-02-12 21:38, Sönke Ludwig wrote:

Or a path to a cloned git repository where the developer can check out
and branch/revision that fits?

Well, git can clone both remote repositories and local ones from the
file system. I don't see the point in needing to limit that.

/Jacob Carlborg

Re: Improving the ~branch vs. vX.Y.Z version situation

Am 13.02.2014 21:23, schrieb Jacob Carlborg:

On 2014-02-12 21:38, Sönke Ludwig wrote:

Or a path to a cloned git repository where the developer can check out
and branch/revision that fits?

Well, git can clone both remote repositories and local ones from the
file system. I don't see the point in needing to limit that.

I mean a path to a cloned working copy, not a local "git remote". That
would avoid the burden for DUB to perform the clone/checkout, possibly
managing credentials etc. and provide full flexibility for the user. DUB
wouldn't even have to know what branch/tag is checked out and any VCS
would work.

Re: Improving the ~branch vs. vX.Y.Z version situation

On Wed, 12 Feb 2014 13:01:43 GMT, Sönke Ludwig wrote:

DUB supports two kinds of schemata for selecting package versions:

  1. SemVer based version identifiers (e.g. ">=1.0.0")
  2. Selection of a specific branch HEAD using the "~" prefix (e.g. "~master")

The rationale for supporting the latter is improving the situation for library developers. In particular it allows library developers to have their library checked out locally and be able to make and commit changes to the library while testing those changes in the context of a separate application package. Usually this would require making a new version tag for each change, which is not really practical. By referencing a certain branch of the library instead, this isn't necessary and development can happen nicely without unnecessary overhead. So far, so good.

However, all this has some unfortunate side effects. First, due to laziness or missing awareness many packages in the registry have no version tags at all, and, partially because of that, many public packages reference their dependencies by branch instead of by version. What this means is that any change on a branch of such a package can break an unknown amount of external code with no possibility for external packages to at least stay at a particular working commit.

The second issue is that this is prone to introducing version conflicts. If some library A correctly references library B by version (say >=1.0.3) and now the developer wants to develop library B in the context of some application A. To do so, application A, which also uses library A, references library B as ~master and the developer checks out the git repository of B and calls dub add-local on it. But now there is a conflict that generally cannot be easily or unambiguously resolved. Should the branch or the version constraint have precedence? Should this work for just ~master or any branch? What happens with >=1.0.0 vs. a ~2.0.x branch? There are arguments for and against either way - but no solution we encountered so far was ideal.

What finally occurred to us was the following simple, radical solution:

  1. Deprecate ~branch style dependencies and at some point finally completely remove support for them
  2. From now on, accept only packages for the registry if they contain at least a single version tag
  3. To still properly support development, allow the developer to override locally that a branch should be used for certain packages instead of the tagged version that would usually be used (either system globally for all projects, or on a per project basis)

Obligatory quote: Destroy!

Most of my packages (currently all) intentionally don't have versions because I don't consider them stable. If somebody adds them as a dependency he should know that (because there only ist the ~master version) it is not stable and can change without notice. That way I want to make sure nobody builds upon a (highly unstable) piece of code.

Once I get the feeling somebody can depend on this state of code without needing to change it to make it work, I add a version to the repository.

It's just the way I use this feature without any judgement.

Re: Improving the ~branch vs. vX.Y.Z version situation

On 2014-02-13 21:38, Sönke Ludwig wrote:

I mean a path to a cloned working copy, not a local "git remote".

Git can clone from a cloned working copy as well.

That would avoid the burden for DUB to perform the clone/checkout

Dub could of course check if it's a local path.

, possibly managing credentials etc. and provide full flexibility for the user.

Right.

DUB wouldn't even have to know what branch/tag is checked out and any VCS
would work.

Right. I'm not against supporting a local path but I think supporting
arbitrary git repositories would be nice as well. Bundler (a tool used
by Ruby projects) supports gems (which would correspond to a package in
the dub registry), git repositories and local file paths. It also
supports "shortcuts" for github repositories. When using a git
repository it will by default used the default branch.

/Jacob Carlborg

Pages: 1 2 3