Skip to content
/ rfcs Public
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions rfcs/0183-versioned-flakes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
feature: versioned-flakes
start-date: 2024-11-25
author: domenkozar
co-authors: None
shepherd-team: None
shepherd-leader: None
related-issues: None
---
## Summary

Introduce a standardized versioning schema for Nix flakes using [SemVer](https://semver.org/),
Copy link
Member

@inclyc inclyc Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem in semver:

how can we prove two packages are semantically same, even if their versions are different?.

It is more reliable if: any package update will trigger "full-rebuilds" for those dependent on it.

I just feel a little bit strange about introducing "SemVer" here.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, isn't this RFC about versioning flakes, not packages?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused, isn't this RFC about versioning flakes, not packages?

That's the interesting paradox: if we don't use semantic versioning (SemVer) for packages, why should we use SemVer for flakes?

If there are valid reasons for using SemVer with 'flake' dependencies, why wouldn't those same reasons apply to packages as well?

Copy link
Member Author

@domenkozar domenkozar Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will you apply semver to nixpkgs flake?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the interesting paradox: if we don't use semantic versioning (SemVer) for packages, why should we use SemVer for flakes?

If there are valid reasons for using SemVer with 'flake' dependencies, why wouldn't those same reasons apply to packages as well?

  • Flake version is about the flake's API surface, while package version is about the package's API surface or whatever upstream wants to do, they are orthogonal to each other
  • You can't and shouldn't force developers to use a certain version format for their software, so package versions should be as flexible as possible (nixpkgs of course has no restrictions at all really)
  • Flake versions could be automatically resolved, it's well known where to search for versions and how to load them, while neither really applies to packages

I don't have an opinion on this RFC either way but the two situations are certainly very different.

following lessons learned from [RFC 144](https://github.com/NixOS/rfcs/pull/144/files).

Adds to flakes:

- `version` attribute to `inputs` in the top-level of `flake.nix` to specify version of the input to be resolved.
- An attribute `version` in the top-level of `flake.nix`.

## Motivation

Currently, Flakes lack a formal versioning mechanism, leading to potential duplication of dependencies and inefficient evaluations.

By adopting a versioning schema similar to Rust's Cargo system, we can utilize a SAT solver to manage dependencies more effectively, minimizing redundancy and improving performance.

## Explanation

- **Version Schema:** Implement a versioning system for flakes that follows SemVer conventions (e.g., `1.0.0`, `2.1.3`).
- **Input Versioning:** Allow flake inputs to specify version constraints (e.g., `inputs.nixpkgs.version = "^3.0.0";`) following [Rust Caret Requirement Syntax]([https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#version-requirement-syntax](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#caret-requirements)).
- **Dependency Resolution:** Integrate a SAT solver to resolve dependencies based on specified versions, ensuring compatibility and reducing duplication.

### Examples

**Defining a Flake with a Version:**

```nix
{
version = "1.0.0";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs";
nixpkgs.version = "^1.0.55";
};

outputs = { self, nixpkgs }: { /* ... */ };
}
```

### Implementation

Nix would resolve versions as part of the evaluation, shipping a SAT version resolver.

`flake-compat` wouldn't support version resolving.

[flakestry.dev](https://github.com/flakestry/flakestry.dev) would provide an HTTP API for resolving by preevaluating flakes.