2020-07-03 15:22:21 +03:00
{
2022-12-05 19:28:45 +03:00
inputs = {
nixpkgs . url = " n i x p k g s / n i x o s - u n s t a b l e " ;
flake-utils . url = " g i t h u b : n u m t i d e / f l a k e - u t i l s " ;
pre-commit-hooks = {
url = " g i t h u b : c a c h i x / p r e - c o m m i t - h o o k s . n i x " ;
inputs . nixpkgs . follows = " n i x p k g s " ;
inputs . flake-utils . follows = " f l a k e - u t i l s " ;
} ;
rust-overlay = {
url = " g i t h u b : o x a l i c a / r u s t - o v e r l a y " ;
inputs . nixpkgs . follows = " n i x p k g s " ;
inputs . flake-utils . follows = " f l a k e - u t i l s " ;
} ;
crane = {
url = " g i t h u b : i p e t k o v / c r a n e " ;
inputs . nixpkgs . follows = " n i x p k g s " ;
} ;
2023-03-28 17:02:30 +03:00
topiary = {
url = " g i t h u b : t w e a g / t o p i a r y " ;
inputs . nixpkgs . follows = " n i x p k g s " ;
} ;
2022-12-05 19:28:45 +03:00
} ;
2020-07-03 15:22:21 +03:00
2021-11-17 14:25:22 +03:00
nixConfig = {
2022-08-01 16:51:45 +03:00
extra-substituters = [ " h t t p s : / / t w e a g - n i c k e l . c a c h i x . o r g " ] ;
extra-trusted-public-keys = [ " t w e a g - n i c k e l . c a c h i x . o r g - 1 : G I t h u i K 4 L R g n W 6 4 A L Y E o i o V U Q B W s 0 j e x y o Y V e L D B w R A = " ] ;
2021-11-17 14:25:22 +03:00
} ;
2022-01-19 01:11:10 +03:00
outputs =
{ self
, nixpkgs
, flake-utils
, pre-commit-hooks
, rust-overlay
2022-12-05 19:28:45 +03:00
, crane
2023-03-28 17:02:30 +03:00
, topiary
2022-01-19 01:11:10 +03:00
} :
2020-07-03 15:22:21 +03:00
let
2021-01-15 16:23:16 +03:00
SYSTEMS = [
2021-09-13 22:20:54 +03:00
" a a r c h 6 4 - d a r w i n "
" a a r c h 6 4 - l i n u x "
2021-01-15 16:23:16 +03:00
" x 8 6 _ 6 4 - d a r w i n "
2021-09-13 22:20:54 +03:00
" x 8 6 _ 6 4 - l i n u x "
2021-01-15 16:23:16 +03:00
] ;
2021-01-15 16:16:59 +03:00
2022-01-17 14:53:18 +03:00
RUST_CHANNELS = [
2021-01-23 21:46:38 +03:00
" s t a b l e "
" b e t a "
] ;
2022-01-19 01:11:10 +03:00
forEachRustChannel = fn : builtins . listToAttrs ( builtins . map fn RUST_CHANNELS ) ;
2022-01-15 00:47:05 +03:00
cargoTOML = builtins . fromTOML ( builtins . readFile ./Cargo.toml ) ;
2023-06-16 19:34:13 +03:00
cargoLock = builtins . fromTOML ( builtins . readFile ./Cargo.lock ) ;
2022-01-15 00:47:05 +03:00
2023-08-30 18:23:10 +03:00
inherit ( cargoTOML . workspace . package ) version ;
2022-01-17 01:17:41 +03:00
2022-01-19 01:11:10 +03:00
in
flake-utils . lib . eachSystem SYSTEMS ( system :
let
pkgs = import nixpkgs {
inherit system ;
overlays = [
( import rust-overlay )
2023-09-06 12:14:59 +03:00
# gnulib tests in diffutils fail for musl arm64, cf. https://github.com/NixOS/nixpkgs/pull/241281
( final : prev : {
diffutils =
if ! ( final . stdenv . hostPlatform . isMusl && final . stdenv . hostPlatform . isAarch64 ) then
prev . diffutils
else
prev . diffutils . overrideAttrs ( old : {
postPatch = ''
sed - i ' s:gnulib-tests::g' Makefile . in
'' ;
} ) ;
} )
2022-01-19 01:11:10 +03:00
] ;
} ;
2023-08-08 00:13:42 +03:00
wasm-bindgen-cli =
let
wasmBindgenCargoVersions = builtins . map ( { version , . . . }: version ) ( builtins . filter ( { name , . . . }: name == " w a s m - b i n d g e n " ) cargoLock . package ) ;
wasmBindgenVersion = assert builtins . length wasmBindgenCargoVersions == 1 ; builtins . elemAt wasmBindgenCargoVersions 0 ;
in
pkgs . wasm-bindgen-cli . override {
version = wasmBindgenVersion ;
hash = " s h a 2 5 6 - 0 r K + Y x 4 / J y 4 4 F w 5 V w J 3 t G 2 4 3 Z s y O I B B e h Y U 5 4 X P / J G k = " ;
cargoHash = " s h a 2 5 6 - v c p x c R l W 1 O K o D 6 4 o w F F 6 m k x S q m N r v Y + y 3 C k n 5 U w E Q 5 0 = " ;
} ;
2022-12-21 14:36:53 +03:00
# Additional packages required to build Nickel on Darwin
2023-08-07 14:55:13 +03:00
systemSpecificPkgs =
2022-01-19 01:11:10 +03:00
if pkgs . stdenv . isDarwin then
[
pkgs . darwin . apple_sdk . frameworks . Security
pkgs . darwin . libiconv
]
else
[ ] ;
2022-01-19 11:23:22 +03:00
mkRust =
2023-06-02 10:39:21 +03:00
let
inherit ( pkgs . stdenv ) hostPlatform ;
inherit ( pkgs . rust ) toRustTarget ;
in
2022-01-19 11:23:22 +03:00
{ rustProfile ? " m i n i m a l "
, rustExtensions ? [
" r u s t - s r c "
" r u s t - a n a l y s i s "
2022-12-05 19:28:45 +03:00
" r u s t f m t "
" c l i p p y "
2022-01-19 11:23:22 +03:00
]
, channel ? " s t a b l e "
2023-06-02 10:39:21 +03:00
, targets ? [ ( toRustTarget hostPlatform ) ]
++ pkgs . lib . optional ( ! hostPlatform . isMacOS ) ( toRustTarget pkgs . pkgsMusl . stdenv . hostPlatform )
2022-01-19 11:23:22 +03:00
} :
2022-12-05 19:28:45 +03:00
if channel == " n i g h t l y " then
pkgs . rust-bin . selectLatestNightlyWith
( toolchain : toolchain . ${ rustProfile } . override {
extensions = rustExtensions ;
2023-06-02 10:39:21 +03:00
inherit targets ;
2022-12-05 19:28:45 +03:00
} )
else
pkgs . rust-bin . ${ channel } . latest . ${ rustProfile } . override {
extensions = rustExtensions ;
2023-06-02 10:39:21 +03:00
inherit targets ;
2022-12-05 19:28:45 +03:00
} ;
2022-01-19 11:23:22 +03:00
2022-12-06 12:50:37 +03:00
# A note on check_format: the way we invoke rustfmt here works locally but fails on CI.
# Since the formatting is checked on CI anyway - as part of the rustfmt check - we
# disable rustfmt in the pre-commit hook when running checks, but enable it when
# running in a dev shell.
pre-commit-builder = { rust ? mkRust { } , checkFormat ? false }: pre-commit-hooks . lib . ${ system } . run {
2022-12-05 19:28:45 +03:00
src = self ;
hooks = {
nixpkgs-fmt = {
enable = true ;
# Excluded because they are generated by Node2nix
excludes = [
2023-06-29 14:40:35 +03:00
" l s p / v s c o d e - e x t e n s i o n / d e f a u l t . n i x "
" l s p / v s c o d e - e x t e n s i o n / n o d e - e n v . n i x "
" l s p / v s c o d e - e x t e n s i o n / n o d e - p a c k a g e s . n i x "
2022-12-05 19:28:45 +03:00
] ;
} ;
2022-01-19 11:23:22 +03:00
2022-12-05 19:28:45 +03:00
rustfmt = {
2022-12-06 12:50:37 +03:00
enable = checkFormat ;
entry = pkgs . lib . mkForce " ${ rust } / b i n / c a r g o - f m t f m t - - - - c h e c k - - c o l o r a l w a y s " ;
2022-12-05 19:28:45 +03:00
} ;
2022-01-19 01:11:10 +03:00
2022-12-05 19:28:45 +03:00
markdownlint = {
enable = true ;
excludes = [
" n o t e s / ( . + ) \\ . m d $ "
" ^ R E L E A S E S \\ . m d $ "
] ;
} ;
2022-01-17 14:53:18 +03:00
2023-06-22 12:41:50 +03:00
# we could use pre-commit-hook's built-in topiary, be for now, Topiary
# is evolving quickly and we prefer to have the latest version.
# This might change once the Nickel support is stabilized.
topiary-latest = topiary . lib . ${ system } . pre-commit-hook // {
enable = true ;
2023-06-30 18:50:04 +03:00
# Some tests are currently failing the idempotency check, and
# formatting is less important there. We at least want the examples
# as well as the stdlib to be properly formatted.
2023-06-22 12:41:50 +03:00
files = " \\ . n c l $ " ;
excludes = [
" / t e s t s / ( . + ) \\ . n c l $ "
] ;
} ;
2022-12-05 19:28:45 +03:00
} ;
} ;
2022-11-17 20:18:49 +03:00
2022-12-21 14:36:53 +03:00
# Customize source filtering for Crane as Nickel uses non-standard-Rust
# files like `*.lalrpop`.
filterNickelSrc = filterCargoSources :
let
mkFilter = regexp : path : _type : builtins . match regexp path != null ;
lalrpopFilter = mkFilter " . * l a l r p o p $ " ;
nclFilter = mkFilter " . * n c l $ " ;
txtFilter = mkFilter " . * t x t $ " ;
2023-01-09 13:32:40 +03:00
snapFilter = mkFilter " . * s n a p $ " ;
2023-07-13 13:43:51 +03:00
scmFilter = mkFilter " . * s c m $ " ;
2023-09-19 16:09:58 +03:00
mdFilter = mkFilter " . * m d $ " ; # include markdown files for checking snippets in the documentation
2023-08-04 00:57:08 +03:00
importsFilter = mkFilter " . * / c o r e / t e s t s / i n t e g r a t i o n / i m p o r t s / i m p o r t e d / . * $ " ; # include all files that are imported in tests
2023-09-04 18:41:23 +03:00
infraFilter = mkFilter " . * / i n f r a / . * $ " ;
2022-12-21 14:36:53 +03:00
in
pkgs . lib . cleanSourceWith {
src = pkgs . lib . cleanSource ./. ;
# Combine our custom filters with the default one from Crane
# See https://github.com/ipetkov/crane/blob/master/docs/API.md#libfiltercargosources
filter = path : type :
builtins . any ( filter : filter path type ) [
lalrpopFilter
nclFilter
txtFilter
2023-01-09 13:32:40 +03:00
snapFilter
2023-07-13 13:43:51 +03:00
scmFilter
2023-09-19 16:09:58 +03:00
mdFilter
2022-12-21 14:36:53 +03:00
filterCargoSources
2023-08-04 00:57:08 +03:00
importsFilter
2023-09-04 18:41:23 +03:00
] && ! ( builtins . any ( filter : filter path type ) [
infraFilter
] ) ;
2022-12-21 14:36:53 +03:00
} ;
2023-09-11 11:53:20 +03:00
# if we directly set the revision, it would invalidate the cache on every commit.
# instead we set a static dummy hash and edit the binary in a separate (fast) derivation.
dummyRev = " D U M M Y R E V _ T H I S _ S H O U L D _ N O T _ A P P E A R _ a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a " ;
# pad a string with the tail of another string
padWith = pad : str :
str +
builtins . substring
( builtins . stringLength str )
( builtins . stringLength pad )
pad ;
# We want `nickel --version` to print the git revision that nickel
# was compiled from. However, putting self.shortRev in a derivation
# invalidates the cache on any change, even if otherwise the derivation
# is identical. To mitigate this, we pass an unchanging string as the
# revision in `NICKEL_NIX_BUILD_REV`, and then have a small wrapper that
# replaces that string in the output binary. On every new commit this fast
# derivation will have to be rebuilt, but the slow compilation of rust
# code will only happen on more substantial changes.
# This is only needed for binaries that actually make use of this
# information (just the cli)
fixupGitRevision = pkg : pkgs . stdenv . mkDerivation {
pname = pkg . pname + " - r e v - f i x u p " ;
inherit ( pkg ) version meta ;
src = pkg ;
buildInputs = [ pkgs . bbe ] ;
phases = [ " f i x u p P h a s e " ] ;
fixupPhase = ''
mkdir - p $ out/bin
for srcBin in $ src/bin /* ; d o
outBin = " $ o u t / b i n / $ ( b a s e n a m e $ s r c B i n ) "
# [dirty] must have 7 characters to match dummyRev (hard coded in nickel-lang-cli)
# we have to pad them out to the same length as dummyRev so they fit
# in the same spot in the binary
bbe - e ' s / $ { dummyRev } / $ { padWith dummyRev ( self . shortRev or " [ d i r t y ] " ) } / ' \
$ srcBin > $ outBin
chmod + x $ outBin
done
'' ;
} ;
2022-12-21 14:36:53 +03:00
# Given a rust toolchain, provide Nickel's Rust dependencies, Nickel, as
# well as rust tools (like clippy)
2023-02-15 20:36:31 +03:00
mkCraneArtifacts = { rust ? mkRust { } , noRunBench ? false }:
2022-12-05 19:28:45 +03:00
let
craneLib = crane . lib . ${ system } . overrideToolchain rust ;
2023-08-30 18:23:10 +03:00
# suffixes get added via pnameSuffix
pname = " n i c k e l - l a n g " ;
2022-12-05 19:28:45 +03:00
# Customize source filtering as Nickel uses non-standard-Rust files like `*.lalrpop`.
2022-12-21 14:36:53 +03:00
src = filterNickelSrc craneLib . filterCargoSources ;
2022-11-17 20:18:49 +03:00
2023-01-14 18:03:32 +03:00
# set of cargo args common to all builds
cargoBuildExtraArgs = " - - f r o z e n - - o f f l i n e " ;
2022-12-05 19:28:45 +03:00
# Build *just* the cargo dependencies, so we can reuse all of that work (e.g. via cachix) when running in CI
cargoArtifacts = craneLib . buildDepsOnly {
2023-08-30 18:23:10 +03:00
inherit pname src ;
2023-09-24 02:41:06 +03:00
cargoExtraArgs = " ${ cargoBuildExtraArgs } - - a l l - f e a t u r e s " ;
# If we build all the packages at once, feature unification takes
# over and we get libraries with different sets of features than
# we would get building them separately. Meaning that when we
# later build them separately, it won't hit the cache. So instead,
# we need to build each package separately when we are collecting
# dependencies.
cargoBuildCommand = " c a r g o W o r k s p a c e b u i l d " ;
cargoTestCommand = " c a r g o W o r k s p a c e t e s t " ;
cargoCheckCommand = " c a r g o W o r k s p a c e c h e c k " ;
preBuild = ''
cargoWorkspace ( ) {
command = $ ( shift )
for packageDir in $ ( $ { pkgs . yq } /bin/tomlq - r ' . workspace . members [ ] ' Cargo . toml ) ; do
(
cd $ packageDir
pwd
cargoWithProfile $ command " $ @ "
)
done
}
'' ;
2023-01-16 17:28:57 +03:00
# pyo3 needs a Python interpreter in the build environment
# https://pyo3.rs/v0.17.3/building_and_distribution#configuring-the-python-version
2023-01-14 18:03:32 +03:00
buildInputs = [ pkgs . python3 ] ;
2022-01-17 01:17:41 +03:00
} ;
2021-08-31 12:05:36 +03:00
2023-08-07 14:55:13 +03:00
env = {
2023-09-11 11:53:20 +03:00
NICKEL_NIX_BUILD_REV = dummyRev ;
2023-08-07 14:55:13 +03:00
} ;
2023-09-06 12:14:59 +03:00
buildPackage = { pnameSuffix , cargoPackage ? " ${ pname } ${ pnameSuffix } " , extraBuildArgs ? " " , extraArgs ? { } }:
2023-06-02 10:39:21 +03:00
craneLib . buildPackage ( {
2023-01-14 18:03:32 +03:00
inherit
2023-01-27 18:11:17 +03:00
pname
2023-08-30 18:23:10 +03:00
pnameSuffix
2023-01-14 18:03:32 +03:00
src
2023-06-16 19:34:13 +03:00
version
2023-09-11 11:53:20 +03:00
cargoArtifacts ;
2023-01-14 18:03:32 +03:00
2023-09-06 12:14:59 +03:00
cargoExtraArgs = " ${ cargoBuildExtraArgs } ${ extraBuildArgs } - - p a c k a g e ${ cargoPackage } " ;
2023-06-02 10:39:21 +03:00
} // extraArgs ) ;
2023-01-14 18:03:32 +03:00
in
2023-06-02 10:39:21 +03:00
rec {
2023-06-16 19:34:13 +03:00
inherit cargoArtifacts ;
2023-08-30 18:23:10 +03:00
nickel-lang-core = buildPackage { pnameSuffix = " - c o r e " ; } ;
2023-09-11 11:53:20 +03:00
nickel-lang-cli = fixupGitRevision ( buildPackage {
pnameSuffix = " - c l i " ;
extraArgs = {
inherit env ;
meta . mainProgram = " n i c k e l " ;
} ;
} ) ;
lsp-nls = buildPackage {
pnameSuffix = " - l s p " ;
extraArgs . meta . mainProgram = " n l s " ;
} ;
2023-06-02 10:39:21 +03:00
2023-07-17 17:06:29 +03:00
# Static building isn't really possible on MacOS because the system call ABIs aren't stable.
2023-06-02 10:39:21 +03:00
nickel-static =
if pkgs . stdenv . hostPlatform . isMacOS
2023-06-16 19:34:13 +03:00
then nickel-lang-cli
2023-06-02 10:39:21 +03:00
else
2023-07-17 17:06:29 +03:00
# To build Nickel and its dependencies statically we use the musl
# libc and clang with libc++ to build C and C++ dependencies. We
# tried building with libstdc++ but without success.
2023-09-11 11:53:20 +03:00
fixupGitRevision
( buildPackage {
cargoPackage = " n i c k e l - l a n g - c l i " ;
pnameSuffix = " - s t a t i c " ;
extraArgs = {
inherit env ;
CARGO_BUILD_TARGET = pkgs . rust . toRustTarget pkgs . pkgsMusl . stdenv . hostPlatform ;
# For some reason, the rust build doesn't pick up the paths
# to `libcxx` and `libcxxabi` from the stdenv. So we specify
# them explicitly. Also, `libcxx` expects to be linked with
# `libcxxabi` at the end, and we need to make the rust linker
# aware of that.
#
# We also explicitly add `libc` because of https://github.com/rust-lang/rust/issues/89626.
RUSTFLAGS = " - L ${ pkgs . pkgsMusl . llvmPackages . libcxx } / l i b - L ${ pkgs . pkgsMusl . llvmPackages . libcxxabi } / l i b - l s t a t i c = c + + a b i - C l i n k - a r g = - l c " ;
# Explain to `cc-rs` that it should use the `libcxx` C++
# standard library, and a static version of it, when building
# C++ libraries. The `cc-rs` crate is typically used in
# upstream build.rs scripts.
CXXSTDLIB = " s t a t i c = c + + " ;
stdenv = pkgs . pkgsMusl . libcxxStdenv ;
doCheck = false ;
meta . mainProgram = " n i c k e l " ;
} ;
} ) ;
2022-01-17 14:53:18 +03:00
2023-02-13 11:59:06 +03:00
benchmarks = craneLib . mkCargoDerivation {
2023-08-30 18:23:10 +03:00
inherit pname src version cargoArtifacts env ;
2023-02-13 11:59:06 +03:00
2023-08-30 18:23:10 +03:00
pnameSuffix = " - b e n c h " ;
2023-02-13 11:59:06 +03:00
2023-02-15 20:36:31 +03:00
buildPhaseCargoCommand = ''
2023-06-26 19:58:40 +03:00
cargo bench - p nickel-lang-core $ { pkgs . lib . optionalString noRunBench " - - n o - r u n " }
2023-02-15 20:36:31 +03:00
'' ;
2023-02-13 11:59:06 +03:00
doInstallCargoArtifacts = false ;
} ;
2023-04-28 11:32:29 +03:00
# Check that documentation builds without warnings or errors
2023-08-30 18:23:10 +03:00
checkRustDoc = craneLib . cargoDoc {
inherit pname src version cargoArtifacts env ;
2023-04-28 11:32:29 +03:00
inherit ( cargoArtifacts ) buildInputs ;
2023-08-30 18:23:10 +03:00
RUSTDOCFLAGS = " - D w a r n i n g s " ;
2023-04-28 11:32:29 +03:00
2023-08-30 18:23:10 +03:00
cargoExtraArgs = " ${ cargoBuildExtraArgs } - - w o r k s p a c e - - a l l - f e a t u r e s " ;
2023-04-28 11:32:29 +03:00
doInstallCargoArtifacts = false ;
} ;
2022-12-05 19:28:45 +03:00
rustfmt = craneLib . cargoFmt {
# Notice that unlike other Crane derivations, we do not pass `cargoArtifacts` to `cargoFmt`, because it does not need access to dependencies to format the code.
2023-09-11 11:53:20 +03:00
inherit pname src ;
2022-01-17 01:17:41 +03:00
2022-12-05 19:28:45 +03:00
cargoExtraArgs = " - - a l l " ;
2022-01-17 01:17:41 +03:00
2022-12-05 19:28:45 +03:00
# `-- --check` is automatically prepended by Crane
rustFmtExtraArgs = " - - c o l o r a l w a y s " ;
} ;
2022-01-17 01:17:41 +03:00
2022-12-05 19:28:45 +03:00
clippy = craneLib . cargoClippy {
2023-08-30 18:23:10 +03:00
inherit pname src cargoArtifacts env ;
2023-02-28 19:08:42 +03:00
inherit ( cargoArtifacts ) buildInputs ;
2023-01-14 18:03:32 +03:00
cargoExtraArgs = cargoBuildExtraArgs ;
2023-02-28 19:08:42 +03:00
cargoClippyExtraArgs = " - - a l l - f e a t u r e s - - a l l - t a r g e t s - - w o r k s p a c e - - - - d e n y w a r n i n g s - - a l l o w c l i p p y : : n e w - w i t h o u t - d e f a u l t - - a l l o w c l i p p y : : m a t c h _ l i k e _ m a t c h e s _ m a c r o " ;
2022-12-05 19:28:45 +03:00
} ;
2022-11-17 20:18:49 +03:00
} ;
2021-08-31 12:05:36 +03:00
2022-11-17 20:18:49 +03:00
makeDevShell = { rust }: pkgs . mkShell {
2022-12-05 19:28:45 +03:00
# Trick found in Crane's examples to get a nice dev shell
# See https://github.com/ipetkov/crane/blob/master/examples/quick-start/flake.nix
inputsFrom = builtins . attrValues ( mkCraneArtifacts { inherit rust ; } ) ;
2022-11-21 14:42:16 +03:00
buildInputs = [
pkgs . rust-analyzer
2023-01-09 13:32:40 +03:00
pkgs . cargo-insta
pkgs . nixpkgs-fmt
2022-11-21 14:42:16 +03:00
pkgs . nodejs
2023-06-28 12:24:39 +03:00
pkgs . yarn
pkgs . yarn2nix
2022-11-21 14:42:16 +03:00
pkgs . nodePackages . markdownlint-cli
2023-01-08 21:45:01 +03:00
pkgs . python3
2023-03-28 17:02:30 +03:00
topiary . packages . ${ system } . default
2022-11-21 14:42:16 +03:00
] ;
2021-02-07 21:43:11 +03:00
2022-12-06 12:50:37 +03:00
shellHook = ( pre-commit-builder { inherit rust ; checkFormat = true ; } ) . shellHook + ''
2022-11-17 20:18:49 +03:00
echo " = = = N i c k e l d e v e l o p m e n t s h e l l = = = "
echo " I n f o : G i t h o o k s c a n b e i n s t a l l e d u s i n g \` p r e - c o m m i t i n s t a l l \` "
'' ;
RUST_SRC_PATH = " ${ rust } / l i b / r u s t l i b / s r c / r u s t / l i b r a r y " ;
} ;
2021-01-24 13:18:00 +03:00
2022-12-21 14:36:53 +03:00
# Profile is passed to `wasm-pack`, and is either "dev" (with debug
# symbols and no optimization), "release" (with optimization and without
# debug symbols) or "profiling". Right now only dev and release are used:
# - release for the production build
# - dev for checks, as the code isn't optimized, and WASM optimization
# takes time
2022-06-15 12:02:48 +03:00
buildNickelWasm =
2023-06-02 10:39:21 +03:00
{ rust ? mkRust { targets = [ " w a s m 3 2 - u n k n o w n - u n k n o w n " ] ; }
2022-12-21 14:36:53 +03:00
, profile ? " r e l e a s e "
2022-01-19 01:11:10 +03:00
} :
2022-12-21 14:36:53 +03:00
let
# Build the various Crane artifacts (dependencies, packages, rustfmt, clippy) for a given Rust toolchain
craneLib = crane . lib . ${ system } . overrideToolchain rust ;
2021-09-27 18:02:07 +03:00
2023-08-30 18:23:10 +03:00
# suffixes get added via pnameSuffix
pname = " n i c k e l - l a n g - w a s m " ;
2022-12-21 14:36:53 +03:00
# Customize source filtering as Nickel uses non-standard-Rust files like `*.lalrpop`.
src = filterNickelSrc craneLib . filterCargoSources ;
2021-09-27 18:02:07 +03:00
2023-06-26 19:58:40 +03:00
cargoExtraArgs = " - p n i c k e l - w a s m - r e p l - - t a r g e t w a s m 3 2 - u n k n o w n - u n k n o w n - - f r o z e n - - o f f l i n e " ;
2022-12-25 14:17:39 +03:00
# * --mode no-install prevents wasm-pack from trying to download and
2022-12-21 14:36:53 +03:00
# vendor tools like wasm-bindgen, wasm-opt, etc. but use the one
# provided by Nix
# * --no-default-features disable some default features of Nickel that
2022-12-25 14:17:39 +03:00
# aren't useful for the WASM REPL (and possibly incompatible with
2022-12-21 14:36:53 +03:00
# WASM build)
wasmPackExtraArgs = " - - ${ profile } - - m o d e n o - i n s t a l l - - - - n o - d e f a u l t - f e a t u r e s - - f r o z e n - - o f f l i n e " ;
2022-01-19 11:23:22 +03:00
2022-12-21 14:36:53 +03:00
# Build *just* the cargo dependencies, so we can reuse all of that work (e.g. via cachix) when running in CI
cargoArtifacts = craneLib . buildDepsOnly {
2023-08-30 18:23:10 +03:00
inherit pname src cargoExtraArgs ;
2022-12-21 14:36:53 +03:00
doCheck = false ;
} ;
in
craneLib . mkCargoDerivation {
2023-08-30 18:23:10 +03:00
inherit pname cargoArtifacts src ;
2022-12-21 14:36:53 +03:00
buildPhaseCargoCommand = ''
2023-06-26 19:58:40 +03:00
WASM_PACK_CACHE = . wasm-pack-cache wasm-pack build wasm-repl $ { wasmPackExtraArgs }
2022-01-19 01:11:10 +03:00
'' ;
2021-12-10 14:07:47 +03:00
2022-12-21 14:36:53 +03:00
# nickel-lang.org expects an interface `nickel-repl.wasm`, hence the
# `ln`
installPhaseCommand = ''
2022-01-19 11:23:22 +03:00
mkdir - p $ out
2023-06-26 19:58:40 +03:00
cp - r wasm-repl/pkg $ out/nickel-repl
ln - s $ out/nickel-repl/nickel_wasm_repl_bg.wasm $ out/nickel-repl/nickel_repl.wasm
2022-01-19 11:23:22 +03:00
'' ;
2022-12-21 14:36:53 +03:00
nativeBuildInputs = [
rust
pkgs . wasm-pack
2023-08-08 00:13:42 +03:00
wasm-bindgen-cli
2022-12-21 14:36:53 +03:00
pkgs . binaryen
2023-08-07 14:55:13 +03:00
# Used to include the git revision in the Nickel binary, for `--version`
pkgs . git
] ++ systemSpecificPkgs ;
2022-01-19 01:11:10 +03:00
} ;
2021-09-27 18:02:07 +03:00
2022-01-19 01:11:10 +03:00
buildDocker = nickel : pkgs . dockerTools . buildLayeredImage {
name = " n i c k e l " ;
tag = version ;
contents = [
nickel
] ;
config = {
2023-09-06 11:49:31 +03:00
Entrypoint = pkgs . lib . getExe nickel ;
2023-06-27 19:03:01 +03:00
# Labels that are recognized by GHCR
# See https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#labelling-container-images
Labels = {
" o r g . o p e n c o n t a i n e r s . i m a g e . s o u r c e " = " h t t p s : / / g i t h u b . c o m / t w e a g / n i c k e l " ;
" o r g . o p e n c o n t a i n e r s . i m a g e . d e s c r i p t i o n " = " N i c k e l : b e t t e r c o n f i g u r a t i o n f o r l e s s " ;
" o r g . o p e n c o n t a i n e r s . i m a g e . l i c e n s e s " = " M I T " ;
} ;
2022-01-19 01:11:10 +03:00
} ;
} ;
2021-09-27 18:02:07 +03:00
2023-06-28 12:24:39 +03:00
# Build the Nickel VSCode extension
vscodeExtension = pkgs . mkYarnPackage {
pname = " v s c o d e - n i c k e l " ;
2023-06-29 14:40:35 +03:00
src = pkgs . lib . cleanSource ./lsp/vscode-extension ;
2023-06-28 12:24:39 +03:00
buildPhase = ''
# yarn tries to create a .yarn file in $HOME. There's probably a
# better way to fix this but setting HOME to TMPDIR works for now.
export HOME = " $ T M P D I R "
cd deps/vscode-nickel
yarn - - offline compile
yarn - - offline vsce package - - yarn - o $ pname . vsix
'' ;
installPhase = ''
mkdir $ out
mv $ pname . vsix $ out
'' ;
distPhase = " t r u e " ;
} ;
2022-01-19 01:11:10 +03:00
2022-12-21 14:36:53 +03:00
# Copy the markdown user manual to $out.
2022-02-28 20:09:25 +03:00
userManual = pkgs . stdenv . mkDerivation {
name = " n i c k e l - u s e r - m a n u a l - ${ version } " ;
src = ./doc/manual ;
installPhase = ''
mkdir - p $ out
2022-06-21 20:32:33 +03:00
cp - r . / $ out
'' ;
} ;
2023-03-30 18:14:09 +03:00
# Generate the stdlib documentation from `nickel doc` as `format`.
stdlibDoc = format :
let
extension =
{
" m a r k d o w n " = " m d " ;
} . " ${ format } " or format ;
in
pkgs . stdenv . mkDerivation {
name = " n i c k e l - s t d l i b - d o c - ${ format } - ${ version } " ;
2023-06-26 19:58:40 +03:00
src = ./core/stdlib ;
2023-03-30 18:14:09 +03:00
installPhase = ''
mkdir - p $ out
for file in $ ( ls * . ncl | grep - v ' internals . ncl' )
do
module = $ ( basename $ file . ncl )
2023-09-06 11:49:31 +03:00
$ { pkgs . lib . getExe self . packages . " ${ system } " . default } doc - - format " ${ format } " - f " $ m o d u l e . n c l " \
2023-03-30 18:14:09 +03:00
- - output " $ o u t / $ m o d u l e . ${ extension } "
done
'' ;
} ;
2022-02-28 20:09:25 +03:00
2023-09-04 18:41:23 +03:00
infraShell = nickel :
let
terraform = pkgs . terraform . withPlugins ( p : with p ; [
archive
aws
github
] ) ;
ec2-region = " e u - n o r t h - 1 " ;
ec2-ami = ( import " ${ nixpkgs } / n i x o s / m o d u l e s / v i r t u a l i s a t i o n / a m a z o n - e c 2 - a m i s . n i x " ) . latest . ${ ec2-region } . aarch64-linux . hvm-ebs ;
run-terraform = pkgs . writeShellScriptBin " r u n - t e r r a f o r m " ''
set - e
2023-09-06 11:49:31 +03:00
$ { pkgs . lib . getExe nickel } export > main . tf . json < < EOF
2023-09-04 18:41:23 +03:00
( ( import " m a i n . n c l " ) & {
region = " ${ ec2-region } " ,
nixos-ami = " ${ ec2-ami } " ,
} ) . config
EOF
$ { terraform } /bin/terraform " $ @ "
'' ;
update-infra = pkgs . writeShellScriptBin " u p d a t e - i n f r a " ''
set - e
$ { run-terraform } /bin/run-terraform init
GITHUB_TOKEN = " $ ( ${ pkgs . gh } / b i n / g h a u t h t o k e n ) " $ { run-terraform } /bin/run-terraform apply
'' ;
in
pkgs . mkShell {
buildInputs = [ terraform run-terraform update-infra ] ;
} ;
2022-01-19 01:11:10 +03:00
in
rec {
packages = {
2023-01-27 18:11:17 +03:00
inherit ( mkCraneArtifacts { } )
2023-06-16 19:34:13 +03:00
nickel-lang-cli
2023-02-13 12:51:44 +03:00
benchmarks
2023-06-02 10:39:21 +03:00
lsp-nls
2023-07-17 17:06:29 +03:00
cargoArtifacts ;
2023-01-27 18:11:17 +03:00
default = pkgs . buildEnv {
name = " n i c k e l " ;
2023-06-16 19:34:13 +03:00
paths = [ packages . nickel-lang-cli packages . lsp-nls ] ;
2023-09-06 11:49:31 +03:00
meta . mainProgram = " n i c k e l " ;
2023-01-27 18:11:17 +03:00
} ;
2022-12-05 19:28:45 +03:00
nickelWasm = buildNickelWasm { } ;
2023-07-17 17:06:29 +03:00
dockerImage = buildDocker packages . nickel-lang-cli ; # TODO: docker image should be a passthru
2022-01-19 01:11:10 +03:00
inherit vscodeExtension ;
2022-02-28 20:09:25 +03:00
inherit userManual ;
2023-03-30 18:14:09 +03:00
stdlibMarkdown = stdlibDoc " m a r k d o w n " ;
stdlibJson = stdlibDoc " j s o n " ;
2023-07-17 17:06:29 +03:00
} // pkgs . lib . optionalAttrs ( ! pkgs . stdenv . hostPlatform . isDarwin ) {
inherit ( mkCraneArtifacts { } ) nickel-static ;
# Use the statically linked binary for the docker image if we're not on MacOS.
dockerImage = buildDocker packages . nickel-static ;
2022-01-19 01:11:10 +03:00
} ;
2021-09-27 18:02:07 +03:00
2022-12-23 12:57:27 +03:00
apps = {
default = {
type = " a p p " ;
2023-09-06 11:49:31 +03:00
program = pkgs . lib . getExe packages . nickel-lang-cli ;
2022-12-23 12:57:27 +03:00
} ;
} ;
2022-12-05 19:28:45 +03:00
devShells = ( forEachRustChannel ( channel : {
name = channel ;
2023-06-07 17:17:13 +03:00
value = makeDevShell { rust = mkRust { inherit channel ; rustProfile = " d e f a u l t " ; targets = [ " w a s m 3 2 - u n k n o w n - u n k n o w n " ] ; } ; } ;
2022-12-05 19:28:45 +03:00
} ) ) // {
2022-08-03 17:15:41 +03:00
default = devShells . stable ;
2023-09-04 18:41:23 +03:00
infra = infraShell packages . nickel-lang-cli ;
2022-12-05 19:28:45 +03:00
} ;
2022-01-19 01:11:10 +03:00
checks = {
2023-02-15 20:36:31 +03:00
inherit ( mkCraneArtifacts { noRunBench = true ; } )
benchmarks
2022-12-05 19:28:45 +03:00
clippy
2023-04-28 11:32:29 +03:00
checkRustDoc
2023-02-15 20:36:31 +03:00
lsp-nls
2023-06-16 19:34:13 +03:00
nickel-lang-cli
2023-06-26 19:58:40 +03:00
nickel-lang-core
2022-12-05 19:28:45 +03:00
rustfmt ;
2023-09-24 02:41:06 +03:00
# There's a tradeoff here: "release" build is in theory longer than
# "dev", but it hits the cache on dependencies so in practice it is
# shorter. Another option would be to compile a dev dependencies version
# of cargoArtifacts. But that almost doubles the cache space.
nickelWasm = buildNickelWasm { profile = " r e l e a s e " ; } ;
2022-11-21 14:56:42 +03:00
inherit vscodeExtension ;
2022-12-05 19:28:45 +03:00
pre-commit = pre-commit-builder { } ;
} ;
2022-01-19 01:11:10 +03:00
}
2022-01-17 01:17:41 +03:00
) ;
2020-07-03 15:22:21 +03:00
}