fix and improve nix build: actually output a proper veloren voxygen package now

This commit is contained in:
Yusuf Bera Ertan 2020-11-24 04:08:57 +03:00
parent 24e5e714b9
commit 62d34422fe
No known key found for this signature in database
GPG Key ID: 1D8F8FAF2294D6EA
11 changed files with 4528 additions and 2065 deletions

3
.gitignore vendored
View File

@ -49,4 +49,5 @@ userdata
.DS_Store
# Nix
nix/result
nix/result*
/result*

View File

@ -7,50 +7,50 @@ use std::{
};
fn main() {
// If the env variable exists then we are building on nix, use it as hash and
// return. `git-lfs` check is handled by nix itself.
if let Some(hash) = option_env!("NIX_GIT_HASH") {
// If these env variables exist then we are building on nix, use them as hash
// and tag.
if let (Some(hash), Some(tag)) = (option_env!("NIX_GIT_HASH"), option_env!("NIX_GIT_TAG")) {
create_hash_file(hash);
return;
}
// Get the current githash
// Note: It will compare commits. As long as the commits do not diverge from the
// server no version change will be detected.
match Command::new("git")
.args(&[
"log",
"-n",
"1",
"--pretty=format:%h/%cd",
"--date=format:%Y-%m-%d-%H:%M",
"--abbrev=8",
])
.output()
{
Ok(output) => match String::from_utf8(output.stdout) {
Ok(hash) => {
create_hash_file(&hash);
create_tag_file(tag);
} else {
// Get the current githash
// Note: It will compare commits. As long as the commits do not diverge from the
// server no version change will be detected.
match Command::new("git")
.args(&[
"log",
"-n",
"1",
"--pretty=format:%h/%cd",
"--date=format:%Y-%m-%d-%H:%M",
"--abbrev=8",
])
.output()
{
Ok(output) => match String::from_utf8(output.stdout) {
Ok(hash) => {
create_hash_file(&hash);
},
Err(e) => panic!("failed to convert git output to UTF-8: {}", e),
},
Err(e) => panic!("failed to convert git output to UTF-8: {}", e),
},
Err(e) => panic!("failed to retrieve current git commit hash: {}", e),
}
Err(e) => panic!("failed to retrieve current git commit hash: {}", e),
}
// Get the current githash
// Note: It will compare commits. As long as the commits do not diverge from the
// server no version change will be detected.
match Command::new("git")
.args(&["describe", "--exact-match", "--tags", "HEAD"])
.output()
{
Ok(output) => match String::from_utf8(output.stdout) {
Ok(tag) => {
create_tag_file(&tag);
// Get the current githash
// Note: It will compare commits. As long as the commits do not diverge from the
// server no version change will be detected.
match Command::new("git")
.args(&["describe", "--exact-match", "--tags", "HEAD"])
.output()
{
Ok(output) => match String::from_utf8(output.stdout) {
Ok(tag) => {
create_tag_file(&tag);
},
Err(e) => panic!("failed to convert git output to UTF-8: {}", e),
},
Err(e) => panic!("failed to convert git output to UTF-8: {}", e),
},
Err(e) => panic!("failed to retrieve current git commit hash: {}", e),
Err(e) => panic!("failed to retrieve current git commit hash: {}", e),
}
}
// Check if git-lfs is working

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,43 @@
### How to use
To build Voxygen, run:
`nix build`
To build and install Voxygen and the server CLI into user profile, run:
```shell
nix-env -f nix/default.nix -i
```
You can configure what to install by changing the `cratesToBuild` argument:
```shell
nix-env -f nix/default.nix --arg cratesToBuild '["veloren-voxygen"]'
```
For example, this will install Voxygen only.
To build another binary, run:
`nix build --arg crateName "<binary name here>"`
To enter the development shell (which includes all tools mentioned in this readme), run:
`nix-shell shell.nix`
To enter the development shell (which includes all tools mentioned in this readme + tools you'll need to develop Veloren), run:
```shell
nix-shell nix/shell.nix
```
### Managing Cargo.nix
Enter the development shell.
To update `Cargo.nix` (and `crate-hashes.json`) using latest `Cargo.lock`, run:
`crate2nix generate -f ../Cargo.toml`
```shell
crate2nix generate -f ../Cargo.toml
```
### Managing dependencies
We use [niv](https://github.com/nmattia/niv) to manage dependencies.
Enter the development shell in repository root:
`cd .. && nix-shell nix/shell.nix`
To update the dependencies, run:
`niv update`
To update the dependencies, run (from repository root):
```shell
niv update
```
### Formatting
Use [nixfmt](https://github.com/serokell/nixfmt) to format files.
To format every file:
`nixfmt *.nix`
To format every Nix file in current working directory:
```shell
nixfmt *.nix
```

22
nix/common.nix Normal file
View File

@ -0,0 +1,22 @@
{ pkgs }:
with pkgs;
let
xorgLibraries = with xorg; [ libX11 libXcursor libXrandr libXi ];
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
*/
];
neededLibPaths = lib.concatStringsSep ":"
(map (p: "${p}/lib") (xorgLibraries ++ otherLibraries));
crateDeps = {
libudev-sys = [ pkg-config libudev ];
alsa-sys = [ pkg-config alsaLib ];
veloren-network = [ pkg-config openssl ];
veloren-voxygen = [ atk cairo glib gtk3 pango ];
};
in { inherit neededLibPaths crateDeps; }

View File

@ -1,14 +1,21 @@
{
"auth-common 0.1.0 (git+https://gitlab.com/veloren/auth.git?rev=b943c85e4a38f5ec60cd18c34c73097640162bfe#b943c85e4a38f5ec60cd18c34c73097640162bfe)": "0ckpx36a5gmzirsih03ddfyp4iz23ffwb6sc75smb4srx1ivc7fy",
"authc 1.0.0 (git+https://gitlab.com/veloren/auth.git?rev=b943c85e4a38f5ec60cd18c34c73097640162bfe#b943c85e4a38f5ec60cd18c34c73097640162bfe)": "0ckpx36a5gmzirsih03ddfyp4iz23ffwb6sc75smb4srx1ivc7fy",
"conrod_core 0.63.0 (git+https://gitlab.com/veloren/conrod.git#1ab6eccf94b16a8977a3274b31d4dbfef9cf9a30)": "1xr12b422wb2ygfzn5mfbqyqp8zia2ciclxladzlan7hr5h226jc",
"conrod_derive 0.63.0 (git+https://gitlab.com/veloren/conrod.git#1ab6eccf94b16a8977a3274b31d4dbfef9cf9a30)": "1xr12b422wb2ygfzn5mfbqyqp8zia2ciclxladzlan7hr5h226jc",
"conrod_winit 0.63.0 (git+https://gitlab.com/veloren/conrod.git#1ab6eccf94b16a8977a3274b31d4dbfef9cf9a30)": "1xr12b422wb2ygfzn5mfbqyqp8zia2ciclxladzlan7hr5h226jc",
"conrod_core 0.63.0 (git+https://gitlab.com/veloren/conrod.git?branch=copypasta_0.7#1ae5193588fb662a7189d81edd9f2d653c7f1da0)": "14sxyw8si0c2md5p5hssvfl12368hqp1fy6ighd7v4lb8fqwp6zj",
"conrod_derive 0.63.0 (git+https://gitlab.com/veloren/conrod.git?branch=copypasta_0.7#1ae5193588fb662a7189d81edd9f2d653c7f1da0)": "14sxyw8si0c2md5p5hssvfl12368hqp1fy6ighd7v4lb8fqwp6zj",
"conrod_winit 0.63.0 (git+https://gitlab.com/veloren/conrod.git?branch=copypasta_0.7#1ae5193588fb662a7189d81edd9f2d653c7f1da0)": "14sxyw8si0c2md5p5hssvfl12368hqp1fy6ighd7v4lb8fqwp6zj",
"euc 0.5.1 (git+https://github.com/zesterer/euc.git#c9a7c17a03d45fce00caeeca09afa1e1558cd183)": "0qvk0bx1arkgmdc59sip39zszdw2fwv6jcy5jinv18n5m1nrclw4",
"guillotiere 0.4.2 (git+https://github.com/Imberflur/guillotiere#42c298f5bcf0f95f1a004360d05e25ca3711e9ed)": "1knqbn777f3cgzbsaqawzclgrqf3nav6x3gjzc2hsls3acccx1ya",
"msgbox 0.4.0 (git+https://github.com/bekker/msgbox-rs.git?rev=68fe39a#68fe39a60019b38a1569ae4e9ed796a0f0542673)": "18h6s50n7mz2ggfishhi91p2298shqhzx5xagpg9q4zb4y90c2wr",
"iced_core 0.2.1 (git+https://github.com/hecrj/iced?rev=f464316#f46431600cb61d4e83e0ded1ca79525478436be3)": "08ixcznfi6wmznjyg0ahi9zs12x5mlbw1bznifqr66gkpa25kyp1",
"iced_futures 0.1.2 (git+https://github.com/hecrj/iced?rev=f464316#f46431600cb61d4e83e0ded1ca79525478436be3)": "08ixcznfi6wmznjyg0ahi9zs12x5mlbw1bznifqr66gkpa25kyp1",
"iced_graphics 0.1.0 (git+https://github.com/hecrj/iced?rev=f464316#f46431600cb61d4e83e0ded1ca79525478436be3)": "08ixcznfi6wmznjyg0ahi9zs12x5mlbw1bznifqr66gkpa25kyp1",
"iced_native 0.2.2 (git+https://github.com/hecrj/iced?rev=f464316#f46431600cb61d4e83e0ded1ca79525478436be3)": "08ixcznfi6wmznjyg0ahi9zs12x5mlbw1bznifqr66gkpa25kyp1",
"iced_style 0.1.0 (git+https://github.com/hecrj/iced?rev=f464316#f46431600cb61d4e83e0ded1ca79525478436be3)": "08ixcznfi6wmznjyg0ahi9zs12x5mlbw1bznifqr66gkpa25kyp1",
"iced_winit 0.1.1 (git+https://github.com/hecrj/iced?rev=f464316#f46431600cb61d4e83e0ded1ca79525478436be3)": "08ixcznfi6wmznjyg0ahi9zs12x5mlbw1bznifqr66gkpa25kyp1",
"portpicker 0.1.0 (git+https://github.com/xMAC94x/portpicker-rs#9d6df36c53c94684080a64a7212dd6bfc3617ee4)": "00vl2k3xfihxq86kf5rsknjl8dxmrxqhwajwn0hj4gzgnbssr0rx",
"scan_fmt 0.2.5 (git+https://github.com/Imberflur/scan_fmt#5f9e8eed73e93e8d19fa864d76e75bb4984cffe7)": "1g36jm3rii6iziqpddszhdk6bqpa7jzsbmrlfzmsmi16zcisrvid",
"specs 0.16.1 (git+https://github.com/amethyst/specs.git?rev=7a2e348ab2223818bad487695c66c43db88050a5#7a2e348ab2223818bad487695c66c43db88050a5)": "1z7gjiq7zirg9az3ly1y2ghi5m7s3x1bp35gw5x0cyv50fsi3pjq",
"specs-idvs 0.1.0 (git+https://gitlab.com/veloren/specs-idvs.git?branch=specs-git#fcb0b2306b571f62f9f85d89e79e087454d95efd)": "00w4kc60d7mjb5gbkcxrxzarshmhf4idqm3sk8335f7s3pn9q0s5",
"winit 0.22.2 (git+https://github.com/Imberflur/winit.git?branch=macos-test#e98133adf2abbfc4368f6c069d0beb2b8b688b42)": "0hv9wfsn1d5fwrs37vqyazrwys8665q03m9sygk2kal1jbl3x8zj"
"tui 0.10.0 (git+https://github.com/fdehau/tui-rs.git?branch=paragraph-scroll#54b841fab6cfdb38e8dc1382176e965787964b4c)": "0si3sp0hkjjrrfvmiynhai35pgjlnflw7qwwh268rpivdl8bd9xz",
"vek 0.12.0 (git+https://gitlab.com/veloren/vek.git?branch=fix_intrinsics#237a78528b505f34f6dde5dc77db3b642388fe4a)": "1v3kxjl826zf0zbi9pbwpw75ybidr0cdsgx772l0671zmp3yrkjg",
"winit 0.23.0 (git+https://gitlab.com/veloren/winit.git?branch=macos-test-spiffed#7c8c5f21384c898f50d37298d229093549b08803)": "1amfl8xpmyh7a4sy87iz5rybdgfn598crl6y6hxyrmyamg6cbqd4"
}

View File

@ -1,13 +1,39 @@
{ crateName ? "veloren-voxygen",
# `crate2nix` doesn't support profiles in `Cargo.toml`, so default to release. Otherwise bad performance (non-release is built with opt level 0)
release ? true, nixpkgs ? <nixpkgs>, system ? builtins.currentSystem
{
/* `crate2nix` doesn't support profiles in `Cargo.toml`, so default to release.
Otherwise bad performance (non-release is built with opt level 0)
*/
release ? true, cratesToBuild ? [ "veloren-voxygen" "veloren-server-cli" ]
, system ? builtins.currentSystem
, sources ? import ./sources.nix { inherit system; } }:
let
gitHash =
# Check if git-lfs is working.
isBuildingCrate = name:
builtins.any (otherName: name == otherName) cratesToBuild;
isBuildingVoxygen = isBuildingCrate "veloren-voxygen";
isBuildingServerCli = isBuildingCrate "veloren-server-cli";
pkgs = import ./nixpkgs.nix { inherit sources system; };
common = import ./common.nix { inherit pkgs; };
meta = with pkgs; {
description = "Veloren is a multiplayer voxel RPG written in Rust.";
longDescription = ''
Veloren is a multiplayer voxel RPG written in Rust.
It is inspired by games such as Cube World, Legend of Zelda: Breath of the Wild, Dwarf Fortress and Minecraft.
'';
homepage = "https://veloren.net";
upstream = "https://gitlab.com/veloren/veloren";
license = lib.licenses.gpl3;
maintainers = [ lib.maintainers.yusdacra ];
platforms = lib.platforms.all;
};
makeGitCommand = subcommands: name:
# Check if git-lfs is working. This is a partial check only,
# the actual check is done in `common/build.rs`. We do this
# so that the build fails early.
if builtins.pathExists ../assets/voxygen/background/bg_main.png then
builtins.readFile (pkgs.runCommand "getGitHash" { } ''
builtins.readFile (pkgs.runCommand name { } ''
cd ${
# Only copy the `.git` directory to nix store, anything else is a waste.
builtins.path {
@ -16,7 +42,7 @@ let
name = "git";
}
}
${pkgs.git}/bin/git log -n 1 --pretty=format:%h/%cd --date=format:%Y-%m-%d-%H:%M --abbrev=8 > $out
${pkgs.git}/bin/git ${subcommands} > $out
'')
else
abort ''
@ -28,23 +54,80 @@ let
See the book at https://book.veloren.net/ for details.
'';
pkgs = import ./nixpkgs.nix { inherit sources nixpkgs system; };
gitHash = makeGitCommand
"log -n 1 --pretty=format:%h/%cd --date=format:%Y-%m-%d-%H:%M --abbrev=8"
"getGitHash";
veloren = with pkgs;
gitTag =
# If the git command errors out we feed an empty string
makeGitCommand "describe --exact-match --tags HEAD || printf ''"
"getGitTag";
version = if gitTag != "" then gitTag else gitHash;
veloren-crates = with pkgs;
callPackage ./Cargo.nix {
defaultCrateOverrides = defaultCrateOverrides // {
libudev-sys = _: { buildInputs = [ pkg-config libudev ]; };
alsa-sys = _: { buildInputs = [ pkg-config alsaLib ]; };
veloren-common = _: { NIX_GIT_HASH = gitHash; };
veloren-network = _: { buildInputs = [ pkg-config openssl ]; };
veloren-voxygen = _: {
buildInputs = [ atk cairo glib gtk3 pango ];
nativeBuildInputs = [ makeWrapper ];
postInstall = ''
wrapProgram $out/bin/veloren-voxygen --set LD_LIBRARY_PATH ${xorg.libX11}/lib
'';
defaultCrateOverrides = with common;
defaultCrateOverrides // {
libudev-sys = _: { buildInputs = crateDeps.libudev-sys; };
alsa-sys = _: { buildInputs = crateDeps.alsa-sys; };
veloren-common = _:
(if isBuildingServerCli then {
DISABLE_GIT_LFS_CHECK = true;
} else
{ }) // {
# Declare env values here so that `common/build.rs` sees them
NIX_GIT_HASH = gitHash;
NIX_GIT_TAG = gitTag;
};
veloren-network = _: { buildInputs = crateDeps.veloren-network; };
veloren-server-cli = _: { VELOREN_USERDATA_STRATEGY = "system"; };
veloren-voxygen = _: {
VELOREN_USERDATA_STRATEGY = "system";
buildInputs = crateDeps.veloren-voxygen;
nativeBuildInputs = [ makeWrapper ];
postInstall = ''
wrapProgram $out/bin/veloren-voxygen --set LD_LIBRARY_PATH ${neededLibPaths}
'';
};
};
};
inherit release pkgs nixpkgs;
inherit release pkgs;
};
in veloren.workspaceMembers."${crateName}".build
veloren-assets = pkgs.symlinkJoin {
inherit version;
name = "veloren-assets_${version}";
paths = [
(pkgs.runCommand "mkVelorenAssetsDir" { } ''
mkdir -p $out/share/veloren
ln -sf ${../assets} $out/share/veloren/assets
'')
];
meta = meta // {
longDescription = ''
${meta.longDescription}
This package includes the assets.
'';
};
};
makePkg = name:
pkgs.symlinkJoin {
inherit version;
name = "${name}_${version}";
paths = [ veloren-crates.workspaceMembers."${name}".build ];
meta = meta // {
longDescription = ''
${meta.longDescription}
${if isBuildingVoxygen then
"This package includes the client, Voxygen."
else
""}
${if isBuildingServerCli then
"This package includes the server CLI."
else
""}
'';
};
};
in (pkgs.lib.genAttrs cratesToBuild makePkg) // { inherit veloren-assets; }

View File

@ -1,5 +1,5 @@
{ nixpkgs ? <nixpkgs>, system ? builtins.currentSystem
, sources ? import ./sources.nix { inherit system; } }:
{ system, sources ? import ./sources.nix { inherit system; }
, nixpkgs ? sources.nixpkgs }:
let
mozPkgs = import "${sources.nixpkgsMoz}/package-set.nix" {
@ -7,14 +7,15 @@ let
};
rustChannel = mozPkgs.rustChannelOf {
rustToolchain = ../rust-toolchain;
sha256 = "sha256-hKjJt5RAI9cf55orvwGEkOXIGOaySX5dD2aj3iQ/IDs=";
hash = "sha256-P4FTKRe0nM1FRDV0Q+QY2WcC8M9IR7aPMMLWDfv+rEk=";
};
in import nixpkgs {
inherit system;
overlays = [
(self: super: {
rustc = rustChannel.rust;
inherit (rustChannel) cargo rust rust-std rust-src;
inherit (rustChannel)
;
})
];
}

View File

@ -1,30 +1,15 @@
{ nixpkgs ? <nixpkgs>, sources ? import ./sources.nix { }
, system ? builtins.currentSystem }:
let
pkgs = import ./nixpkgs.nix { inherit sources nixpkgs system; };
crate2nix = import sources.crate2nix { inherit pkgs; };
in pkgs.mkShell {
common = import ./common.nix { inherit pkgs; };
crate2nix = pkgs.callPackage sources.crate2nix { inherit pkgs; };
in with pkgs;
mkShell {
name = "veloren-shell";
nativeBuildInputs = with pkgs; [
pkg-config
python3
git
git-lfs
niv
nixfmt
crate2nix
cargo
rustc
];
buildInputs = with pkgs; [
alsaLib
atk
cairo
glib
gtk3
libudev
openssl
pango
];
nativeBuildInputs = [ git git-lfs niv nixfmt crate2nix cargo rustc ];
buildInputs = lib.concatLists (lib.attrValues common.crateDeps);
shellHook = ''
export LD_LIBRARY_PATH=${common.neededLibPaths}
'';
}

View File

@ -5,10 +5,22 @@
"homepage": "",
"owner": "kolloch",
"repo": "crate2nix",
"rev": "602223cdd990f17edb7bd8587a44b9ba76f8e886",
"sha256": "1jvhi0crlgr570365w024xysx3myflaj0yqk8hx4nz6agvrpb0hc",
"rev": "df3e4e6570c1058d947d70876712209a1eca6731",
"sha256": "1kn98ckf2h4j3xmc50n6904p5g226qa1c1jgha511d9l6lgks24r",
"type": "tarball",
"url": "https://github.com/kolloch/crate2nix/archive/602223cdd990f17edb7bd8587a44b9ba76f8e886.tar.gz",
"url": "https://github.com/kolloch/crate2nix/archive/df3e4e6570c1058d947d70876712209a1eca6731.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgs": {
"branch": "nixpkgs-unstable",
"description": "Nix Packages collection",
"homepage": "",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6625284c397b44bc9518a5a1567c1b5aae455c08",
"sha256": "1w0czzv53sg35gp7sr506facbmzd33jm34p6cg23fb9kz5rf5c89",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/6625284c397b44bc9518a5a1567c1b5aae455c08.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"nixpkgsMoz": {
@ -17,10 +29,10 @@
"homepage": null,
"owner": "mozilla",
"repo": "nixpkgs-mozilla",
"rev": "efda5b357451dbb0431f983cca679ae3cd9b9829",
"sha256": "11wqrg86g3qva67vnk81ynvqyfj0zxk83cbrf0p9hsvxiwxs8469",
"rev": "8c007b60731c07dd7a052cce508de3bb1ae849b4",
"sha256": "1zybp62zz0h077zm2zmqs2wcg3whg6jqaah9hcl1gv4x8af4zhs6",
"type": "tarball",
"url": "https://github.com/mozilla/nixpkgs-mozilla/archive/efda5b357451dbb0431f983cca679ae3cd9b9829.tar.gz",
"url": "https://github.com/mozilla/nixpkgs-mozilla/archive/8c007b60731c07dd7a052cce508de3bb1ae849b4.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}

View File

@ -1,22 +1,26 @@
# This file has been generated by Niv.
{ system ? builtins.currentSystem }:
let
#
# The fetchers. fetch_<type> fetches specs of type <type>.
#
fetch_file = pkgs: spec:
if spec.builtin or true then
builtins_fetchurl { inherit (spec) url sha256; }
fetch_file = pkgs: name: spec:
let name' = sanitizeName name + "-src";
in if spec.builtin or true then
builtins_fetchurl {
inherit (spec) url sha256;
name = name';
}
else
pkgs.fetchurl { inherit (spec) url sha256; };
pkgs.fetchurl {
inherit (spec) url sha256;
name = name';
};
fetch_tarball = pkgs: name: spec:
let
ok = str: !builtins.isNull (builtins.match "[a-zA-Z0-9+-._?=]" str);
# sanitize the name, though nix will still fail if name starts with period
name' = stringAsChars (x: if !ok x then "-" else x) "${name}-src";
let name' = sanitizeName name + "-src";
in if spec.builtin or true then
builtins_fetchTarball {
name = name';
@ -28,10 +32,21 @@ let
inherit (spec) url sha256;
};
fetch_git = spec:
builtins.fetchGit {
fetch_git = name: spec:
let
ref = if spec ? ref then
spec.ref
else if spec ? branch then
"refs/heads/${spec.branch}"
else if spec ? tag then
"refs/tags/${spec.tag}"
else
abort
"In git source '${name}': Please specify `ref`, `tag` or `branch`!";
in builtins.fetchGit {
url = spec.repo;
inherit (spec) rev ref;
inherit (spec) rev;
inherit ref;
};
fetch_local = spec: spec.path;
@ -50,18 +65,25 @@ let
# Various helpers
#
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
sanitizeName = name:
(concatMapStrings (s: if builtins.isList s then "-" else s)
(builtins.split "[^[:alnum:]+._?=-]+"
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)));
# The set of packages used when specs are fetched using non-builtins.
mkPkgs = sources:
mkPkgs = sources: system:
let
sourcesNixpkgs =
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; })
{ };
sourcesNixpkgs = import
(builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {
inherit system;
};
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
in if builtins.hasAttr "nixpkgs" sources then
sourcesNixpkgs
else if hasNixpkgsPath && !hasThisAsNixpkgsPath then
import <nixpkgs> { inherit system; }
import <nixpkgs> { }
else
abort ''
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
@ -74,11 +96,11 @@ let
if !builtins.hasAttr "type" spec then
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
else if spec.type == "file" then
fetch_file pkgs spec
fetch_file pkgs name spec
else if spec.type == "tarball" then
fetch_tarball pkgs name spec
else if spec.type == "git" then
fetch_git spec
fetch_git name spec
else if spec.type == "local" then
fetch_local spec
else if spec.type == "builtin-tarball" then
@ -89,6 +111,15 @@ let
abort
"ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
# If the environment variable NIV_OVERRIDE_${name} is set, then use
# the path directly as opposed to the fetched source.
replace = name: drv:
let
saneName = stringAsChars
(c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
in if ersatz == "" then drv else ersatz;
# Ports of functions for older nix versions
# a Nix version of mapAttrs if the built-in doesn't exist
@ -112,21 +143,27 @@ let
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
concatMapStrings = f: list: concatStrings (map f list);
concatStrings = builtins.concatStringsSep "";
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
optionalAttrs = cond: as: if cond then as else { };
# fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, name, sha256 }@attrs:
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
let inherit (builtins) lessThan nixVersion fetchTarball;
in if lessThan nixVersion "1.12" then
fetchTarball { inherit name url; }
fetchTarball
({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else
fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, sha256 }@attrs:
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
let inherit (builtins) lessThan nixVersion fetchurl;
in if lessThan nixVersion "1.12" then
fetchurl { inherit url; }
fetchurl
({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else
fetchurl attrs;
@ -137,18 +174,24 @@ let
abort
"The values in sources.json should not have an 'outPath' attribute"
else
spec // { outPath = fetch config.pkgs name spec; }) config.sources;
spec // { outPath = replace name (fetch config.pkgs name spec); })
config.sources;
# The "config" used by the fetchers
mkConfig = { sourcesFile ? ./sources.json
, sources ? builtins.fromJSON (builtins.readFile sourcesFile)
, pkgs ? mkPkgs sources }: rec {
mkConfig = { sourcesFile ?
if builtins.pathExists ./sources.json then ./sources.json else null
, sources ? if isNull sourcesFile then
{ }
else
builtins.fromJSON (builtins.readFile sourcesFile)
, system ? builtins.currentSystem, pkgs ? mkPkgs sources system }: rec {
# The sources, i.e. the attribute set of spec name to spec
inherit sources;
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
inherit pkgs;
};
in mkSources (mkConfig { }) // {
__functor = _: settings: mkSources (mkConfig settings);
}