HaxeFoundation / haxelib

The Haxe library manager
https://lib.haxe.org/
MIT License
173 stars 77 forks source link

Look into using mancoosi research for versioning and dependency solving #290

Open nadako opened 8 years ago

nadako commented 8 years ago

As noted by @ousado, OCaml's OPAM uses pretty smart dependency solver based on Mancoosi scientific research project and we can look into using it for managing haxelib repositories.

ibilon commented 8 years ago

The problem is non-haxelib package like git #238 which we can't reason about since we don't have their haxelib.json.

That aside we'd need a cache of all the lib/version to do that in the client, otherwise that'd use a lot of bandwidth.

nadako commented 8 years ago

The problem is non-haxelib package like git #238 which we can't reason about since we don't have their haxelib.json.

OPAM deals with these via separate pin command which we also could look into: https://opam.ocaml.org/doc/Usage.html#opampin

That aside we'd need a cache of all the lib/version to do that in the client, otherwise that'd use a lot of bandwidth.

Yeah, that how it's done in many package managers like APT, OPAM, Homebrew. Another option would be to use to use could-based dependency solving (there are solver farms even: http://cudf-solvers.irill.org/index.html)

nadako commented 8 years ago

The pinning mechanism doesn't play well with our planned git dependencies however, in fact it's similar to what we have now with devmode vcs checkouts :)

ibilon commented 8 years ago

OPAM deals with these via separate pin command which we also could look into: https://opam.ocaml.org/doc/Usage.html#opampin

That's taking into account the dev versions, or any lib that's installed locally, but I was referring to having a git dependency in haxelib.json in a haxelib package

depends should be a list of existing OPAM package names that your package relies on to build and run. OPAM doesn't allow that, because if you don't know the complete recursive dependency list you can't reason on it.

I think we have, luckily, a simpler problem since we can install multiple versions of the same library, so we may not need a state of the art sat solver or something.

nadako commented 8 years ago

I think we have, luckily, a simpler problem since we can install multiple versions of the same library, so we may not need a state of the art sat solver or something.

Hmm, you're right about that

ibilon commented 8 years ago

I did a small code using the constraint programming solver or-tools https://gist.github.com/ibilon/30acc1107f4dc95912a1 (not 100% finish, there's no semver compare code, but that's only used find an optimal solution and the example only has one solution)

Here the example is wanting to install ufront 2.0.0, the file is constructed by recursively listing a library version and its dependencies, or all versions if no version is specified.

Output:

Dependencies required to install ufront 2.0.0 :
 * ufront-mvc 1.1.0
 * ufront-orm 1.1.0
 * ufront-easyauth 1.0.0
 * compiletime 2.6.0
 * minject 2.0.0-rc.1
 * tink_core 1.0.0-rc.11
 * tink_macro 0.6.4
 * PBKDF2 1.0.0
Time to compute: 0 s

All are fixed but tink_core, which was set to 1.0.0-rc.11 by the solver.

Current haxelib would also install 1.0.0-rc.12 as well because tink_macro as "tink_core": "" as dependency.

We shouldn't use as is but that'd be a cool feature to have, especially if we add a --conservative option to install, the objective function can easily be changed to maximize the use of already installed versions (and limit new version installation).

Also the solver can easily use range (>=1.2.0 && <1.3.0) instead of a specific version as dependency, or any set (1.1.0 || (>=1.2.0 && <1.3.0) || 1.5.3 || >=1.6.0) actually. (would just need to change the dependency constraint: add all valid versions to the sum and change from the cardinality of versions to the number of different lib)