edgedb-cli icon indicating copy to clipboard operation
edgedb-cli copied to clipboard

Implement semver version pinning in `edgedb.toml`

Open colinhacks opened this issue 2 years ago • 1 comments

Currently edgedb.toml only supports major version pinning, but with the switch to portable builds we can now support full semver versioning.

Per https://edgedb.slack.com/archives/CNECHA9EW/p1647542994504509

colinhacks avatar Mar 17 '22 18:03 colinhacks

We support 1.2 meaning ^1.2 (which is also how cargo works too). Other patterns should be discouraged, as far as I understand.

Do you have any specific problems, that you would like to solve?

tailhook avatar Mar 18 '22 07:03 tailhook

We should support = pinning at least for cases where a point release introduces a regression. So, in edgedb.toml server-version = '=2.6'. Also, we should consider changing the command-line server-version argument to behave like = by default, because otherwise --server-version=2.6 installing a 2.7 is confusing. FWIW, cargo defaults to = on the command line in cargo install also.

elprans avatar Nov 20 '22 04:11 elprans

my suggestion from the zoom chat, this is based on not knowing much about the internals, just what would make sense to me as a user:

--server-version and --pin-server-version (mutually exclusive, and both accepting a version string, rather than --pin-server-version being a boolean flag)

this allows me to clearly communicate my intention/desire to the tool, and avoids any awkward command-lines (such as --server-version='=42')

zackelan avatar Nov 21 '22 18:11 zackelan

So, three options:

Option 1

CLI --server-option is treated exactly the same as server-version in edgedb.toml, i.e. writing X.Y without an operator means ^X.Y. In this approach, pinning requires explicit =, e.g --server-version="=2.8".

Upside: consistent handling of specifiers Downside: behavior could be surprising to users, and constructs like --server-version="=2.7" are somewhat awkward.

Option 2

CLI --server-version rewrites X.Y without an operator into =X.Y in edgedb.toml, so pinning is the default behavior. To opt-out of pinning, one must specify an operator explicitly, e.g --server-version=^2.6

Upside: somewhat less confusing behavior of the command line option Downside: different behavior from edgedb.toml

Option 3 (hybrid)

As suggested by @zackelan above, we use two distinct options for the two options above, where --server-version behaves like Option 1 and --pin-server-version behaves like Option 2.

elprans avatar Nov 21 '22 18:11 elprans

For completeness:

Option 4

--server-version in project init is written literally into edgedb.toml, but the specific version is installed.

Upside: works both for testing on specific version and for end users Downside: may be perceived as inconsistent

Option 5

We ask interactively which version to install on --server-version.

Upside: user don't have to learn semver semantics and = operator Downside: the whole point of the option is not to ask

tailhook avatar Nov 22 '22 09:11 tailhook

I think Option 1 is good. And Option 4 is tolerable.

Option 2 is bad as the primary function of the project init is to write a toml file, and then initialize project using that toml. So --server-version is a way to write the toml file. (Same applies to Option 4, but in my opinion in more acceptable form).

Option 3 doesn't add anything to me. It's as easy to learn =2.5 as --pin-server-version=2.5. Even more so, as =2.5 is a standard semver operator, and it's what will be written into toml anyway (i.e. users will occasionally read that).

Option 5 is weirdly inconsistent:

  1. In non-interactive mode we can't ask. So we have to make extra command-line argument for that?
  2. If someone writes a guide where this is used: edgedb project init --server-version=2.5. They also have to put instructions to answer that extra question.
  3. It's inconsistent with other options: we don't ask the question if answer is provided in an option.

tailhook avatar Nov 22 '22 10:11 tailhook

Another possible addition is to add one or both of:

  1. --minimum-version -- that works both on new edgedb.toml and the old one. I.e. if you need to test your project on 2.1. While that is written in the toml file, you do project init --minimum-version. Likewise you can do project init --server-version=2.1 --minimum-version on the new project.
  2. --force-version=2.3 -- that works like --minimum-version, but has more specific requirements.

Here is the discussion of the similar feature in cargo. Although, not all of that discussion applies to EdgeDB as we basically have just "a single dependency".

But I think most use cases we encountered so far are ad-hoc projects to test specific version and --server-version "=2.1" will be shorter and more obvious to use for that.

tailhook avatar Nov 22 '22 10:11 tailhook

Looks like we're satisfied with Option 1 and PR #897.

tailhook avatar Nov 28 '22 17:11 tailhook