Merge pull request #8077 from Ericson2314/agda

Interactive `env` for developing Agda packages, and misc cleanup
This commit is contained in:
Mateusz Kowalczyk 2015-06-08 14:57:38 +01:00
commit 9bb5c2c488

View File

@ -7,100 +7,86 @@
, extension ? (self: super: {}) , extension ? (self: super: {})
}: }:
with stdenv.lib.strings;
let let
optionalString = stdenv.lib.optionalString; defaults = self : {
filter = stdenv.lib.filter; # There is no Hackage for Agda so we require src.
concatMapStringsSep = stdenv.lib.strings.concatMapStringsSep; inherit (self) src name;
concatMapStrings = stdenv.lib.strings.concatMapStrings;
unwords = stdenv.lib.strings.concatStringsSep " ";
mapInside = xs: unwords (map (x: x + "/*") xs);
in
{ mkDerivation = args:
let
postprocess = x: x // {
sourceDirectories = filter (y: !(y == null)) x.sourceDirectories;
propagatedBuildInputs = filter (y : ! (y == null)) x.propagatedBuildInputs;
propagatedUserEnvPkgs = filter (y : ! (y == null)) x.propagatedUserEnvPkgs;
everythingFile = if x.everythingFile == "" then "Everything.agda" else x.everythingFile;
passthru = { inherit (x) extras; }; isAgdaPackage = true;
extras = null;
};
defaults = self : { buildInputs = [ Agda ] ++ self.buildDepends;
# There is no Hackage for Agda so we require src. buildDepends = [];
inherit (self) src name;
isAgdaPackage = true; buildDependsAgda = stdenv.lib.filter
(dep: dep ? isAgdaPackage && dep.isAgdaPackage)
self.buildDepends;
buildDependsAgdaShareAgda = map (x: x + "/share/agda") self.buildDependsAgda;
buildInputs = [ Agda ] ++ self.buildDepends; # Not much choice here ;)
buildDepends = []; LANG = "en_US.UTF-8";
LOCALE_ARCHIVE = stdenv.lib.optionalString
stdenv.isLinux
"${glibcLocales}/lib/locale/locale-archive";
buildDependsAgda = filter everythingFile = "Everything.agda";
(dep: dep ? isAgdaPackage && dep.isAgdaPackage)
self.buildDepends;
buildDependsAgdaShareAgda = map (x: x + "/share/agda") self.buildDependsAgda;
# Not much choice here ;) propagatedBuildInputs = self.buildDependsAgda;
LANG = "en_US.UTF-8"; propagatedUserEnvPkgs = self.buildDependsAgda;
LOCALE_ARCHIVE = optionalString stdenv.isLinux "${glibcLocales}/lib/locale/locale-archive";
everythingFile = "Everything.agda"; # Immediate source directories under which modules can be found.
sourceDirectories = [ ];
propagatedBuildInputs = self.buildDependsAgda; # This is used if we have a top-level element that only serves
propagatedUserEnvPkgs = self.buildDependsAgda; # as the container for the source and we only care about its
# contents. The directories put here will have their
# *contents* copied over as opposed to sourceDirectories which
# would make a direct copy of the whole thing.
topSourceDirectories = [ "src" ];
# Immediate source directories under which modules can be found. # FIXME: `dirOf self.everythingFile` is what we really want, not hardcoded "./"
sourceDirectories = [ ]; includeDirs = self.buildDependsAgdaShareAgda
++ self.sourceDirectories ++ self.topSourceDirectories
++ [ "." ];
buildFlags = concatStringsSep " " (map (x: "-i " + x) self.includeDirs);
# This is used if we have a top-level element that only serves agdaWithArgs = "${Agda}/bin/agda ${self.buildFlags}";
# as the container for the source and we only care about its
# contents. The directories put here will have their
# *contents* copied over as opposed to sourceDirectories which
# would make a direct copy of the whole thing.
topSourceDirectories = [ "src" ];
# FIXME: `dirOf self.everythingFile` is what we really want, not hardcoded "./" buildPhase = ''
includeDirs = self.buildDependsAgdaShareAgda runHook preBuild
++ self.sourceDirectories ++ self.topSourceDirectories ${self.agdaWithArgs} ${self.everythingFile}
++ [ "." ]; runHook postBuild
buildFlags = unwords (map (x: "-i " + x) self.includeDirs); '';
agdaWithArgs = "${Agda}/bin/agda ${self.buildFlags}"; installPhase = let
srcFiles = self.sourceDirectories
++ map (x: x + "/*") self.topSourceDirectories;
in ''
runHook preInstall
mkdir -p $out/share/agda
cp -pR ${concatStringsSep " " srcFiles} $out/share/agda
runHook postInstall
'';
buildPhase = '' passthru = {
runHook preBuild env = stdenv.mkDerivation {
${self.agdaWithArgs} ${self.everythingFile} name = "interactive-${self.name}";
runHook postBuild inherit (self) LANG LOCALE_ARCHIVE;
''; AGDA_PACKAGE_PATH = concatMapStrings (x: x + ":") self.buildDependsAgdaShareAgda;
buildInputs = let
installPhase = ''
runHook preInstall
mkdir -p $out/share/agda
cp -pR ${unwords self.sourceDirectories} ${mapInside self.topSourceDirectories} $out/share/agda
runHook postInstall
'';
# Optionally-built conveniences
extras = {
# Makes a wrapper available to the user. Very useful in # Makes a wrapper available to the user. Very useful in
# nix-shell where all dependencies are -i'd. # nix-shell where all dependencies are -i'd.
agdaWrapper = writeScriptBin "agda" '' agdaWrapper = writeScriptBin "agda" ''
${self.agdaWithArgs} "$@" ${self.agdaWithArgs} "$@"
''; '';
in [agdaWrapper] ++ self.buildDepends;
# Use this to stick `agdaWrapper` at the front of the PATH:
#
# agda.mkDerivation (self: { PATH = self.extras.agdaWrapperPATH; })
#
# Not sure this is the best way to handle conflicts....
agdaWrapperPATH = "${self.extras.agdaWrapper}/bin:$PATH";
AGDA_PACKAGE_PATH = concatMapStrings (x: x + ":") self.buildDependsAgdaShareAgda;
};
}; };
in stdenv.mkDerivation };
(postprocess (let super = defaults self // args self; };
self = super // extension self super; in
in self)); { mkDerivation = args: let
super = defaults self // args self;
self = super // extension self super;
in stdenv.mkDerivation self;
} }