nix: dont run git-lfs shell hook if its already initialized, add experimental nix-bundle bundling command, add nixGL to shell.nix for non-nixos users, switch to nixpkgs-fmt for formatting, update niv deps and many other minor improvements

This commit is contained in:
Yusuf Bera Ertan 2020-11-30 03:48:00 +03:00
parent 515e444e3d
commit 3c7d682361
No known key found for this signature in database
GPG Key ID: 1D8F8FAF2294D6EA
7 changed files with 572 additions and 415 deletions

View File

@ -2,23 +2,27 @@
# "generate" "-f" "../Cargo.toml" # "generate" "-f" "../Cargo.toml"
# See https://github.com/kolloch/crate2nix for more info. # See https://github.com/kolloch/crate2nix for more info.
{ nixpkgs ? <nixpkgs>, pkgs ? import nixpkgs { config = { }; }, lib ? pkgs.lib { nixpkgs ? <nixpkgs>
, stdenv ? pkgs.stdenv, buildRustCrate ? pkgs.buildRustCrate , pkgs ? import nixpkgs { config = { }; }
, lib ? pkgs.lib
, stdenv ? pkgs.stdenv
, buildRustCrate ? pkgs.buildRustCrate
# This is used as the `crateOverrides` argument for `buildRustCrate`. # This is used as the `crateOverrides` argument for `buildRustCrate`.
, defaultCrateOverrides ? pkgs.defaultCrateOverrides , defaultCrateOverrides ? pkgs.defaultCrateOverrides
# The features to enable for the root_crate or the workspace_members. # The features to enable for the root_crate or the workspace_members.
, rootFeatures ? [ , rootFeatures ? [
"default" "default"
] ]
# If true, throw errors instead of issueing deprecation warnings. # If true, throw errors instead of issueing deprecation warnings.
, strictDeprecation ? false , strictDeprecation ? false
# Whether to perform release builds: longer compile times, faster binaries. # Whether to perform release builds: longer compile times, faster binaries.
, release ? true , release ? true
# Additional crate2nix configuration if it exists. # Additional crate2nix configuration if it exists.
, crateConfig ? if builtins.pathExists ./crate-config.nix then , crateConfig ? if builtins.pathExists ./crate-config.nix then
pkgs.callPackage ./crate-config.nix { } pkgs.callPackage ./crate-config.nix { }
else else
{ } }: { }
}:
rec { rec {
# #
@ -125,8 +129,9 @@ rec {
# A derivation that joins the outputs of all workspace members together. # A derivation that joins the outputs of all workspace members together.
allWorkspaceMembers = pkgs.symlinkJoin { allWorkspaceMembers = pkgs.symlinkJoin {
name = "all-workspace-members"; name = "all-workspace-members";
paths = let members = builtins.attrValues workspaceMembers; paths =
in builtins.map (m: m.build) members; let members = builtins.attrValues workspaceMembers;
in builtins.map (m: m.build) members;
}; };
# #
@ -2258,18 +2263,22 @@ rec {
packageId = "smithay-clipboard 0.6.1"; packageId = "smithay-clipboard 0.6.1";
optional = true; optional = true;
target = { target, features }: target = { target, features }:
(target."unix" && (!((target."os" == "macos") (target."unix" && (
|| (target."os" == "android") || (target."os" == "ios") !((target."os" == "macos")
|| (target."os" == "emscripten")))); || (target."os" == "android") || (target."os" == "ios")
|| (target."os" == "emscripten"))
));
} }
{ {
name = "x11-clipboard"; name = "x11-clipboard";
packageId = "x11-clipboard"; packageId = "x11-clipboard";
optional = true; optional = true;
target = { target, features }: target = { target, features }:
(target."unix" && (!((target."os" == "macos") (target."unix" && (
|| (target."os" == "android") || (target."os" == "ios") !((target."os" == "macos")
|| (target."os" == "emscripten")))); || (target."os" == "android") || (target."os" == "ios")
|| (target."os" == "emscripten"))
));
} }
]; ];
features = { features = {
@ -10167,7 +10176,7 @@ rec {
target = { target, features }: target = { target, features }:
(((target."arch" == "aarch64") || (target."arch" == "arm") (((target."arch" == "aarch64") || (target."arch" == "arm")
|| (target."arch" == "x86") || (target."arch" == "x86_64")) || (target."arch" == "x86") || (target."arch" == "x86_64"))
&& (!(target."os" == "ios"))); && (!(target."os" == "ios")));
} }
{ {
name = "untrusted"; name = "untrusted";
@ -16391,17 +16400,21 @@ rec {
name = "clipboard_wayland"; name = "clipboard_wayland";
packageId = "clipboard_wayland"; packageId = "clipboard_wayland";
target = { target, features }: target = { target, features }:
(target."unix" && (!((target."os" == "macos") (target."unix" && (
|| (target."os" == "android") || (target."os" == "emscripten") !((target."os" == "macos")
|| (target."os" == "ios")))); || (target."os" == "android") || (target."os" == "emscripten")
|| (target."os" == "ios"))
));
} }
{ {
name = "clipboard_x11"; name = "clipboard_x11";
packageId = "clipboard_x11"; packageId = "clipboard_x11";
target = { target, features }: target = { target, features }:
(target."unix" && (!((target."os" == "macos") (target."unix" && (
|| (target."os" == "android") || (target."os" == "emscripten") !((target."os" == "macos")
|| (target."os" == "ios")))); || (target."os" == "android") || (target."os" == "emscripten")
|| (target."os" == "ios"))
));
} }
{ {
name = "raw-window-handle"; name = "raw-window-handle";
@ -16817,18 +16830,20 @@ rec {
# This doesn't appear to be officially documented anywhere yet. # This doesn't appear to be officially documented anywhere yet.
# See https://github.com/rust-lang-nursery/rust-forge/issues/101. # See https://github.com/rust-lang-nursery/rust-forge/issues/101.
os = if stdenv.hostPlatform.isDarwin then os =
"macos" if stdenv.hostPlatform.isDarwin then
else "macos"
stdenv.hostPlatform.parsed.kernel.name; else
stdenv.hostPlatform.parsed.kernel.name;
arch = stdenv.hostPlatform.parsed.cpu.name; arch = stdenv.hostPlatform.parsed.cpu.name;
family = "unix"; family = "unix";
env = "gnu"; env = "gnu";
endian = if stdenv.hostPlatform.parsed.cpu.significantByte.name endian =
== "littleEndian" then if stdenv.hostPlatform.parsed.cpu.significantByte.name
"little" == "littleEndian" then
else "little"
"big"; else
"big";
pointer_width = toString stdenv.hostPlatform.parsed.cpu.bits; pointer_width = toString stdenv.hostPlatform.parsed.cpu.bits;
vendor = stdenv.hostPlatform.parsed.vendor.name; vendor = stdenv.hostPlatform.parsed.vendor.name;
debug_assertions = false; debug_assertions = false;
@ -16838,31 +16853,33 @@ rec {
# TODO(pkolloch): Substitute with gitignore filter # TODO(pkolloch): Substitute with gitignore filter
sourceFilter = name: type: sourceFilter = name: type:
let baseName = builtins.baseNameOf (builtins.toString name); let baseName = builtins.baseNameOf (builtins.toString name);
in !( in
# Filter out git !(
baseName == ".gitignore" || (type == "directory" && baseName == ".git") # Filter out git
baseName == ".gitignore" || (type == "directory" && baseName == ".git")
# Filter out build results # Filter out build results
|| (type == "directory" && (baseName == "target" || baseName == "_site" || (type == "directory" && (baseName == "target" || baseName == "_site"
|| baseName == ".sass-cache" || baseName == ".jekyll-metadata" || baseName == ".sass-cache" || baseName == ".jekyll-metadata"
|| baseName == "build-artifacts")) || baseName == "build-artifacts"))
# Filter out nix-build result symlinks # Filter out nix-build result symlinks
|| (type == "symlink" && lib.hasPrefix "result" baseName) || (type == "symlink" && lib.hasPrefix "result" baseName)
# Filter out IDE config # Filter out IDE config
|| (type == "directory" || (type == "directory"
&& (baseName == ".idea" || baseName == ".vscode")) && (baseName == ".idea" || baseName == ".vscode"))
|| lib.hasSuffix ".iml" baseName || lib.hasSuffix ".iml" baseName
# Filter out nix build files # Filter out nix build files
|| baseName == "Cargo.nix" || baseName == "Cargo.nix"
# Filter out editor backup / swap files. # Filter out editor backup / swap files.
|| lib.hasSuffix "~" baseName || builtins.match "^\\.sw[a-z]$$" baseName || lib.hasSuffix "~" baseName || builtins.match "^\\.sw[a-z]$$" baseName
!= null || builtins.match "^\\..*\\.sw[a-z]$$" baseName != null != null || builtins.match "^\\..*\\.sw[a-z]$$" baseName != null
|| lib.hasSuffix ".tmp" baseName || lib.hasSuffix ".bak" baseName || lib.hasSuffix ".tmp" baseName || lib.hasSuffix ".bak" baseName
|| baseName == "tests.nix"); || baseName == "tests.nix"
);
/* Returns a crate which depends on successful test execution /* Returns a crate which depends on successful test execution
of crate given as the second argument. of crate given as the second argument.
@ -16878,42 +16895,46 @@ rec {
# building the actual lib and bin targets We just have to pass `--test` # building the actual lib and bin targets We just have to pass `--test`
# to rustc and it will do the right thing. We execute the tests and copy # to rustc and it will do the right thing. We execute the tests and copy
# their log and the test executables to $out for later inspection. # their log and the test executables to $out for later inspection.
test = let drv = testCrate.override (_: { buildTests = true; }); test =
in pkgs.runCommand "run-tests-${testCrate.name}" { let drv = testCrate.override (_: { buildTests = true; });
inherit testCrateFlags; in
buildInputs = testInputs; pkgs.runCommand "run-tests-${testCrate.name}"
} '' {
set -ex inherit testCrateFlags;
buildInputs = testInputs;
} ''
set -ex
export RUST_BACKTRACE=1 export RUST_BACKTRACE=1
# recreate a file hierarchy as when running tests with cargo # recreate a file hierarchy as when running tests with cargo
# the source for test data # the source for test data
${pkgs.xorg.lndir}/bin/lndir ${crate.src} ${pkgs.xorg.lndir}/bin/lndir ${crate.src}
# build outputs # build outputs
testRoot=target/debug testRoot=target/debug
mkdir -p $testRoot mkdir -p $testRoot
# executables of the crate # executables of the crate
# we copy to prevent std::env::current_exe() to resolve to a store location # we copy to prevent std::env::current_exe() to resolve to a store location
for i in ${crate}/bin/*; do for i in ${crate}/bin/*; do
cp "$i" "$testRoot" cp "$i" "$testRoot"
done done
chmod +w -R . chmod +w -R .
# test harness executables are suffixed with a hash, like cargo does # test harness executables are suffixed with a hash, like cargo does
# this allows to prevent name collision with the main # this allows to prevent name collision with the main
# executables of the crate # executables of the crate
hash=$(basename $out) hash=$(basename $out)
for file in ${drv}/tests/*; do for file in ${drv}/tests/*; do
f=$testRoot/$(basename $file)-$hash f=$testRoot/$(basename $file)-$hash
cp $file $f cp $file $f
$f $testCrateFlags 2>&1 | tee -a $out $f $testCrateFlags 2>&1 | tee -a $out
done done
''; '';
in crate.overrideAttrs (old: { in
crate.overrideAttrs (old: {
checkPhase = '' checkPhase = ''
test -e ${test} test -e ${test}
''; '';
@ -16921,21 +16942,28 @@ rec {
}); });
# A restricted overridable version of builtRustCratesWithFeatures. # A restricted overridable version of builtRustCratesWithFeatures.
buildRustCrateWithFeatures = { packageId, features ? rootFeatures buildRustCrateWithFeatures =
, crateOverrides ? defaultCrateOverrides, buildRustCrateFunc ? null { packageId
, runTests ? false, testCrateFlags ? [ ], testInputs ? [ ] }: , features ? rootFeatures
, crateOverrides ? defaultCrateOverrides
, buildRustCrateFunc ? null
, runTests ? false
, testCrateFlags ? [ ]
, testInputs ? [ ]
}:
lib.makeOverridable lib.makeOverridable
({ features, crateOverrides, runTests, testCrateFlags, testInputs }: ({ features, crateOverrides, runTests, testCrateFlags, testInputs }:
let let
buildRustCrateFuncOverriden = if buildRustCrateFunc != null then buildRustCrateFuncOverriden =
buildRustCrateFunc if buildRustCrateFunc != null then
else buildRustCrateFunc
(if crateOverrides == pkgs.defaultCrateOverrides then
buildRustCrate
else else
buildRustCrate.override { (if crateOverrides == pkgs.defaultCrateOverrides then
defaultCrateOverrides = crateOverrides; buildRustCrate
}); else
buildRustCrate.override {
defaultCrateOverrides = crateOverrides;
});
builtRustCrates = builtRustCratesWithFeatures { builtRustCrates = builtRustCratesWithFeatures {
inherit packageId features; inherit packageId features;
buildRustCrateFunc = buildRustCrateFuncOverriden; buildRustCrateFunc = buildRustCrateFuncOverriden;
@ -16948,115 +16976,132 @@ rec {
}; };
drv = builtRustCrates.${packageId}; drv = builtRustCrates.${packageId};
testDrv = builtTestRustCrates.${packageId}; testDrv = builtTestRustCrates.${packageId};
derivation = if runTests then derivation =
crateWithTest { if runTests then
crate = drv; crateWithTest
testCrate = testDrv; {
inherit testCrateFlags testInputs; crate = drv;
} testCrate = testDrv;
else inherit testCrateFlags testInputs;
drv; }
in derivation) { else
drv;
in
derivation)
{
inherit features crateOverrides runTests testCrateFlags testInputs; inherit features crateOverrides runTests testCrateFlags testInputs;
}; };
/* Returns an attr set with packageId mapped to the result of buildRustCrateFunc /* Returns an attr set with packageId mapped to the result of buildRustCrateFunc
for the corresponding crate. for the corresponding crate.
*/ */
builtRustCratesWithFeatures = { packageId, features, crateConfigs ? crates builtRustCratesWithFeatures =
, buildRustCrateFunc, runTests, target ? defaultTarget }@args: { packageId
assert (builtins.isAttrs crateConfigs); , features
assert (builtins.isString packageId); , crateConfigs ? crates
assert (builtins.isList features); , buildRustCrateFunc
assert (builtins.isAttrs target); , runTests
assert (builtins.isBool runTests); , target ? defaultTarget
let }@args:
rootPackageId = packageId; assert (builtins.isAttrs crateConfigs);
mergedFeatures = mergePackageFeatures (args // { assert (builtins.isString packageId);
inherit rootPackageId; assert (builtins.isList features);
target = target // { test = runTests; }; assert (builtins.isAttrs target);
}); assert (builtins.isBool runTests);
buildByPackageId = packageId: buildByPackageIdImpl packageId; let
rootPackageId = packageId;
# Memoize built packages so that reappearing packages are only built once. mergedFeatures = mergePackageFeatures (args // {
builtByPackageId = inherit rootPackageId;
lib.mapAttrs (packageId: value: buildByPackageId packageId) target = target // { test = runTests; };
crateConfigs;
buildByPackageIdImpl = packageId:
let
features = mergedFeatures."${packageId}" or [ ];
crateConfig' = crateConfigs."${packageId}";
crateConfig = builtins.removeAttrs crateConfig' [
"resolvedDefaultFeatures"
"devDependencies"
];
devDependencies =
lib.optionals (runTests && packageId == rootPackageId)
(crateConfig'.devDependencies or [ ]);
dependencies = dependencyDerivations {
inherit builtByPackageId features target;
dependencies = (crateConfig.dependencies or [ ])
++ devDependencies;
};
buildDependencies = dependencyDerivations {
inherit builtByPackageId features target;
dependencies = crateConfig.buildDependencies or [ ];
};
filterEnabledDependenciesForThis = dependencies:
filterEnabledDependencies {
inherit dependencies features target;
};
dependenciesWithRenames = lib.filter (d: d ? "rename")
(filterEnabledDependenciesForThis
((crateConfig.buildDependencies or [ ])
++ (crateConfig.dependencies or [ ]) ++ devDependencies));
# Crate renames have the form:
#
# {
# crate_name = [
# { version = "1.2.3"; rename = "crate_name01"; }
# ];
# # ...
# }
crateRenames = let
grouped = lib.groupBy (dependency: dependency.name)
dependenciesWithRenames;
versionAndRename = dep:
let package = builtByPackageId."${dep.packageId}";
in {
inherit (dep) rename;
version = package.version;
};
in lib.mapAttrs
(name: choices: builtins.map versionAndRename choices) grouped;
in buildRustCrateFunc (crateConfig // {
src = crateConfig.src or (pkgs.fetchurl rec {
name = "${crateConfig.crateName}-${crateConfig.version}.tar.gz";
# https://www.pietroalbini.org/blog/downloading-crates-io/
# Not rate-limited, CDN URL.
url =
"https://static.crates.io/crates/${crateConfig.crateName}/${crateConfig.crateName}-${crateConfig.version}.crate";
sha256 = assert (lib.assertMsg (crateConfig ? sha256)
"Missing sha256 for ${name}");
crateConfig.sha256;
});
inherit features dependencies buildDependencies crateRenames
release;
}); });
in builtByPackageId; buildByPackageId = packageId: buildByPackageIdImpl packageId;
# Memoize built packages so that reappearing packages are only built once.
builtByPackageId =
lib.mapAttrs (packageId: value: buildByPackageId packageId)
crateConfigs;
buildByPackageIdImpl = packageId:
let
features = mergedFeatures."${packageId}" or [ ];
crateConfig' = crateConfigs."${packageId}";
crateConfig = builtins.removeAttrs crateConfig' [
"resolvedDefaultFeatures"
"devDependencies"
];
devDependencies =
lib.optionals (runTests && packageId == rootPackageId)
(crateConfig'.devDependencies or [ ]);
dependencies = dependencyDerivations {
inherit builtByPackageId features target;
dependencies = (crateConfig.dependencies or [ ])
++ devDependencies;
};
buildDependencies = dependencyDerivations {
inherit builtByPackageId features target;
dependencies = crateConfig.buildDependencies or [ ];
};
filterEnabledDependenciesForThis = dependencies:
filterEnabledDependencies {
inherit dependencies features target;
};
dependenciesWithRenames = lib.filter (d: d ? "rename")
(filterEnabledDependenciesForThis
((crateConfig.buildDependencies or [ ])
++ (crateConfig.dependencies or [ ]) ++ devDependencies));
# Crate renames have the form:
#
# {
# crate_name = [
# { version = "1.2.3"; rename = "crate_name01"; }
# ];
# # ...
# }
crateRenames =
let
grouped = lib.groupBy (dependency: dependency.name)
dependenciesWithRenames;
versionAndRename = dep:
let package = builtByPackageId."${dep.packageId}";
in
{
inherit (dep) rename;
version = package.version;
};
in
lib.mapAttrs
(name: choices: builtins.map versionAndRename choices)
grouped;
in
buildRustCrateFunc (crateConfig // {
src = crateConfig.src or (pkgs.fetchurl rec {
name = "${crateConfig.crateName}-${crateConfig.version}.tar.gz";
# https://www.pietroalbini.org/blog/downloading-crates-io/
# Not rate-limited, CDN URL.
url =
"https://static.crates.io/crates/${crateConfig.crateName}/${crateConfig.crateName}-${crateConfig.version}.crate";
sha256 = assert (lib.assertMsg (crateConfig ? sha256)
"Missing sha256 for ${name}");
crateConfig.sha256;
});
inherit features dependencies buildDependencies crateRenames
release;
});
in
builtByPackageId;
# Returns the actual derivations for the given dependencies. # Returns the actual derivations for the given dependencies.
dependencyDerivations = dependencyDerivations =
{ builtByPackageId, features, dependencies, target }: { builtByPackageId, features, dependencies, target }:
assert (builtins.isAttrs builtByPackageId); assert (builtins.isAttrs builtByPackageId);
assert (builtins.isList features); assert (builtins.isList features);
assert (builtins.isList dependencies); assert (builtins.isList dependencies);
assert (builtins.isAttrs target); assert (builtins.isAttrs target);
let let
enabledDependencies = enabledDependencies =
filterEnabledDependencies { inherit dependencies features target; }; filterEnabledDependencies { inherit dependencies features target; };
depDerivation = dependency: builtByPackageId.${dependency.packageId}; depDerivation = dependency: builtByPackageId.${dependency.packageId};
in map depDerivation enabledDependencies; in
map depDerivation enabledDependencies;
/* Returns a sanitized version of val with all values substituted that cannot /* Returns a sanitized version of val with all values substituted that cannot
be serialized as JSON. be serialized as JSON.
@ -17097,7 +17142,8 @@ rec {
diffedDefaultPackageFeatures = diffedDefaultPackageFeatures =
diffDefaultPackageFeatures { inherit packageId target; }; diffDefaultPackageFeatures { inherit packageId target; };
}; };
in { internal = debug; }; in
{ internal = debug; };
/* Returns differences between cargo default features and crate2nix default /* Returns differences between cargo default features and crate2nix default
features. features.
@ -17120,10 +17166,13 @@ rec {
onlyInCrate2Nix = builtins.attrNames onlyInCrate2Nix = builtins.attrNames
(lib.filterAttrs (n: v: (v ? "crate2nix") && !(v ? "cargo")) (lib.filterAttrs (n: v: (v ? "crate2nix") && !(v ? "cargo"))
combined); combined);
differentFeatures = lib.filterAttrs (n: v: differentFeatures = lib.filterAttrs
(v ? "crate2nix") && (v ? "cargo") && (v.crate2nix.features or [ ]) (n: v:
!= (v."cargo".resolved_default_features or [ ])) combined; (v ? "crate2nix") && (v ? "cargo") && (v.crate2nix.features or [ ])
in builtins.toJSON { != (v."cargo".resolved_default_features or [ ]))
combined;
in
builtins.toJSON {
inherit onlyInCargo onlyInCrate2Nix differentFeatures; inherit onlyInCargo onlyInCrate2Nix differentFeatures;
}; };
@ -17132,66 +17181,78 @@ rec {
If multiple paths to a dependency enable different features, the If multiple paths to a dependency enable different features, the
corresponding feature sets are merged. Features in rust are additive. corresponding feature sets are merged. Features in rust are additive.
*/ */
mergePackageFeatures = { crateConfigs ? crates, packageId mergePackageFeatures =
, rootPackageId ? packageId, features ? rootFeatures { crateConfigs ? crates
, packageId
, rootPackageId ? packageId
, features ? rootFeatures
, dependencyPath ? [ crates.${packageId}.crateName ] , dependencyPath ? [ crates.${packageId}.crateName ]
, featuresByPackageId ? { }, target , featuresByPackageId ? { }
# Adds devDependencies to the crate with rootPackageId. , target
, runTests ? false, ... }@args: # Adds devDependencies to the crate with rootPackageId.
assert (builtins.isAttrs crateConfigs); , runTests ? false
assert (builtins.isString packageId); , ...
assert (builtins.isString rootPackageId); }@args:
assert (builtins.isList features); assert (builtins.isAttrs crateConfigs);
assert (builtins.isList dependencyPath); assert (builtins.isString packageId);
assert (builtins.isAttrs featuresByPackageId); assert (builtins.isString rootPackageId);
assert (builtins.isAttrs target); assert (builtins.isList features);
assert (builtins.isBool runTests); assert (builtins.isList dependencyPath);
let assert (builtins.isAttrs featuresByPackageId);
crateConfig = crateConfigs."${packageId}" or (builtins.throw assert (builtins.isAttrs target);
"Package not found: ${packageId}"); assert (builtins.isBool runTests);
expandedFeatures = let
expandFeatures (crateConfig.features or { }) features; crateConfig = crateConfigs."${packageId}" or (builtins.throw
depWithResolvedFeatures = dependency: "Package not found: ${packageId}");
let expandedFeatures =
packageId = dependency.packageId; expandFeatures (crateConfig.features or { }) features;
features = dependencyFeatures expandedFeatures dependency; depWithResolvedFeatures = dependency:
in { inherit packageId features; };
resolveDependencies = cache: path: dependencies:
assert (builtins.isAttrs cache);
assert (builtins.isList dependencies);
let
enabledDependencies = filterEnabledDependencies {
inherit dependencies target;
features = expandedFeatures;
};
directDependencies =
map depWithResolvedFeatures enabledDependencies;
foldOverCache = op: lib.foldl op cache directDependencies;
in foldOverCache (cache:
{ packageId, features }:
let let
cacheFeatures = cache.${packageId} or [ ]; packageId = dependency.packageId;
combinedFeatures = sortedUnique (cacheFeatures ++ features); features = dependencyFeatures expandedFeatures dependency;
in if cache ? ${packageId} && cache.${packageId} in
== combinedFeatures then { inherit packageId features; };
cache resolveDependencies = cache: path: dependencies:
else assert (builtins.isAttrs cache);
mergePackageFeatures { assert (builtins.isList dependencies);
features = combinedFeatures; let
featuresByPackageId = cache; enabledDependencies = filterEnabledDependencies {
inherit crateConfigs packageId target runTests rootPackageId; inherit dependencies target;
}); features = expandedFeatures;
cacheWithSelf = let };
cacheFeatures = featuresByPackageId.${packageId} or [ ]; directDependencies =
combinedFeatures = sortedUnique (cacheFeatures ++ expandedFeatures); map depWithResolvedFeatures enabledDependencies;
in featuresByPackageId // { "${packageId}" = combinedFeatures; }; foldOverCache = op: lib.foldl op cache directDependencies;
cacheWithDependencies = resolveDependencies cacheWithSelf "dep" in
(crateConfig.dependencies or [ ] foldOverCache (cache:
++ lib.optionals (runTests && packageId == rootPackageId) { packageId, features }:
(crateConfig.devDependencies or [ ])); let
cacheWithAll = resolveDependencies cacheWithDependencies "build" cacheFeatures = cache.${packageId} or [ ];
(crateConfig.buildDependencies or [ ]); combinedFeatures = sortedUnique (cacheFeatures ++ features);
in cacheWithAll; in
if cache ? ${packageId} && cache.${packageId}
== combinedFeatures then
cache
else
mergePackageFeatures {
features = combinedFeatures;
featuresByPackageId = cache;
inherit crateConfigs packageId target runTests rootPackageId;
});
cacheWithSelf =
let
cacheFeatures = featuresByPackageId.${packageId} or [ ];
combinedFeatures = sortedUnique (cacheFeatures ++ expandedFeatures);
in
featuresByPackageId // { "${packageId}" = combinedFeatures; };
cacheWithDependencies = resolveDependencies cacheWithSelf "dep"
(crateConfig.dependencies or [ ]
++ lib.optionals (runTests && packageId == rootPackageId)
(crateConfig.devDependencies or [ ]));
cacheWithAll = resolveDependencies cacheWithDependencies "build"
(crateConfig.buildDependencies or [ ]);
in
cacheWithAll;
# Returns the enabled dependencies given the enabled features. # Returns the enabled dependencies given the enabled features.
filterEnabledDependencies = { dependencies, features, target }: filterEnabledDependencies = { dependencies, features, target }:
@ -17199,11 +17260,13 @@ rec {
assert (builtins.isList features); assert (builtins.isList features);
assert (builtins.isAttrs target); assert (builtins.isAttrs target);
lib.filter (dep: lib.filter
let targetFunc = dep.target or (features: true); (dep:
in targetFunc { inherit features target; } && (!(dep.optional or false) let targetFunc = dep.target or (features: true);
in
targetFunc { inherit features target; } && (!(dep.optional or false)
|| builtins.any (doesFeatureEnableDependency dep) features)) || builtins.any (doesFeatureEnableDependency dep) features))
dependencies; dependencies;
# Returns whether the given feature should enable the given dependency. # Returns whether the given feature should enable the given dependency.
doesFeatureEnableDependency = { name, rename ? null, ... }: doesFeatureEnableDependency = { name, rename ? null, ... }:
@ -17212,7 +17275,8 @@ rec {
prefix = "${name}/"; prefix = "${name}/";
len = builtins.stringLength prefix; len = builtins.stringLength prefix;
startsWithPrefix = builtins.substring 0 len feature == prefix; startsWithPrefix = builtins.substring 0 len feature == prefix;
in (rename == null && feature == name) in
(rename == null && feature == name)
|| (rename != null && rename == feature) || startsWithPrefix; || (rename != null && rename == feature) || startsWithPrefix;
/* Returns the expanded features for the given inputFeatures by applying the /* Returns the expanded features for the given inputFeatures by applying the
@ -17230,7 +17294,8 @@ rec {
[ feature ] [ feature ]
++ (expandFeatures featureMap (featureMap."${feature}" or [ ])); ++ (expandFeatures featureMap (featureMap."${feature}" or [ ]));
outFeatures = lib.concatMap expandFeature inputFeatures; outFeatures = lib.concatMap expandFeature inputFeatures;
in sortedUnique outFeatures; in
sortedUnique outFeatures;
/* Returns the actual features for the given dependency. /* Returns the actual features for the given dependency.
@ -17243,12 +17308,15 @@ rec {
defaultOrNil = defaultOrNil =
if dependency.usesDefaultFeatures or true then [ "default" ] else [ ]; if dependency.usesDefaultFeatures or true then [ "default" ] else [ ];
explicitFeatures = dependency.features or [ ]; explicitFeatures = dependency.features or [ ];
additionalDependencyFeatures = let additionalDependencyFeatures =
dependencyPrefix = (dependency.rename or dependency.name) + "/"; let
dependencyFeatures = dependencyPrefix = (dependency.rename or dependency.name) + "/";
builtins.filter (f: lib.hasPrefix dependencyPrefix f) features; dependencyFeatures =
in builtins.map (lib.removePrefix dependencyPrefix) dependencyFeatures; builtins.filter (f: lib.hasPrefix dependencyPrefix f) features;
in defaultOrNil ++ explicitFeatures ++ additionalDependencyFeatures; in
builtins.map (lib.removePrefix dependencyPrefix) dependencyFeatures;
in
defaultOrNil ++ explicitFeatures ++ additionalDependencyFeatures;
# Sorts and removes duplicates from a list of strings. # Sorts and removes duplicates from a list of strings.
sortedUnique = features: sortedUnique = features:
@ -17258,7 +17326,8 @@ rec {
outFeaturesSet = outFeaturesSet =
lib.foldl (set: feature: set // { "${feature}" = 1; }) { } features; lib.foldl (set: feature: set // { "${feature}" = 1; }) { } features;
outFeaturesUnique = builtins.attrNames outFeaturesSet; outFeaturesUnique = builtins.attrNames outFeaturesSet;
in builtins.sort (a: b: a < b) outFeaturesUnique; in
builtins.sort (a: b: a < b) outFeaturesUnique;
deprecationWarning = message: value: deprecationWarning = message: value:
if strictDeprecation then if strictDeprecation then

View File

@ -23,6 +23,16 @@ You can configure the crates to be built with debug mode (not recommended, equal
nix-env -f nix/default.nix --arg release false nix-env -f nix/default.nix --arg release false
``` ```
If you aren't on NixOS, you can run `veloren-voxygen` using the provided `nixGLIntel` in the dev shell:
```shell
nixGLIntel veloren-voxygen
```
If you have an Nvidia GPU, you can enter the dev shell like so:
```shell
nix-shell nix/shell.nix --arg nvidia true
```
And you'll be able to use `nixGLNvidia` and `nixGLNvidiaBumblebee`.
### Managing Cargo.nix ### Managing Cargo.nix
Enter the development shell. Enter the development shell.
@ -43,9 +53,9 @@ niv update
### Formatting ### Formatting
Use [nixfmt](https://github.com/serokell/nixfmt) to format files. Use [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) to format files.
To format every Nix file in current working directory: To format every Nix file:
```shell ```shell
nixfmt *.nix nixpkgs-fmt nix/*.nix
``` ```

View File

@ -1,40 +1,52 @@
{ system, nixpkgsMoz, nixpkgs }: { system, sources, nixpkgs }:
let let
mozPkgs = import "${nixpkgsMoz}/package-set.nix" { mozPkgs = import "${sources.nixpkgsMoz}/package-set.nix" {
pkgs = import nixpkgs { inherit system; }; pkgs = import nixpkgs { inherit system; };
}; };
rustChannel = mozPkgs.rustChannelOf { rustChannel = mozPkgs.rustChannelOf {
rustToolchain = ../rust-toolchain; rustToolchain = ../rust-toolchain;
sha256 = "sha256-P4FTKRe0nM1FRDV0Q+QY2WcC8M9IR7aPMMLWDfv+rEk="; sha256 = "sha256-P4FTKRe0nM1FRDV0Q+QY2WcC8M9IR7aPMMLWDfv+rEk=";
}; };
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
overlays = [ overlays = [
(self: super: { (final: prev: {
rustc = rustChannel.rust; rustc = rustChannel.rust;
inherit (rustChannel) inherit (rustChannel)
; ;
crate2nix = prev.callPackage sources.crate2nix { pkgs = prev; };
nixGL = prev.callPackage sources.nixGL { pkgs = prev; };
}) })
]; ];
}; };
in with pkgs; in
with pkgs;
let let
xorgLibraries = with xorg; [ libX11 libXcursor libXrandr libXi ]; # deps that crates need (for compiling)
otherLibraries = [
libGL
# wayland
/* uncomment above for wayland support (?)
for some reason it doesn't work (triggers `unreachable!()` code in winit!)
so I disabled it by default
*/
];
neededLibPathsVoxygen = lib.concatStringsSep ":"
(map (p: "${p}/lib") (xorgLibraries ++ otherLibraries));
crateDeps = { crateDeps = {
libudev-sys = [ pkg-config libudev ]; libudev-sys = {
alsa-sys = [ pkg-config alsaLib ]; buildInputs = [ libudev ];
veloren-network = [ pkg-config openssl ]; nativeBuildInputs = [ pkg-config ];
veloren-voxygen = [ atk cairo glib gtk3 pango ]; };
alsa-sys = {
buildInputs = [ alsaLib ];
nativeBuildInputs = [ pkg-config ];
};
veloren-network = {
buildInputs = [ openssl ];
nativeBuildInputs = [ pkg-config ];
};
veloren-voxygen = {
buildInputs = [ xorg.libxcb ];
nativeBuildInputs = [ ];
};
}; };
in { inherit pkgs neededLibPathsVoxygen crateDeps; }
# deps that voxygen needs to function
voxygenNeededLibs = (with xorg; [ libX11 libXcursor libXrandr libXi ])
++ [ libGL ];
gitLfsCheckFile = ../assets/voxygen/background/bg_main.png;
in
{ inherit pkgs voxygenNeededLibs crateDeps gitLfsCheckFile; }

View File

@ -1,16 +1,15 @@
{ {
/* `crate2nix` doesn't support profiles in `Cargo.toml`, so default to release. # `crate2nix` doesn't support profiles in `Cargo.toml`, so default to release.
Otherwise bad performance (non-release is built with opt level 0) # Otherwise bad performance (non-release is built with opt level 0)
*/ release ? true
release ? true, cratesToBuild ? [ "veloren-voxygen" "veloren-server-cli" ] , cratesToBuild ? [ "veloren-voxygen" "veloren-server-cli" ]
, system ? builtins.currentSystem, nixpkgs ? sources.nixpkgs , system ? builtins.currentSystem
, sources ? import ./sources.nix { inherit system; } }: , nixpkgs ? sources.nixpkgs
, nvidia ? false
, sources ? import ./sources.nix { inherit system; }
}:
let let
common = import ./common.nix { common = import ./common.nix { inherit nixpkgs system sources; };
inherit nixpkgs system;
inherit (sources) nixpkgsMoz;
};
inherit (common) pkgs; inherit (common) pkgs;
meta = with pkgs.stdenv.lib; { meta = with pkgs.stdenv.lib; {
@ -26,23 +25,25 @@ let
platforms = platforms.all; platforms = platforms.all;
}; };
isGitLfsSetup = let isGitLfsSetup =
checkFile = ../assets/voxygen/background/bg_main.png; let
gitLfsCheckOutput = builtins.readFile (pkgs.runCommand "gitLfsCheck" { } '' gitLfsCheckOutput = with common;
[ "$(${pkgs.file}/bin/file --mime-type ${checkFile})" = "${checkFile}: image/png" ] builtins.readFile (pkgs.runCommand "gitLfsCheck" { } ''
printf $? > $out [ "$(${pkgs.file}/bin/file --mime-type ${gitLfsCheckFile})" = "${gitLfsCheckFile}: image/png" ]
''); printf $? > $out
in if gitLfsCheckOutput == "0" then '');
true in
else if gitLfsCheckOutput == "0" then
abort '' true
Git Large File Storage (`git-lfs`) has not been set up correctly. else
Most common reasons: abort ''
- `git-lfs` was not installed before cloning this repository. Git Large File Storage (`git-lfs`) has not been set up correctly.
- This repository was not cloned from the primary GitLab mirror. Most common reasons:
- The GitHub mirror does not support LFS. - `git-lfs` was not installed before cloning this repository.
See the book at https://book.veloren.net/ for details. - This repository was not cloned from the primary GitLab mirror.
''; - The GitHub mirror does not support LFS.
See the book at https://book.veloren.net/ for details.
'';
makeGitCommand = subcommands: name: makeGitCommand = subcommands: name:
builtins.readFile (pkgs.runCommand name { } '' builtins.readFile (pkgs.runCommand name { } ''
@ -64,11 +65,14 @@ let
gitTag = gitTag =
# If the git command errors out we feed an empty string # If the git command errors out we feed an empty string
makeGitCommand "describe --exact-match --tags HEAD || printf ''" makeGitCommand "describe --exact-match --tags HEAD || printf ''"
"getGitTag"; "getGitTag";
# If gitTag has a tag (meaning the commit we are on is a *release*), use it as version # If gitTag has a tag (meaning the commit we are on is a *release*), use it as version
# If not, we just use the prettified hash we have # If not, we just use the prettified hash we have
version = if gitTag != "" then gitTag else gitHash; version = if gitTag != "" then gitTag else gitHash;
# Sanitize version string since it contains not allowed characters for a Nix store path
# Only used in the package name
sanitizedVersion = pkgs.stdenv.lib.strings.sanitizeDerivationName version;
veloren-assets = pkgs.runCommand "makeAssetsDir" { } '' veloren-assets = pkgs.runCommand "makeAssetsDir" { } ''
mkdir $out mkdir $out
@ -79,8 +83,12 @@ let
callPackage ./Cargo.nix { callPackage ./Cargo.nix {
defaultCrateOverrides = with common; defaultCrateOverrides = with common;
defaultCrateOverrides // { defaultCrateOverrides // {
libudev-sys = _: { buildInputs = crateDeps.libudev-sys; }; libudev-sys = _: {
alsa-sys = _: { buildInputs = crateDeps.alsa-sys; }; inherit (crateDeps.libudev-sys) nativeBuildInputs buildInputs;
};
alsa-sys = _: {
inherit (crateDeps.alsa-sys) nativeBuildInputs buildInputs;
};
veloren-common = _: { veloren-common = _: {
# Disable `git-lfs` check here since we check it ourselves # Disable `git-lfs` check here since we check it ourselves
DISABLE_GIT_LFS_CHECK = isGitLfsSetup; DISABLE_GIT_LFS_CHECK = isGitLfsSetup;
@ -88,45 +96,49 @@ let
NIX_GIT_HASH = gitHash; NIX_GIT_HASH = gitHash;
NIX_GIT_TAG = gitTag; NIX_GIT_TAG = gitTag;
}; };
veloren-network = _: { buildInputs = crateDeps.veloren-network; }; veloren-network = _: {
inherit (crateDeps.veloren-network) nativeBuildInputs buildInputs;
};
veloren-server-cli = _: { veloren-server-cli = _: {
name = "veloren-server-cli_${sanitizedVersion}";
inherit version;
VELOREN_USERDATA_STRATEGY = "system"; VELOREN_USERDATA_STRATEGY = "system";
nativeBuildInputs = [ makeWrapper ]; nativeBuildInputs = [ makeWrapper ];
postInstall = '' postInstall = ''
wrapProgram $out/bin/veloren-server-cli --set VELOREN_ASSETS ${veloren-assets} wrapProgram $out/bin/veloren-server-cli --set VELOREN_ASSETS ${veloren-assets}
''; '';
meta = meta // {
longDescription = ''
${meta.longDescription}
"This package includes the server CLI."
'';
};
}; };
veloren-voxygen = _: { veloren-voxygen = _: {
name = "veloren-voxygen_${sanitizedVersion}";
inherit version;
VELOREN_USERDATA_STRATEGY = "system"; VELOREN_USERDATA_STRATEGY = "system";
buildInputs = crateDeps.veloren-voxygen; inherit (crateDeps.veloren-voxygen) buildInputs;
nativeBuildInputs = [ makeWrapper ]; nativeBuildInputs = crateDeps.veloren-voxygen.nativeBuildInputs
++ [ makeWrapper ];
postInstall = '' postInstall = ''
wrapProgram $out/bin/veloren-voxygen\ wrapProgram $out/bin/veloren-voxygen\
--set LD_LIBRARY_PATH ${neededLibPathsVoxygen}\ --set VELOREN_ASSETS ${veloren-assets}\
--set VELOREN_ASSETS ${veloren-assets} --set LD_LIBRARY_PATH ${
lib.makeLibraryPath common.voxygenNeededLibs
}
''; '';
meta = meta // {
longDescription = ''
${meta.longDescription}
"This package includes the client, Voxygen."
'';
};
}; };
}; };
inherit release pkgs; inherit release pkgs;
}; };
makePkg = name: makePkg = name: veloren-crates.workspaceMembers."${name}".build;
pkgs.symlinkJoin { in
inherit version; (pkgs.lib.genAttrs cratesToBuild makePkg)
name = "${name}_${version}";
paths = [ veloren-crates.workspaceMembers."${name}".build ];
meta = meta // {
longDescription = ''
${meta.longDescription}
${if name == "veloren-voxygen" then
"This package includes the client, Voxygen."
else
""}
${if name == "veloren-server-cli" then
"This package includes the server CLI."
else
""}
'';
};
};
in (pkgs.lib.genAttrs cratesToBuild makePkg)

View File

@ -1,25 +1,51 @@
{ nixpkgs ? <nixpkgs>, sources ? import ./sources.nix { } { nixpkgs ? <nixpkgs>
, system ? builtins.currentSystem }: , sources ? import ./sources.nix { }
, system ? builtins.currentSystem
, nvidia ? false
}:
let common = import ./common.nix { inherit nixpkgs system sources; };
in
with common.pkgs;
let let
common = import ./common.nix { nixGLPackages = ((with nixGL; [ nixGLIntel ]) ++ (lib.optional nvidia
inherit nixpkgs system; (with nixGL; [ nixGLNvidia nixGLNvidiaBumblebee ])));
inherit (sources) nixpkgsMoz;
};
crate2nix = getAllCratesDeps = name:
common.pkgs.callPackage sources.crate2nix { inherit (common) pkgs; }; (lib.concatLists
in with common.pkgs; (map (attrset: attrset."${name}") (lib.attrValues common.crateDeps)));
bundleCrate = writeScriptBin "bundleCrate" ''
#!${stdenv.shell}
${nix-bundle}/bin/nix-bundle "(pkgs.callPackage ./nix/default.nix { }).$1" /bin/$1
'';
in
with common;
mkShell { mkShell {
name = "veloren-shell"; name = "veloren-shell";
nativeBuildInputs = nativeBuildInputs = [
[ git git-lfs niv nixfmt crate2nix cargo rustc rustfmt clippy cachix ]; bundleCrate
buildInputs = lib.concatLists (lib.attrValues common.crateDeps); git
git-lfs
niv
nixpkgs-fmt
crate2nix
cargo
rustc
rustfmt
clippy
cachix
] ++ nixGLPackages ++ (getAllCratesDeps "nativeBuildInputs");
buildInputs = getAllCratesDeps "buildInputs";
shellHook = '' shellHook = ''
# Setup our cachix "substituter"
export NIX_CONFIG=" export NIX_CONFIG="
substituters = https://cache.nixos.org https://veloren-nix.cachix.org substituters = https://cache.nixos.org https://veloren-nix.cachix.org
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= veloren-nix.cachix.org-1:zokfKJqVsNV6kI/oJdLF6TYBdNPYGSb+diMVQPn/5Rc= trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= veloren-nix.cachix.org-1:zokfKJqVsNV6kI/oJdLF6TYBdNPYGSb+diMVQPn/5Rc=
" "
export LD_LIBRARY_PATH=${common.neededLibPathsVoxygen} # We need this so that Voxygen runs
git lfs install --local && git lfs fetch && git lfs checkout export LD_LIBRARY_PATH=${lib.makeLibraryPath voxygenNeededLibs}
# No need to install git-lfs and run fetch / checkout commands if we have it setup
[ "$(${file}/bin/file --mime-type ${gitLfsCheckFile})" = "${gitLfsCheckFile}: image/png" ] || (git lfs install --local && git lfs fetch && git lfs checkout)
''; '';
} }

View File

@ -5,10 +5,22 @@
"homepage": "", "homepage": "",
"owner": "kolloch", "owner": "kolloch",
"repo": "crate2nix", "repo": "crate2nix",
"rev": "df3e4e6570c1058d947d70876712209a1eca6731", "rev": "3701179c8aef0677dab1915457ca0f367f2dc523",
"sha256": "1kn98ckf2h4j3xmc50n6904p5g226qa1c1jgha511d9l6lgks24r", "sha256": "0z5vz3dcbx53a7q6xrm8qjrn62zlvzvaxdisv2axfh70qq4lx4n2",
"type": "tarball", "type": "tarball",
"url": "https://github.com/kolloch/crate2nix/archive/df3e4e6570c1058d947d70876712209a1eca6731.tar.gz", "url": "https://github.com/kolloch/crate2nix/archive/3701179c8aef0677dab1915457ca0f367f2dc523.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixGL": {
"branch": "master",
"description": "A wrapper tool for nix OpenGL application",
"homepage": null,
"owner": "guibou",
"repo": "nixGL",
"rev": "7d6bc1b21316bab6cf4a6520c2639a11c25a220e",
"sha256": "02y38zmdplk7a9ihsxvnrzhhv7324mmf5g8hmxqizaid5k5ydpr3",
"type": "tarball",
"url": "https://github.com/guibou/nixGL/archive/7d6bc1b21316bab6cf4a6520c2639a11c25a220e.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"nixpkgs": { "nixpkgs": {
@ -17,10 +29,10 @@
"homepage": "", "homepage": "",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "6625284c397b44bc9518a5a1567c1b5aae455c08", "rev": "1121b2259b7d66e8c7c5131d1588a48c80ef9e58",
"sha256": "1w0czzv53sg35gp7sr506facbmzd33jm34p6cg23fb9kz5rf5c89", "sha256": "0w2i4byhfn8c9lq8a97xnix5alfandqkbyvh6lbpr9zrm63lmyip",
"type": "tarball", "type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/6625284c397b44bc9518a5a1567c1b5aae455c08.tar.gz", "url": "https://github.com/NixOS/nixpkgs/archive/1121b2259b7d66e8c7c5131d1588a48c80ef9e58.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"nixpkgsMoz": { "nixpkgsMoz": {

View File

@ -1,18 +1,18 @@
# This file has been generated by Niv. # This file has been generated by Niv.
let let
# #
# The fetchers. fetch_<type> fetches specs of type <type>. # The fetchers. fetch_<type> fetches specs of type <type>.
# #
fetch_file = pkgs: name: spec: fetch_file = pkgs: name: spec:
let name' = sanitizeName name + "-src"; let name' = sanitizeName name + "-src";
in if spec.builtin or true then in
builtins_fetchurl { if spec.builtin or true then
inherit (spec) url sha256; builtins_fetchurl
name = name'; {
} inherit (spec) url sha256;
name = name';
}
else else
pkgs.fetchurl { pkgs.fetchurl {
inherit (spec) url sha256; inherit (spec) url sha256;
@ -21,11 +21,13 @@ let
fetch_tarball = pkgs: name: spec: fetch_tarball = pkgs: name: spec:
let name' = sanitizeName name + "-src"; let name' = sanitizeName name + "-src";
in if spec.builtin or true then in
builtins_fetchTarball { if spec.builtin or true then
name = name'; builtins_fetchTarball
inherit (spec) url sha256; {
} name = name';
inherit (spec) url sha256;
}
else else
pkgs.fetchzip { pkgs.fetchzip {
name = name'; name = name';
@ -34,16 +36,18 @@ let
fetch_git = name: spec: fetch_git = name: spec:
let let
ref = if spec ? ref then ref =
spec.ref if spec ? ref then
else if spec ? branch then spec.ref
"refs/heads/${spec.branch}" else if spec ? branch then
else if spec ? tag then "refs/heads/${spec.branch}"
"refs/tags/${spec.tag}" else if spec ? tag then
else "refs/tags/${spec.tag}"
abort else
"In git source '${name}': Please specify `ref`, `tag` or `branch`!"; abort
in builtins.fetchGit { "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
in
builtins.fetchGit {
url = spec.repo; url = spec.repo;
inherit (spec) rev; inherit (spec) rev;
inherit ref; inherit ref;
@ -75,12 +79,14 @@ let
mkPkgs = sources: system: mkPkgs = sources: system:
let let
sourcesNixpkgs = import sourcesNixpkgs = import
(builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; })
{
inherit system; inherit system;
}; };
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = <nixpkgs> == ./.; hasThisAsNixpkgsPath = <nixpkgs> == ./.;
in if builtins.hasAttr "nixpkgs" sources then in
if builtins.hasAttr "nixpkgs" sources then
sourcesNixpkgs sourcesNixpkgs
else if hasNixpkgsPath && !hasThisAsNixpkgsPath then else if hasNixpkgsPath && !hasThisAsNixpkgsPath then
import <nixpkgs> { } import <nixpkgs> { }
@ -109,26 +115,30 @@ let
fetch_builtin-url name fetch_builtin-url name
else else
abort abort
"ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
# If the environment variable NIV_OVERRIDE_${name} is set, then use # If the environment variable NIV_OVERRIDE_${name} is set, then use
# the path directly as opposed to the fetched source. # the path directly as opposed to the fetched source.
replace = name: drv: replace = name: drv:
let let
saneName = stringAsChars saneName = stringAsChars
(c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c)
name;
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
in if ersatz == "" then drv else ersatz; in
if ersatz == "" then drv else ersatz;
# Ports of functions for older nix versions # Ports of functions for older nix versions
# a Nix version of mapAttrs if the built-in doesn't exist # a Nix version of mapAttrs if the built-in doesn't exist
mapAttrs = builtins.mapAttrs or (f: set: mapAttrs = builtins.mapAttrs or (f: set:
with builtins; with builtins;
listToAttrs (map (attr: { listToAttrs (map
name = attr; (attr: {
value = f attr set.${attr}; name = attr;
}) (attrNames set))); value = f attr set.${attr};
})
(attrNames set)));
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
range = first: last: range = first: last:
@ -152,39 +162,44 @@ let
# fetchTarball version that is compatible between all the versions of Nix # fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, name ? null, sha256 }@attrs: builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
let inherit (builtins) lessThan nixVersion fetchTarball; let inherit (builtins) lessThan nixVersion fetchTarball;
in if lessThan nixVersion "1.12" then in
if lessThan nixVersion "1.12" then
fetchTarball fetchTarball
({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else else
fetchTarball attrs; fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix # fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, name ? null, sha256 }@attrs: builtins_fetchurl = { url, name ? null, sha256 }@attrs:
let inherit (builtins) lessThan nixVersion fetchurl; let inherit (builtins) lessThan nixVersion fetchurl;
in if lessThan nixVersion "1.12" then in
if lessThan nixVersion "1.12" then
fetchurl fetchurl
({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else else
fetchurl attrs; fetchurl attrs;
# Create the final "sources" from the config # Create the final "sources" from the config
mkSources = config: mkSources = config:
mapAttrs (name: spec: mapAttrs
if builtins.hasAttr "outPath" spec then (name: spec:
abort if builtins.hasAttr "outPath" spec then
"The values in sources.json should not have an 'outPath' attribute" abort
else "The values in sources.json should not have an 'outPath' attribute"
spec // { outPath = replace name (fetch config.pkgs name spec); }) else
config.sources; spec // { outPath = replace name (fetch config.pkgs name spec); })
config.sources;
# The "config" used by the fetchers # The "config" used by the fetchers
mkConfig = { sourcesFile ? mkConfig =
if builtins.pathExists ./sources.json then ./sources.json else null { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
, sources ? if isNull sourcesFile then , sources ? if isNull sourcesFile then
{ } { }
else else
builtins.fromJSON (builtins.readFile sourcesFile) builtins.fromJSON (builtins.readFile sourcesFile)
, system ? builtins.currentSystem, pkgs ? mkPkgs sources system }: rec { , system ? builtins.currentSystem
, pkgs ? mkPkgs sources system
}: rec {
# The sources, i.e. the attribute set of spec name to spec # The sources, i.e. the attribute set of spec name to spec
inherit sources; inherit sources;
@ -192,6 +207,7 @@ let
inherit pkgs; inherit pkgs;
}; };
in mkSources (mkConfig { }) // { in
mkSources (mkConfig { }) // {
__functor = _: settings: mkSources (mkConfig settings); __functor = _: settings: mkSources (mkConfig settings);
} }