Skip to content

Haxe haxec haxelib plan

Nicolas Cannasse edited this page May 20, 2020 · 16 revisions

(This is a preliminary plan for implementing a better libary versioning and resolution system.)

Overall structure

There are three executables, each with separate versioning.

  • haxe
  • haxec
  • haxelib

haxec (the backend)

The compiler itself is renamed to haxec. It behaves like the current compiler except that the following CLI arguments are deprecated:

  • -lib
  • --each
  • --next
  • --cwd

haxelib (the package manager)

The package manager still has the general functionality of the old manager when running in a directory without a scope (a warning may be emitted when installing globally?). It has the new command haxelib scope init.

It can also download, install, and select compiler versions (reserved haxelib package haxe?)

Haxelibs with a dev version haxelib dev lib ... take priority over any scope-resolved libraries.

Scope convention

The convention is a haxelib-lock.json file in a project directory (see below for minimal format).

Both haxe and haxelib can be asked to use a different scope with the --lock-file argument. In this case, the path provided overrides haxelib-lock.json, in the sense as both are used but the lock file can override some definition in haxelib-lock.json

Global override

It is possible to define a global override file (stored in HAXELIB_OVERRIDE_PATH, or if not defined $(HOME)/haxelib-global-lock.json). If present, this global override file takes precedence globally over all local files.

Uses cases:

  • test new library version on many projects without changing configuration
  • same with different haxe compiler version

haxe (the frontend)

The new default exectuable becomes haxe, replacing the functionality of Haxeshim. It is fairly simple and takes care of:

  • Scope management. It understands the scope convention, using it to resolve compiler versions and library versions. Scope can be overridden with --lock-file.
  • HXML parsing and normalisation. It can parse HXML files. --next and --each are parsed and result in separate calls to haxec. -lib is parsed and resolves to -D + -cp (+ optionally extra arguments) based on the scope convention. All paths are resolved to absolute paths. ${haxelib} paths are resolved.
  • Resolving the default haxec version, when one is not specified in the scope.
  • Allows the new scoping convention and CLI arguments to be used with older versions of haxe and haxelib.

It does NOT:

  • Take care of installing, downloading, or upgrading libraries or compiler versions.

The front end is also usable as a library, to allow embedding the logic of scope resolution into tools like vshaxe.

Front end detailed version

  • Reads haxelib-lock.json (if exists).
  • Reads <file> (if called with --lock-file <file>) which will partially override haxelib-lock.json.
  • Takes arguments (HXML files and regular arguments).
  • Expand HXML files to their actual content (resolve imports, parse out --next and --each).
  • Resolve -lib <name> into -cp <path> -D <name>=<version> using library resolution below.
  • Resolve haxec binary using haxec resolution.
  • Calls haxec with the expanded arguments.

The order in which -lib are expanded and replaced in arguments should be the same the current haxe compiler does (see haxelib path <lib> output too regarding dependencies).

Library resolution

Here's the minimal format of the lock file as written by the package manager:

{
  "mylib": {
    "version": "1.5.3",
    "path": "${haxelib}/mylib/1.5.3",
    "dependencies": ["otherlib"]
  }
  ...
}

When -lib mylib is found, the front end will replace it with -D mylib=1.5.3 -cp /path/to/haxelib/mylib/1.5.3 (+ additional arguments from extraArguments.hxml, if present) as well as all libraries mylib dependends on, recursively.

Environment variables can be used in the path field and are resolved according to the system environment variables. There is a special path for the haxelib variable: if defined, HAXELIB_LIBRARY_PATH is used instead, otherwise reads the content of the file ${HOME}/.haxelib (or its equivalent on other OS).

When there is no haxelib-lock.json (or override file), libraries are resolved differently:

  • read path into ${haxelib}/mylib/.dev
  • if does not exist read version into ${haxelib}/mylib/.current and set default path to ${haxelib}/mylib/<version>
  • read haxelib.json (if exists) for dependencies

haxec resolution

The first successful match is used, in order:

  • haxec library in the overriding --lock-file
  • haxec library in the default haxelib-lock.json
  • HAXEC_PATH environment variable
  • haxec in system PATH
  • resolve haxec as a haxelib (see library resolution)

Legacy haxelib features

The following haxelib features are currently not covered:

  • local repositories (haxelib newrepo)
  • haxelib dev paths (when you have a lock file, needs to use Global Override instead)