Skip to content

Commit

Permalink
Update README (#2)
Browse files Browse the repository at this point in the history
* Add intro and initial sections

* Add reference to additional inputs

* Remove some TODOs

* Complete Plugins section

* Fix style of functions

* Update plugins documentation

* Update headline / Add key differences section

* Update LICENSE

* Add missing plugins section
  • Loading branch information
sestrella authored Nov 21, 2023
1 parent 354e559 commit 5d92cb2
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 1 deletion.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2023 Sebastian Estrella
Copyright 2023-present Sebastian Estrella

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
Expand Down
161 changes: 161 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,164 @@
# asdf2nix

[![CI](https://github.com/sestrella/asdf2nix/actions/workflows/ci.yml/badge.svg)](https://github.com/sestrella/asdf2nix/actions/workflows/ci.yml)

asdf2nix is a tool designed for [asdf] users who want to experiment with
nix-shells, as well as former Nix users who want to simplify package version
management with a single configuration file. The following are some of the key
features:

- **Single source of truth** - The primary goal of asdf2nix is to allow both
asdf and Nix users to rely on the same configuration file to install
different tools with specific versions.
- **Transition to Nix** - asdf2nix is intended to be used as a bridge tool for
asdf users who want to try Nix without investing heavily in setting up a
completely new development environment with Nix.
- **Friendly error messages** - The majority of error messages contain hints on
how to work around them in order to improve the development experience.

## Disclaimer

Before you proceed, keep in mind that asdf currently supports a [wide range of
plugins](https://github.com/asdf-vm/asdf-plugins) that asdf2nix does not; while
some workarounds are detailed in the following sections, some of them require a
deeper understanding of Nix.

### Key Differences

- **Up-to-date versions** - Unlike asdf plugins, asdf2nix plugins do not obtain
the list of versions directly from an official upstream; thus, the available
packages may be slightly out-of-date when compared to their counterpart
plugins.
- **Plugins repository** - In contrast to asdf, there is no central repository
containing all references to existing plugins; users may have to rely on
GitHub or a Nix flake registry to locate specific plugins.
- **Reproducibility** - Because Nix values reproducibility, alias versions of
the form `x.y` or `x` may not be supported by all plugins due to their
mutability.

## Getting Started

Install Nix and enable Flakes using one of the methods listed below:

- Use Determinate Systems
[nix-installer](https://github.com/DeterminateSystems/nix-installer)
(recommended).
- Install Nix via the official [installer](https://nixos.org/download) and
enable [Flakes](https://nixos.wiki/wiki/Flakes) manually.

## Usage

The Nix flake scaffolding command is the quickest way to bootstrap asdf2nix:

```sh
nix flake init -t github:sestrella/asdf2nix
```

The remainder of this section’s content will walk you through the scaffolding
command’s output step by step.

The first input is from asdf2nix, which exposes the `packagesFromVersionsFile`
function, which is used to retrieve a set of packages based on a versions file:

```nix
inputs.asdf2nix.url = "github:sestrella/asdf2nix";
```

Because asdf2nix does not include all plugins, each plugin must be declared as
a separate input. Here is an example of a Python plugin:

```nix
inputs.asdf2nix-python.url = "github:sestrella/asdf2nix?dir=plugins/python";
```

**Note:** Not all plugins must come from this repository; the basic structure
of a plugin can be copied from the [Python plugin](plugins/python) and stored
in a different repository.

The following additional inputs are mentioned in the context of this example:

- **[flake-utils]** - Pure Nix flake utility functions.
- **[nixpkgs]** - Nix Packages collection & NixOS

```nix
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
```

The previously described `asdf2nix-python` plugin relies on a flake that stores
pre-compiled binaries in a cache, adding the binary cache configuration to the
`flake.nix` file would significantly speed up the process of obtaining packages
from this source:

```nix
nixConfig = {
extra-substituters = "https://nixpkgs-python.cachix.org";
extra-trusted-public-keys = "nixpkgs-python.cachix.org-1:hxjI7pFxTyuTHn2NkvWCrAUcNZLNS3ZAvfYNuYifcEU=";
};
```

The following code snippet uses [flake-utils] to loop over a set of [default
systems](https://github.com/nix-systems/default) to call
`packagesFromVersionsFile`, which is the main function exposed by asdf2nix and
takes care of parsing the versions file and fetching the corresponding packages
using the provided plugins:

```nix
packages = asdf2nix.lib.packagesFromVersionsFile {
inherit system;
versionsFile = ./.tool-versions;
plugins = {
python = asdf2nix-python.lib;
};
}
```

Finally, the output of `packagesFromVersionsFile` could be used to build a
[nix-shell].

```nix
devShells.default = pkgs.mkShell {
buildInputs = [ packages.python ];
};
```

**Note:** It is worth noting that the value returned by
`packagesFromVersionsFile` is of the form `{ “<plugin-1>” = <package-1>;
"<plugin-2>" = <package-2>; ... }`.

## Plugins

In an asdf2nix context, a plugin’s primary goal is to determine whether a
package version exists and to retrieve it. Plugins are made up of the following
functions:

- `hasVersion` - Checks if the requested version of a package is provided by
the plugin.
- `packageFromVersion` - Retrieves a package that matches a specific version.

For more information on how to structure a plugin, see the [Python
plugin](plugins/python).

### Missing Plugins

This section describes some workarounds for scenarios in which an asdf2nix
plugin for a specific tool is still unavailable. Here are some possible
workarounds:

- **Pull an existing package from nixpkgs** - This method makes use of the Nix
binary cache by retrieving a pre-built package from it; however, the package
version may be slightly out-of-date. Take a look at the following
[example](templates/nodejs-from-nixpkgs).
- **Override the version of an existing package** - This approach provides more
flexibility because it allows users to select the version of a package that
they want at the expense of more computational power if the package is not
available in a binary cache because it would be built from scratch. Take a
look at the following [example](templates/nodejs-override-version).

## License

[MIT](LICENSE)

[asdf]: https://asdf-vm.com
[flake-utils]: https://github.com/numtide/flake-utils
[nixpkgs]: https://github.com/nixos/nixpkgs
1 change: 1 addition & 0 deletions templates/nodejs-from-nixpkgs/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 20.5.1
29 changes: 29 additions & 0 deletions templates/nodejs-from-nixpkgs/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{

inputs = {
asdf2nix.url = "github:sestrella/asdf2nix";
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
};

outputs = { self, asdf2nix, flake-utils, nixpkgs }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
packages = asdf2nix.lib.packagesFromVersionsFile {
inherit system;
versionsFile = ./.tool-versions;
plugins = {
nodejs = {
hasVersion = { version, ... }: pkgs.nodejs_20.version == version;
packageFromVersion = _: pkgs.nodejs_20;
};
};
};
in
{
devShells.default = pkgs.mkShell {
buildInputs = [ packages.nodejs ];
};
});
}
1 change: 1 addition & 0 deletions templates/nodejs-override-version/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 20.9.0
36 changes: 36 additions & 0 deletions templates/nodejs-override-version/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{

inputs = {
asdf2nix.url = "github:sestrella/asdf2nix";
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05";
};

outputs = { self, asdf2nix, flake-utils, nixpkgs }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
packages = asdf2nix.lib.packagesFromVersionsFile {
inherit system;
versionsFile = ./.tool-versions;
plugins = {
nodejs = {
hasVersion = { version, ... }: version == "20.9.0";
packageFromVersion = { version, ... }:
pkgs.nodejs_20.overrideAttrs (_: {
inherit version;
src = builtins.fetchurl {
url = "https://nodejs.org/dist/v${version}/node-v${version}.tar.xz";
sha256 = "sha256:06a578f4h3sirjwp21dwnyak1wqhag74g79ldd15a15z1a0rcgd2";
};
});
};
};
};
in
{
devShells.default = pkgs.mkShell {
buildInputs = [ packages.nodejs ];
};
});
}

0 comments on commit 5d92cb2

Please sign in to comment.