Skip to content

Spec for Extended package specific variables

Kate edited this page Apr 10, 2023 · 6 revisions

Wrt https://github.com/ocaml/opam/issues/4526 we discussed the possibility of using the available field to resolve this problem instead of having yet another flag.

This would make the behaviour independent of the version of opam as undefined variables are false by default.

Proposal

  • Add a new option --set <var>[=<value>] to opam install, opam reinstall, opam upgrade and opam switch which would:

    • set a variable defined only for the packages listed explicitly by the command above used
    • said variable would be stored in <switch-prefix>/.opam-switch/config/<pkg>.config the same way <pkg>.config are. The variables passed as argument would override any variables from the <pkg>.config file if there is any.
    • said variable would be treated the same way as usual packages variables (coming from .config files)
  • Broader changes to packages variables:

    • packages variable from the current package (aka. _:var) can now be used in the available field
    • with-test and with-doc would become shorthands for _:with-test and _:with-doc respectively and the --with-{test,doc} argument would become shorthands for --set with-{test,doc}
    • Package variables can also be set before even installing the package with opam var pkg:var=value. However trying to do that on currently installed packages would result in an error.
  • Later features:

    • Default global values for package variable could be added as a feature later (e.g. opam var _:with-test=true would make any future packages compile the tests as well)
    • We could detect new values when calling opam install --set var=new-value pkg and rebuild pkg if the value of var is different from the one installed.

Usage

This would be very useful for:

  • Making packages unavailable: changing the package for it to be available: _:manual | !(os-family = "alpine" | os-distribution = "centos") for instance so that people can still install it if they have things set up locally, but would be unavailable by default. People would just have to call opam install --set manual <pkg> if they sure they really want it. This would also remove any use for x-ci-accept-failures in CIs that support it.
  • This would make opam finally on-par to gentoo's USE flags (https://www.gentoo.org/support/use-flags/) — superior even, as USE flags do not carry values — and would open possibilities such as: opam switch create --set use-flambda 4.12.0 and would remove any use of conf-option-* packages.

Related issues

Design issues

  • _:var in available: will return an error when added using opam 2.0 and 2.1
    • To test: Is var a shorthand for _:var?
  • _:var isn't false by default, it's undefined. Which means that in opam 2.0 and 2.1, build: ["true"] {_:var} and build: ["true"] {!_:var} will do the exact same thing (not do anything)
    • Solution: ?var & var will give the right result

WIP design whiteboard

Statically known variables:

  • Defined in advance (it's better if there are listed in a new "vars" field for example but not mendatory)
  • Can be used to mess with dependencies safely (known before solver call)
  • <pkg>:name
  • <pkg>:pinned
  • <pkg>:bin & <pkg>:sbin & <pkg>:lib & <pkg>:man & <pkg>:doc & <pkg>:share & <pkg>:etc

Dynamically known variables:

  • Unsafe to use in depends, depexts, depopts and conflicts (requires multi solver calls)
  • e.g. everything set on the fly in <pkg>.config files
  • <pkg>:version
  • <pkg>:depends
  • <pkg>:installed
  • <pkg>:enabled
  • <pkg>:build
  • <pkg>:hash
  • <pkg>:dev
  • <pkg>:build-id
  • <pkg>:opamfile

Could default values for dynamically set variables help? Something like:

variables: [
  [bytecode-only = false]
  32bit
  ...
]