switch to python

This commit is contained in:
Rowan Torbitzky-Lane 2025-04-08 23:07:58 -05:00
parent 49a7a1e404
commit 60b547a470
2 changed files with 212 additions and 111 deletions

99
flake.lock generated
View File

@ -1,92 +1,95 @@
{ {
"nodes": { "nodes": {
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1744098102, "lastModified": 1744098102,
"narHash": "sha256-tzCdyIJj9AjysC3OuKA+tMD/kDEDAF9mICPDU7ix0JA=", "narHash": "sha256-tzCdyIJj9AjysC3OuKA+tMD/kDEDAF9mICPDU7ix0JA=",
"owner": "nixos", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c8cd81426f45942bb2906d5ed2fe21d2f19d95b7", "rev": "c8cd81426f45942bb2906d5ed2fe21d2f19d95b7",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixos-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-lib": { "pyproject-build-systems": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"pyproject-nix": [
"pyproject-nix"
],
"uv2nix": [
"uv2nix"
]
},
"locked": { "locked": {
"lastModified": 1743296961, "lastModified": 1743993520,
"narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", "narHash": "sha256-DgQ/b7f7QIECEVYVIWrqYXl1iTzXTfibMhxp6QMsAwA=",
"owner": "nix-community", "owner": "pyproject-nix",
"repo": "nixpkgs.lib", "repo": "build-system-pkgs",
"rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", "rev": "4470eb3e37dc5d2791b77b90c5228506d729800f",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "pyproject-nix",
"repo": "nixpkgs.lib", "repo": "build-system-pkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs_2": { "pyproject-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": { "locked": {
"lastModified": 1736320768, "lastModified": 1743438845,
"narHash": "sha256-nIYdTAiKIGnFNugbomgBJR+Xv5F1ZQU+HfaBqJKroC0=", "narHash": "sha256-1GSaoubGtvsLRwoYwHjeKYq40tLwvuFFVhGrG8J9Oek=",
"owner": "NixOS", "owner": "pyproject-nix",
"repo": "nixpkgs", "repo": "pyproject.nix",
"rev": "4bc9c909d9ac828a039f288cf872d16d38185db8", "rev": "8063ec98edc459571d042a640b1c5e334ecfca1e",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "pyproject-nix",
"ref": "nixpkgs-unstable", "repo": "pyproject.nix",
"repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay" "pyproject-build-systems": "pyproject-build-systems",
"pyproject-nix": "pyproject-nix",
"uv2nix": "uv2nix"
} }
}, },
"rust-overlay": { "uv2nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_2" "nixpkgs": [
"nixpkgs"
],
"pyproject-nix": [
"pyproject-nix"
]
}, },
"locked": { "locked": {
"lastModified": 1744166053, "lastModified": 1744108242,
"narHash": "sha256-mpI7OzFwp+fUeDtZYQbVZ2YmtxTN2UNrrOwbYD27xKU=", "narHash": "sha256-cvwVUlHKqjv/8NlO1681vcoB/lHPkV9gKm/HHED/dvw=",
"owner": "oxalica", "owner": "pyproject-nix",
"repo": "rust-overlay", "repo": "uv2nix",
"rev": "896158be1835589db6f42f45ef0a49b8b492cc66", "rev": "e00f7117aaebaa1f9ff846976d655c5a4d919321",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "oxalica", "owner": "pyproject-nix",
"repo": "rust-overlay", "repo": "uv2nix",
"type": "github" "type": "github"
} }
} }

214
flake.nix
View File

@ -1,75 +1,173 @@
{ {
description = "tito flake using uv2nix";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
rust-overlay.url = "github:oxalica/rust-overlay"; pyproject-nix = {
url = "github:pyproject-nix/pyproject.nix";
inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = inputs: uv2nix = {
inputs.flake-parts.lib.mkFlake { inherit inputs; } { url = "github:pyproject-nix/uv2nix";
systems = [ "x86_64-linux" ]; inputs.pyproject-nix.follows = "pyproject-nix";
perSystem = { config, self', pkgs, lib, system, ... }: inputs.nixpkgs.follows = "nixpkgs";
};
pyproject-build-systems = {
url = "github:pyproject-nix/build-system-pkgs";
inputs.pyproject-nix.follows = "pyproject-nix";
inputs.uv2nix.follows = "uv2nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
{
nixpkgs,
uv2nix,
pyproject-nix,
pyproject-build-systems,
...
}:
let let
runtimeDeps = with pkgs; [ alsa-lib speechd ]; inherit (nixpkgs) lib;
buildDeps = with pkgs; [ pkg-config rustPlatform.bindgenHook ];
devDeps = with pkgs; [ gdb ];
cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); # Load a uv workspace from a workspace root.
msrv = cargoToml.package.rust-version; # Uv2nix treats all uv projects as workspace projects.
workspace = uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; };
rustPackage = features: # Create package overlay from workspace.
(pkgs.makeRustPlatform { overlay = workspace.mkPyprojectOverlay {
cargo = pkgs.rust-bin.stable.latest.minimal; # Prefer prebuilt binary wheels as a package source.
rustc = pkgs.rust-bin.stable.latest.minimal; # Sdists are less likely to "just work" because of the metadata missing from uv.lock.
}).buildRustPackage { # Binary wheels are more likely to, but may still require overrides for library dependencies.
inherit (cargoToml.package) name version; sourcePreference = "wheel"; # or sourcePreference = "sdist";
src = ./.; # Optionally customise PEP 508 environment
cargoLock.lockFile = ./Cargo.lock; # environ = {
buildFeatures = features; # platform_release = "5.10.65";
buildInputs = runtimeDeps; # };
nativeBuildInputs = buildDeps;
# Uncomment if your cargo tests require networking or otherwise
# don't play nicely with the Nix build sandbox:
# doCheck = false;
}; };
mkDevShell = rustc: # Extend generated overlay with build fixups
#
# Uv2nix can only work with what it has, and uv.lock is missing essential metadata to perform some builds.
# This is an additional overlay implementing build fixups.
# See:
# - https://pyproject-nix.github.io/uv2nix/FAQ.html
pyprojectOverrides = _final: _prev: {
# Implement build fixups here.
# Note that uv2nix is _not_ using Nixpkgs buildPythonPackage.
# It's using https://pyproject-nix.github.io/pyproject.nix/build.html
};
# This example is only using x86_64-linux
pkgs = nixpkgs.legacyPackages.x86_64-linux;
# Use Python 3.12 from nixpkgs
python = pkgs.python312;
# Construct package set
pythonSet =
# Use base package set from pyproject.nix builders
(pkgs.callPackage pyproject-nix.build.packages {
inherit python;
}).overrideScope
(
lib.composeManyExtensions [
pyproject-build-systems.overlays.default
overlay
pyprojectOverrides
]
);
in
{
# Package a virtual environment as our main application.
#
# Enable no optional dependencies for production build.
packages.x86_64-linux.default = pythonSet.mkVirtualEnv "tito-env" workspace.deps.default;
# This example provides two different modes of development:
# - Impurely using uv to manage virtual environments
# - Pure development using uv2nix to manage virtual environments
devShells.x86_64-linux = {
# It is of course perfectly OK to keep using an impure virtualenv workflow and only use uv2nix to build packages.
# This devShell simply adds Python and undoes the dependency leakage done by Nixpkgs Python infrastructure.
# impure = pkgs.mkShell {
# packages = [
# python
# pkgs.uv
# ];
# env =
# {
# # Prevent uv from managing Python downloads
# UV_PYTHON_DOWNLOADS = "never";
# # Force uv to use nixpkgs Python interpreter
# UV_PYTHON = python.interpreter;
# }
# // lib.optionalAttrs pkgs.stdenv.isLinux {
# # Python libraries often load native shared objects using dlopen(3).
# # Setting LD_LIBRARY_PATH makes the dynamic library loader aware of libraries without using RPATH for lookup.
# LD_LIBRARY_PATH = lib.makeLibraryPath pkgs.pythonManylinuxPackages.manylinux1;
# };
# shellHook = ''
# unset PYTHONPATH
# '';
# };
# This devShell uses uv2nix to construct a virtual environment purely from Nix, using the same dependency specification as the application.
# The notable difference is that we also apply another overlay here enabling editable mode ( https://setuptools.pypa.io/en/latest/userguide/development_mode.html ).
#
# This means that any changes done to your local files do not require a rebuild.
uv2nix =
let
# Create an overlay enabling editable mode for all local dependencies.
# Note: Editable support is still under development and this API might change.
editableOverlay = workspace.mkEditablePyprojectOverlay {
# Use environment variable
root = "$REPO_ROOT";
# Optional: Only enable editable for these packages
# members = [ "hello-world" ];
};
# Override previous set with our overrideable overlay.
editablePythonSet = pythonSet.overrideScope editableOverlay;
# Build virtual environment, with local packages being editable.
#
# Enable all optional dependencies for development.
virtualenv = editablePythonSet.mkVirtualEnv "tito-dev-env" workspace.deps.all;
in
pkgs.mkShell { pkgs.mkShell {
packages = [
virtualenv
pkgs.uv
];
env = {
# Don't create venv using uv
UV_NO_SYNC = "1";
# Force uv to use Python interpreter from venv
UV_PYTHON = "${virtualenv}/bin/python";
# Prevent uv from downloading managed Python's
UV_PYTHON_DOWNLOADS = "never";
};
shellHook = '' shellHook = ''
export RUST_SRC_PATH=${pkgs.rustPlatform.rustLibSrc} # Undo dependency propagation by nixpkgs.
unset PYTHONPATH
# Get repository root using git. This is expanded at runtime by the editable `.pth` machinery.
export REPO_ROOT=$(git rev-parse --show-toplevel)
export SHELL=${pkgs.lib.getExe pkgs.bashInteractive} export SHELL=${pkgs.lib.getExe pkgs.bashInteractive}
''; '';
buildInputs = runtimeDeps;
nativeBuildInputs = buildDeps ++ devDeps ++ [ rustc ];
packages = with pkgs; [
rust-analyzer
lldb
(vscode-with-extensions.override {
vscode = vscodium;
vscodeExtensions = with vscode-extensions; [
rust-lang.rust-analyzer
vadimcn.vscode-lldb
];
})
];
}; };
in {
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
overlays = [ (import inputs.rust-overlay) ];
};
packages.default = self'.packages.tito;
# devShells.default = self'.devShells.nightly;
devShells.default = self'.devShells.stable;
packages.tito = (rustPackage "tito");
packages.tito-base = (rustPackage "");
devShells.nightly = (mkDevShell (pkgs.rust-bin.selectLatestNightlyWith
(toolchain: toolchain.default)));
devShells.stable = (mkDevShell pkgs.rust-bin.stable.latest.default);
devShells.msrv = (mkDevShell pkgs.rust-bin.stable.${msrv}.default);
}; };
}; };
} }