Unnamed repository; edit this file 'description' to name the repository.
Clean up Nix Flake & make it easier to customize (#12831)
Christopher Smyth 12 months ago
parent 671a603 · commit 1d45378
-rw-r--r--default.nix84
-rw-r--r--flake.lock28
-rw-r--r--flake.nix195
-rw-r--r--grammars.nix32
4 files changed, 142 insertions, 197 deletions
diff --git a/default.nix b/default.nix
index d2c51ec3..0efa75bb 100644
--- a/default.nix
+++ b/default.nix
@@ -1,8 +1,78 @@
-# Flake's default package for non-flake-enabled nix instances
-let
- compat = builtins.fetchTarball {
- url = "https://github.com/edolstra/flake-compat/archive/b4a34015c698c7793d592d66adbab377907a2be8.tar.gz";
- sha256 = "sha256:1qc703yg0babixi6wshn5wm2kgl5y1drcswgszh4xxzbrwkk9sv7";
- };
+{
+ lib,
+ rustPlatform,
+ callPackage,
+ runCommand,
+ installShellFiles,
+ git,
+ ...
+}: let
+ fs = lib.fileset;
+
+ src = fs.difference (fs.gitTracked ./.) (fs.unions [
+ ./.envrc
+ ./rustfmt.toml
+ ./screenshot.png
+ ./book
+ ./docs
+ ./flake.lock
+ (fs.fileFilter (file: lib.strings.hasInfix ".git" file.name) ./.)
+ (fs.fileFilter (file: file.hasExt "svg") ./.)
+ (fs.fileFilter (file: file.hasExt "md") ./.)
+ (fs.fileFilter (file: file.hasExt "nix") ./.)
+ ]);
+
+ # Next we actually need to build the grammars and the runtime directory
+ # that they reside in. It is built by calling the derivation in the
+ # grammars.nix file, then taking the runtime directory in the git repo
+ # and hooking symlinks up to it.
+ grammars = callPackage ./grammars.nix {};
+ runtimeDir = runCommand "helix-runtime" {} ''
+ mkdir -p $out
+ ln -s ${./runtime}/* $out
+ rm -r $out/grammars
+ ln -s ${grammars} $out/grammars
+ '';
in
- (import compat {src = ./.;}).defaultNix
+ # Currently rustPlatform.buildRustPackage doesn't have the finalAttrs pattern
+ # hooked up. To get around this while having good customization, mkDerivation is
+ # used instead.
+ rustPlatform.buildRustPackage (self: {
+ cargoLock.lockFile = ./Cargo.lock;
+
+ nativeBuildInputs = [
+ installShellFiles
+ git
+ ];
+
+ buildType = "release";
+
+ name = with builtins; (fromTOML (readFile ./helix-term/Cargo.toml)).package.name;
+ src = fs.toSource {
+ root = ./.;
+ fileset = src;
+ };
+
+ # Helix attempts to reach out to the network and get the grammars. Nix doesn't allow this.
+ HELIX_DISABLE_AUTO_GRAMMAR_BUILD = "1";
+
+ # So Helix knows what rev it is.
+ HELIX_NIX_BUILD_REV = self.rev or self.dirtyRev or null;
+
+ doCheck = false;
+ strictDeps = true;
+
+ # Sets the Helix runtimedir to the grammars
+ env.HELIX_DEFAULT_RUNTIME = "${runtimeDir}";
+
+ # Get all the application stuff in the output directory.
+ postInstall = ''
+ mkdir -p $out/lib
+ installShellCompletion ${./contrib/completion}/hx.{bash,fish,zsh}
+ mkdir -p $out/share/{applications,icons/hicolor/256x256/apps}
+ cp ${./contrib/Helix.desktop} $out/share/applications
+ cp ${./contrib/helix.png} $out/share/icons/hicolor/256x256/apps
+ '';
+
+ meta.mainProgram = "hx";
+ })
diff --git a/flake.lock b/flake.lock
index 62ff3447..7e3d5bd3 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,20 +1,5 @@
{
"nodes": {
- "crane": {
- "locked": {
- "lastModified": 1737563566,
- "narHash": "sha256-GLJvkOG29XCynQm8XWPyykMRqIhxKcBARVu7Ydrz02M=",
- "owner": "ipetkov",
- "repo": "crane",
- "rev": "849376434956794ebc7a6b487d31aace395392ba",
- "type": "github"
- },
- "original": {
- "owner": "ipetkov",
- "repo": "crane",
- "type": "github"
- }
- },
"flake-utils": {
"inputs": {
"systems": "systems"
@@ -35,11 +20,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1728018373,
- "narHash": "sha256-NOiTvBbRLIOe5F6RbHaAh6++BNjsb149fGZd1T4+KBg=",
+ "lastModified": 1740560979,
+ "narHash": "sha256-Vr3Qi346M+8CjedtbyUevIGDZW8LcA1fTG0ugPY/Hic=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "bc947f541ae55e999ffdb4013441347d83b00feb",
+ "rev": "5135c59491985879812717f4c9fea69604e7f26f",
"type": "github"
},
"original": {
@@ -51,7 +36,6 @@
},
"root": {
"inputs": {
- "crane": "crane",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
@@ -64,11 +48,11 @@
]
},
"locked": {
- "lastModified": 1737599167,
- "narHash": "sha256-S2rHCrQWCDVp63XxL/AQbGr1g5M8Zx14C7Jooa4oM8o=",
+ "lastModified": 1740623427,
+ "narHash": "sha256-3SdPQrZoa4odlScFDUHd4CUPQ/R1gtH4Mq9u8CBiK8M=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "38374302ae9edf819eac666d1f276d62c712dd06",
+ "rev": "d342e8b5fd88421ff982f383c853f0fc78a847ab",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 1fda3fa9..7d176cb0 100644
--- a/flake.nix
+++ b/flake.nix
@@ -8,13 +8,11 @@
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
- crane.url = "github:ipetkov/crane";
};
outputs = {
self,
nixpkgs,
- crane,
flake-utils,
rust-overlay,
...
@@ -24,167 +22,56 @@
inherit system;
overlays = [(import rust-overlay)];
};
- mkRootPath = rel:
- builtins.path {
- path = "${toString ./.}/${rel}";
- name = rel;
- };
- filteredSource = let
- pathsToIgnore = [
- ".envrc"
- ".ignore"
- ".github"
- ".gitignore"
- "logo_dark.svg"
- "logo_light.svg"
- "rust-toolchain.toml"
- "rustfmt.toml"
- "runtime"
- "screenshot.png"
- "book"
- "docs"
- "README.md"
- "CHANGELOG.md"
- "shell.nix"
- "default.nix"
- "grammars.nix"
- "flake.nix"
- "flake.lock"
- ];
- ignorePaths = path: type: let
- inherit (nixpkgs) lib;
- # split the nix store path into its components
- components = lib.splitString "/" path;
- # drop off the `/nix/hash-source` section from the path
- relPathComponents = lib.drop 4 components;
- # reassemble the path components
- relPath = lib.concatStringsSep "/" relPathComponents;
- in
- lib.all (p: ! (lib.hasPrefix p relPath)) pathsToIgnore;
- in
- builtins.path {
- name = "helix-source";
- path = toString ./.;
- # filter out unnecessary paths
- filter = ignorePaths;
- };
- makeOverridableHelix = old: config: let
- grammars = pkgs.callPackage ./grammars.nix config;
- runtimeDir = pkgs.runCommand "helix-runtime" {} ''
- mkdir -p $out
- ln -s ${mkRootPath "runtime"}/* $out
- rm -r $out/grammars
- ln -s ${grammars} $out/grammars
- '';
- helix-wrapped =
- pkgs.runCommand
- old.name
- {
- inherit (old) pname version;
- meta = old.meta or {};
- passthru =
- (old.passthru or {})
- // {
- unwrapped = old;
- };
- nativeBuildInputs = [pkgs.makeWrapper];
- makeWrapperArgs = config.makeWrapperArgs or [];
- }
- ''
- cp -rs --no-preserve=mode,ownership ${old} $out
- wrapProgram "$out/bin/hx" ''${makeWrapperArgs[@]} --set HELIX_RUNTIME "${runtimeDir}"
- '';
- in
- helix-wrapped
- // {
- override = makeOverridableHelix old;
- passthru =
- helix-wrapped.passthru
- // {
- wrapper = old: makeOverridableHelix old config;
- };
- };
- stdenv =
- if pkgs.stdenv.isLinux
- then pkgs.stdenv
- else pkgs.clangStdenv;
- rustFlagsEnv = pkgs.lib.optionalString stdenv.isLinux "-C link-arg=-fuse-ld=lld -C target-cpu=native -Clink-arg=-Wl,--no-rosegment --cfg tokio_unstable";
- rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
- craneLibMSRV = (crane.mkLib pkgs).overrideToolchain rustToolchain;
- craneLibStable = (crane.mkLib pkgs).overrideToolchain pkgs.pkgsBuildHost.rust-bin.stable.latest.default;
- commonArgs = {
- inherit stdenv;
- inherit (craneLibMSRV.crateNameFromCargoToml {cargoToml = ./helix-term/Cargo.toml;}) pname;
- inherit (craneLibMSRV.crateNameFromCargoToml {cargoToml = ./Cargo.toml;}) version;
- src = filteredSource;
- # disable fetching and building of tree-sitter grammars in the helix-term build.rs
- HELIX_DISABLE_AUTO_GRAMMAR_BUILD = "1";
- buildInputs = [stdenv.cc.cc.lib];
- nativeBuildInputs = [pkgs.installShellFiles];
- # disable tests
- doCheck = false;
- meta.mainProgram = "hx";
+
+ # Get Helix's MSRV toolchain to build with by default.
+ msrvToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
+ msrvPlatform = pkgs.makeRustPlatform {
+ cargo = msrvToolchain;
+ rustc = msrvToolchain;
};
- cargoArtifacts = craneLibMSRV.buildDepsOnly commonArgs;
in {
- packages = {
- helix-unwrapped = craneLibStable.buildPackage (commonArgs
- // {
- cargoArtifacts = craneLibStable.buildDepsOnly commonArgs;
- postInstall = ''
- mkdir -p $out/share/applications $out/share/icons/hicolor/scalable/apps $out/share/icons/hicolor/256x256/apps
- cp contrib/Helix.desktop $out/share/applications
- cp logo.svg $out/share/icons/hicolor/scalable/apps/helix.svg
- cp contrib/helix.png $out/share/icons/hicolor/256x256/apps
- installShellCompletion contrib/completion/hx.{bash,fish,zsh}
- '';
- # set git revision for nix flake builds, see 'git_hash' in helix-loader/build.rs
- HELIX_NIX_BUILD_REV = self.rev or self.dirtyRev or null;
- });
- helix = makeOverridableHelix self.packages.${system}.helix-unwrapped {};
- default = self.packages.${system}.helix;
- };
+ packages = rec {
+ helix = pkgs.callPackage ./default.nix {};
- checks = {
- # Build the crate itself
- inherit (self.packages.${system}) helix;
-
- clippy = craneLibMSRV.cargoClippy (commonArgs
- // {
- inherit cargoArtifacts;
- cargoClippyExtraArgs = "--all-targets -- --deny warnings";
- });
-
- fmt = craneLibMSRV.cargoFmt commonArgs;
-
- doc = craneLibMSRV.cargoDoc (commonArgs
- // {
- inherit cargoArtifacts;
- });
-
- test = craneLibMSRV.cargoTest (commonArgs
- // {
- inherit cargoArtifacts;
- });
+ # The default Helix build. Uses the latest stable Rust toolchain, and unstable
+ # nixpkgs.
+ #
+ # This can be overridden though to add Cargo Features, flags, and different toolchains with
+ # packages.${system}.default.override { ... };
+ default = helix;
};
- devShells.default = pkgs.mkShell {
- inputsFrom = builtins.attrValues self.checks.${system};
- nativeBuildInputs = with pkgs;
- [lld_13 cargo-flamegraph rust-analyzer]
- ++ (lib.optional (stdenv.isx86_64 && stdenv.isLinux) pkgs.cargo-tarpaulin)
- ++ (lib.optional stdenv.isLinux pkgs.lldb)
- ++ (lib.optional stdenv.isDarwin pkgs.darwin.apple_sdk.frameworks.CoreFoundation);
- shellHook = ''
- export HELIX_RUNTIME="$PWD/runtime"
- export RUST_BACKTRACE="1"
- export RUSTFLAGS="''${RUSTFLAGS:-""} ${rustFlagsEnv}"
- '';
+ checks.helix = self.outputs.packages.${system}.helix.override {
+ buildType = "debug";
+ rustPlatform = msrvPlatform;
};
+
+ # Devshell behavior is preserved.
+ devShells.default = let
+ rustFlagsEnv = pkgs.lib.optionalString pkgs.stdenv.isLinux "-C link-arg=-fuse-ld=lld -C target-cpu=native -Clink-arg=-Wl,--no-rosegment --cfg tokio_unstable";
+ in
+ pkgs.mkShell
+ {
+ inputsFrom = [self.checks.${system}.helix];
+ nativeBuildInputs = with pkgs;
+ [
+ lld_13
+ cargo-flamegraph
+ rust-bin.nightly.latest.rust-analyzer
+ ]
+ ++ (lib.optional (stdenv.isx86_64 && stdenv.isLinux) cargo-tarpaulin)
+ ++ (lib.optional stdenv.isLinux lldb)
+ ++ (lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.CoreFoundation);
+ shellHook = ''
+ export HELIX_RUNTIME="$PWD/runtime"
+ export RUST_BACKTRACE="1"
+ export RUSTFLAGS="''${RUSTFLAGS:-""} ${rustFlagsEnv}"
+ '';
+ };
})
// {
overlays.default = final: prev: {
- inherit (self.packages.${final.system}) helix;
+ helix = final.callPackage ./default.nix {};
};
};
diff --git a/grammars.nix b/grammars.nix
index 967b1b13..bc99d21d 100644
--- a/grammars.nix
+++ b/grammars.nix
@@ -32,10 +32,10 @@
# If `use-grammars.except` is set, use all other grammars.
# Otherwise use all grammars.
useGrammar = grammar:
- if languagesConfig?use-grammars.only then
- builtins.elem grammar.name languagesConfig.use-grammars.only
- else if languagesConfig?use-grammars.except then
- !(builtins.elem grammar.name languagesConfig.use-grammars.except)
+ if languagesConfig ? use-grammars.only
+ then builtins.elem grammar.name languagesConfig.use-grammars.only
+ else if languagesConfig ? use-grammars.except
+ then !(builtins.elem grammar.name languagesConfig.use-grammars.except)
else true;
grammarsToUse = builtins.filter useGrammar languagesConfig.grammar;
gitGrammars = builtins.filter isGitGrammar grammarsToUse;
@@ -66,10 +66,10 @@
version = grammar.source.rev;
src = source;
- sourceRoot = if builtins.hasAttr "subpath" grammar.source then
- "source/${grammar.source.subpath}"
- else
- "source";
+ sourceRoot =
+ if builtins.hasAttr "subpath" grammar.source
+ then "source/${grammar.source.subpath}"
+ else "source";
dontConfigure = true;
@@ -116,15 +116,19 @@
'';
};
grammarsToBuild = builtins.filter includeGrammarIf gitGrammars;
- builtGrammars = builtins.map (grammar: {
- inherit (grammar) name;
- value = buildGrammar grammar;
- }) grammarsToBuild;
+ builtGrammars =
+ builtins.map (grammar: {
+ inherit (grammar) name;
+ value = buildGrammar grammar;
+ })
+ grammarsToBuild;
extensibleGrammars =
lib.makeExtensible (self: builtins.listToAttrs builtGrammars);
- overlaidGrammars = lib.pipe extensibleGrammars
+ overlaidGrammars =
+ lib.pipe extensibleGrammars
(builtins.map (overlay: grammar: grammar.extend overlay) grammarOverlays);
- grammarLinks = lib.mapAttrsToList
+ grammarLinks =
+ lib.mapAttrsToList
(name: artifact: "ln -s ${artifact}/${name}.so $out/${name}.so")
(lib.filterAttrs (n: v: lib.isDerivation v) overlaidGrammars);
in