{"action":"created","issue":{"url":"https://api.github.com/repos/ocaml/opam/issues/2247","labels_url":"https://api.github.com/repos/ocaml/opam/issues/2247/labels{/name}","comments_url":"https://api.github.com/repos/ocaml/opam/issues/2247/comments","events_url":"https://api.github.com/repos/ocaml/opam/issues/2247/events","html_url":"https://github.com/ocaml/opam/issues/2247","id":93582608,"number":2247,"title":"Switch and package configuration variables","user":{"login":"dbuenzli","id":485596,"avatar_url":"https://avatars.githubusercontent.com/u/485596?v=3","gravatar_id":"","url":"https://api.github.com/users/dbuenzli","html_url":"https://github.com/dbuenzli","followers_url":"https://api.github.com/users/dbuenzli/followers","following_url":"https://api.github.com/users/dbuenzli/following{/other_user}","gists_url":"https://api.github.com/users/dbuenzli/gists{/gist_id}","starred_url":"https://api.github.com/users/dbuenzli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dbuenzli/subscriptions","organizations_url":"https://api.github.com/users/dbuenzli/orgs","repos_url":"https://api.github.com/users/dbuenzli/repos","events_url":"https://api.github.com/users/dbuenzli/events{/privacy}","received_events_url":"https://api.github.com/users/dbuenzli/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2015-07-07T17:18:28Z","updated_at":"2015-07-08T14:40:12Z","closed_at":null,"body":"# Switch and package configuration variables\r\n\r\nSwitch and package configuration variables are respectively per switch and per package key-values bindings that can be accessed in opam files to configure packages.\r\n\r\nConfiguration variables come in two flavors, input and output variables (better names ? user and state variables ?). The difference being that input variables can be set by the opam end-user while output variables are usually defined by the result of install processes.\r\n\r\nMore precisely for package configuration variables:\r\n\r\n* *input* variables can be set before package installation to configure the package installation process.\r\n* *output* variables can be declared by the package install to provide information about its installation for other packages to use.\r\n\r\nFor switch configuration variables:\r\n\r\n* *input* variables can be set to globally configure packages that may use the variable.\r\n* *output* variables are variables determined by the switch creation procedure\r\n\r\nNote that both input and output variables share the same namespace. It is not possible to declare both an input and output variable with the same name.\r\n\r\nAlso note that the current value of an *input* variable says nothing about the current install state of a switch or a package as they may be set by the end-user at any time without further side-effects. (N.B. if we had precise dependency tracking of variables in the opam files we could actually reinstall any package that depends on a variable whenever it is changed, but that may not be desirable either).\r\n\r\n## Input variable declaration\r\n\r\nSwitch input variables are defined in the switch's `.comp` file and package input variables are defined in the package's `opam` file via the `config-input-vars` field as follows:\r\n\r\n```\r\nconfig-input-vars: [ ([IDENT (BOOL | STRING | [ STRING+ ]) STRING])+ ]\r\n```\r\nThat is each input variable needs to define a name, a default value (which can be a variable interpolated string, e.g. in a package it can refer to a switch input variable) and a documentation\r\nstring. Example:\r\n```\r\nconfig-input-vars: [\r\n  [ \"modernity\" false \"Use CPU extensions (SSE2, AES-NI).\" ]\r\n]\r\n```\r\n\r\n## Output variables declaration\r\n\r\nOutput variables are defined in the switch's `.comp` file and the package's `opam` files via the `config-output-vars` variables as follows:\r\n```\r\nconfig-output-vars: [ ([IDENT STRING])+ ]\r\n```\r\nThat is each output variable needs to define its name and a documentation string.\r\n\r\nFor packages, the package must then define the value of each of the declared variables by installing a `opam.config` file with the package in its `lib` directory, i.e. `$opam/$SWITCH/lib/opam.config`.\r\n\r\nIt is an *install* error if the package declares an output variables and fails to define it in its `opam.config` file.\r\n\r\nFIXME I know less about the switch install procedure but I guess something similar could be done.\r\n\r\n## Setting input variables\r\n\r\nInput variables can be set by using the following invocations:\r\n```\r\nopam config var-set $PKG:$VAR $VALUE\r\nopam config var-set $VAR $VALUE\r\n```\r\nFor packages this commands writes the `$VAR` to `$VALUE` binding in `$opam/$SWITCH/config/$PKG.config` file. For switches it does so in the file `$opam/$SWITCH/config/global-config.config`.  The invocations error if `$VAR` is not declared in the package's or switch's `config-input-vars` field.\r\n\r\nInput variables can be reset to their default state using:\r\n```\r\nopam config var-reset $PKG[:$VAR]\r\nopam config var-reset [$VAR]\r\n```\r\nInvoking this command resets the value of `$VAR` to the one that is declared in the `opam` or `.comp` file. If `$VAR` is unspecified all the input variables are reset. The invocations error if `$VAR` is not declared in the package or switch's `config-input-vars` field.\r\n\r\n## Getting configuration variables\r\n\r\nBoth input and output configuration variables can be accessed using the following invocation:\r\n```\r\nopam config var [$PKG:]$VAR\r\n```\r\nThey can also be used in the fields of `opam` files that support string interpolation to get their value by using `$PKG:$VAR` and `$VAR`. The invocations error if `$VAR` is not in declared in one of the `config-*-vars` field. \r\n"},"comment":{"url":"https://api.github.com/repos/ocaml/opam/issues/comments/119605595","html_url":"https://github.com/ocaml/opam/issues/2247#issuecomment-119605595","issue_url":"https://api.github.com/repos/ocaml/opam/issues/2247","id":119605595,"user":{"login":"dbuenzli","id":485596,"avatar_url":"https://avatars.githubusercontent.com/u/485596?v=3","gravatar_id":"","url":"https://api.github.com/users/dbuenzli","html_url":"https://github.com/dbuenzli","followers_url":"https://api.github.com/users/dbuenzli/followers","following_url":"https://api.github.com/users/dbuenzli/following{/other_user}","gists_url":"https://api.github.com/users/dbuenzli/gists{/gist_id}","starred_url":"https://api.github.com/users/dbuenzli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dbuenzli/subscriptions","organizations_url":"https://api.github.com/users/dbuenzli/orgs","repos_url":"https://api.github.com/users/dbuenzli/repos","events_url":"https://api.github.com/users/dbuenzli/events{/privacy}","received_events_url":"https://api.github.com/users/dbuenzli/received_events","type":"User","site_admin":false},"created_at":"2015-07-08T14:40:12Z","updated_at":"2015-07-08T14:40:12Z","body":"> I am curently thinking very seriously about removing the .comp files altogether¹. The compiler variables (in global-config.config) are actually a choking point here, and that would more or less result in merging package and switch configuration variables... We'd need a way to specify input vars to opam switch install but otherwise the proposal seems to fit well for that purpose.\r\n\r\nI don't know exactly what your plans are but don't you think you'd still need some kind of switch description file ? If that's the case that seems to be the right place to describe the switch variables. If you think you can eschew the switch description file and that packages create switches (how ? via information provided by a field ?) then yes we can merge the two notions and have switch creating packages define the global variables through their own `opam.config` file (variables which should then be accessible withouth the `$PKG:` prefix. Trying to set user variables for a switch creating package would simply create the `$opam/$SWITCH/config/$PKG.config` file. But then maybe this should be sorted out after we get a concrete compiler as packages proposal. \r\n\r\n> How does this relate to features ? Those also define variables, and in the same namespace, but dynamically evaluated; and they are used both for the package's own build and readable from others. It feels like too many options, could they be replaced by this ? Their limitation is that they can't be set by the user at the moment.\r\n\r\nThis was also a question I had. Reading again about them in the dev manual, it seems to me that we could replace them by this. \r\n\r\n> Checking the existence of an input variable when setting can't be very strict: what if different versions of the package don't define the same variables, \r\n\r\nAh yes. Can't we simply union the variables found in the descriptions. \r\n\r\n> or if the package or variable gets removed from the repository ? This should still avoid spelling errors (but there may even be a --force).\r\n\r\nMaybe having a `--force` is a good idea. \r\n\r\n> install error on undefined output var: it shouldn't be as harsh as removing the package and resetting the build though. As for input vars, we can have different ouptput variables for different versions, and can't completely avoid the case of a variable being undefined.\r\n\r\nWhy not ? I think that not checking this is going to bring more problems in by propagating wrong information in the system. Packages can have different output variables for different versions as described by their opam files, I don't see this as a problem. Besides I think that usage of an undefined output variable by another package should also make its install fail. \r\n\r\n> referring to undefined variables is already supported -- we handle the undefined value and propagate it in formulas. There is no built-in way to check if a variable is defined or not though. History has taught us to be careful when adding warnings that could completely spam the users on opam update.\r\n\r\nI'm not talking about `opam update` here I'm talking about `opam install` which is quite different. Undefinedness can be checked at that point. \r\n\r\n\r\n\r\n"}}