Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Nix flake #28

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Add Nix flake #28

wants to merge 2 commits into from

Conversation

kmaasrud
Copy link
Collaborator

I don't know if you use Nix yourself, but having a Nix flake as part of this repo is very handy for tools like these. For example, I use a Nix flake to build my website, and just by adding this flake to the repo, I'll be able to parse Djot with jotdown by just linking to the repo. One can also run nix run github:hellux/jotdown -- somefile.dj to parse a file without installing anything!

Additionally, (and perhaps the biggest selling point,) setting up a dev environment is now a lot simpler. This crate targets 1.56, but this might not be the version installed on your system (it likely isn't.) Now, one can just run nix develop to get thrown into a shell with the Rust 1.56 toolchain installed. Any additional dependencies for benchmarking/fuzzing/etc. can also be added to this development environment.

@hellux
Copy link
Owner

hellux commented Mar 19, 2023 via email

@kmaasrud
Copy link
Collaborator Author

I.e. is the flake meant for users (to use the binary on their system) or for developers (to debug/benchmarks/fuzz etc)?

Both! Nix is a build system (and an accompanying declarative language) that can be used to build anything reproducibly. With this flake, I've defined three possible build outputs:

  • The package, which will be built the same way no matter the system, since all the build dependencies (only a specific Rust toolchain in this case) must be explicitly defined. The package only consists of the jotdown binary in this case, but manpages etc. could be included as well. You build by running nix build.

  • An runnable app. In this case, it only corresponds to executing the binary built as described above, but it gives users a very cool way of running jotdown in a throwaway fashion. E.g. I can already call jotdown from any computer with Nix on it, without installing anything, by running:

      $ nix run github:hellux/jotdown/nix -- --help
    

    Produces:

    usage: jotdown [option] [file]
    
    arguments:
        file            a djot source file. use a dash (`-`) or no argument
                        to read from stdin
    
    options:
        -h --help       show this text
        -v --version    show the version number
        -o --output     a file to write the output to. stdout if omitted
    
  • A development environment. Nix can literally function as a build system for dev environments, and the paramount advantage is that it builds these reproducibly as well!

Is it possible to place the files anywhere in the repo, e.g. in a contrib dir? The root directory might get cluttered if more similar files get added.

Sadly, no... It is a bit annoying that Rust projects now get two manifest files and two lockfiles, but I don't think there is any way around it.

Also, can the flake be used in Github's CI? Running it in the CI pipeline could help to make sure it is kept up to date, e.g. not targeting an older rust version?

It can! This is one of the really big niceities of using Nix. Have a look at this article to see some really cool examples.

I get it if you prefer the repo would not get too cluttered, and close this PR. However, I implore you to explore the possibilities a bit, as the advantages are really huge!

@clbarnes
Copy link
Contributor

clbarnes commented Jul 20, 2023

Can nix flakes be defined one directory above the package? In that case, could use another repo and have the jotdown repo as a submodule. Nix is one thing, and it's certainly useful, but there's also guix, then potentially build files for all sorts of other distribution types (deb, rpm, snap, flatpak, exe etc.), so the clutter risk is real.

@kmaasrud
Copy link
Collaborator Author

kmaasrud commented Jul 20, 2023 via email

Copy link

@tomhoule tomhoule left a comment

Choose a reason for hiding this comment

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

Just chiming in that as a nix user, this would help. There are advantages of having nix derivations for your project even for your non-nix users: you have at least one known, reproducible, hermetic (all build inputs are known and inspectable with something like nix-tree) way to build the software.

@kmaasrud
Copy link
Collaborator Author

kmaasrud commented Nov 2, 2023

I'm ashamed to say I have been pretty terrible at contributing to the project lately, but I have push access and am open to maintaining a flake for it.

Just need approval from @hellux and I'll pull in the newest changes and merge this PR.

@hellux
Copy link
Owner

hellux commented Nov 2, 2023 via email

@kmaasrud
Copy link
Collaborator Author

kmaasrud commented Nov 2, 2023

Part of the joy of Nix is that it is incredibly stable since everything is reproducible. The only thing that needs to be updated are any dependencies, of which you don't really have any other than Rust itself (notable exception being dev dependencies.)

As such, I only really see the need for checking the flake and potentially updating the tree whenever there is a new release. That is likely way too often, but better safe than sorry 😅 I can take care of that.

Do you know if there is any way that I can get a notification every time you push a tag? Both RSS and GitHub notifications would suffice. I can't find such a feature, but there must be something, right?

@hellux
Copy link
Owner

hellux commented Nov 4, 2023 via email

@kmaasrud
Copy link
Collaborator Author

kmaasrud commented Nov 6, 2023

I am not familiar with nix flakes but I suspect that there are some things that could potentially break at some point. The flake.nix file has some references to a few github repos: - github:NixOS/nixpkgs/nixpkgs-unstable - github:numtide/flake-utils - github:oxalica/rust-overlay Since no hashes seem to be specified for these I suspect we rely on that our usage is compatible with each repo's master branch? Even if it hashed still rely on the content to be available completely unmodified.

The whole dependency tree, with precise hashes are found in the flake.lock file.

The only hash that I can find is this one: jotdown = rustPlatform.buildRustPackage { inherit pname version; src = pkgs.lib.cleanSource ./.; cargoSha256 = "sha256-mQvMB+AiojOWJNw/EYvI+jJmvXtxzBOFntWSis3Wv0s="; }; Does this hash include the source code for jotdown or any dependencies? Does it include the above mentioned repos? Doesn't this hash have to be updated rather frequently?

That hash would have to be updated on any changes to the Cargo.lock file, yes. However, I've now switched the Nix Rust layer to crane, which uses Cargo.lock directly so that won't be necessary anymore.

The file specifies a specific rust version: toolchain = pkgs.rust-bin.stable."1.56.0".default; The rust target version might change so this would break if any newer features were to be used in jotdown.

If the lowest supported version is changed, the flake would have to be updated as well, yes. The same goes for the README, so that will indeed be a manual process. The reason I pinned the flake to the lowest version was so that I could jump into a dev-shell and know what features I had at my disposal. If we don't care about the development part of the Nix flake, we could put a higher version here to ensure that newer features are available.

It is also implicity assumed that the file is compatible with the Nix/flake framework, which could potentially change over time? Especially since it seems to be labeled as an experimental feature.

The "experimental" tag is a widely discussed wart of the ecosystem, but for all intents and purposes, it is misleading. Nix flakes are generally considered quite stable, and for this very simple use-case, I am confident we will not hit any compatibility issues. You can read some thoughts on the matter here.

Yeah, an RSS feed seems to be available at https://github.com/hellux/jotdown/tags.atom.

I'll subscribe to it and keep an eye on any new releases!


In summary, I definitely understand your concerns about adding yet another build tool---one that you are not familiar with yourself---to the mix. However, adding support for Nix gives a huge advantage to the community and lowers the barrier of entry for those that are familiar with the workflow.

afl is not available on Darwin, so I chose to completely ditch the development shell part of the flake, since Nix derivations are generally expected to build exactly the same on all platforms. I also moved the flake to the contrib directory, so it can be considered more of a supplementary option. Feel free to route any questions about it to me.

@hellux
Copy link
Owner

hellux commented Nov 6, 2023 via email

README.md Outdated Show resolved Hide resolved
reproducible build of Jotdown by cloning the repo and running

```
$ nix build ./contrib
Copy link
Owner

Choose a reason for hiding this comment

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

I guess this is for development where it might be good to use 1.56 instead of nightly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I did not setup a derivation for building a development shell, just a derivation for building Jotdown itself. In it, I use the latest Rust, just to get the newest features and speed improvements. If you want, I could setup a development shell managed by Nix as well?

README.md Outdated
### Nix flake

There is a Nix flake available in the `contrib` directory. With, you can get a
reproducible build of Jotdown by cloning the repo and running
Copy link
Owner

Choose a reason for hiding this comment

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

"Reproducible build" usually means a bitwise identical binary, right? But is it necessarily reproducible in this regard? Even if all the inputs are identical, the output is not necessarily deterministic?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

"Reproducible" is typically the word that's used in the context of Nix, as it describes a build process that does not depend on (or get altered by) the build environment.

I'm not sure whether the term "reproducible" entails "identical", but no; the binaries are not necessarily identical. However, that goes for different platforms as well. The point is that I can build a binary of Jotdown on my computer, and you can build a binary with the same behavior on another computer without any further setup.

Copy link
Owner

Choose a reason for hiding this comment

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

In our case I think we only know for certain that we have deterministic or reproducible inputs and not necessarily a reproducible build or output.

E.g. https://reproducible.nixos.org/ seems to refer to "reproducible builds" as bitwise exact outputs.

@hellux
Copy link
Owner

hellux commented Jan 7, 2024

Hi, any update on this? I think this is more or less good to merge.

@kmaasrud
Copy link
Collaborator Author

kmaasrud commented Jan 9, 2024

@hellux hey sorry, christmas got in the way 🎅 I amended a fix to the typo you found and answered some of your questions. Ping me whenever you feel ready and I'll merge the branch 😄

@hellux hellux force-pushed the master branch 4 times, most recently from be8be3c to 0504b10 Compare January 12, 2024 23:11
@hellux hellux force-pushed the master branch 2 times, most recently from 2f643e9 to 35891f8 Compare January 12, 2024 23:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants