diff options
Diffstat (limited to 'Omni/Bild/Builder.nix')
-rw-r--r-- | Omni/Bild/Builder.nix | 291 |
1 files changed, 151 insertions, 140 deletions
diff --git a/Omni/Bild/Builder.nix b/Omni/Bild/Builder.nix index b4e6780..09e478b 100644 --- a/Omni/Bild/Builder.nix +++ b/Omni/Bild/Builder.nix @@ -1,11 +1,14 @@ -/* This is the library of nix builders. Some rules to follow: - - Keep this code as minimal as possible. I'd rather write Haskell than Nix, - wouldn't you? - - Try to reuse as much upstream Nix as possible. +/* +This is the library of nix builders. Some rules to follow: +- Keep this code as minimal as possible. I'd rather write Haskell than Nix, + wouldn't you? +- Try to reuse as much upstream Nix as possible. */ -{ analysisJSON, bild }: -with bild; -let +{ + analysisJSON, + bild, +}: +with bild; let analysis = builtins.fromJSON analysisJSON; # common bash functions for the builder @@ -16,158 +19,166 @@ let } ''; - build = _: target: - let - name = target.out; - root = builtins.getEnv "CODEROOT"; - mainModule = target.mainModule; - compileLine = lib.strings.concatStringsSep " " - ([ target.compiler ] ++ target.compilerFlags); + build = _: target: let + name = target.out; + root = builtins.getEnv "CODEROOT"; + mainModule = target.mainModule; + compileLine = + lib.strings.concatStringsSep " " + ([target.compiler] ++ target.compilerFlags); - allSources = target.srcs ++ [ target.quapath ]; + allSources = target.srcs ++ [target.quapath]; - isEmpty = x: x == null || x == [ ]; + isEmpty = x: x == null || x == []; - skip = [ "_" ".direnv" ]; - filter = file: type: - if lib.lists.elem (builtins.baseNameOf file) skip then - false - # TODO: this means any new directory will cause a rebuild. this bad. i - # should recurse into the directory and match against the srcs. for now I - # just use preBuild to delete empty dirs - else if type == "directory" then - true - else if type == "regular" then - lib.trivial.pipe file [ - (f: lib.strings.removePrefix "${root}/" f) - (f: lib.lists.elem f allSources) - ] - else - false; + skip = ["_" ".direnv"]; + filter = file: type: + if lib.lists.elem (builtins.baseNameOf file) skip + then false + # TODO: this means any new directory will cause a rebuild. this bad. i + # should recurse into the directory and match against the srcs. for now I + # just use preBuild to delete empty dirs + else if type == "directory" + then true + else if type == "regular" + then + lib.trivial.pipe file [ + (f: lib.strings.removePrefix "${root}/" f) + (f: lib.lists.elem f allSources) + ] + else false; - # remove empty directories, leftover from the src filter - preBuild = "find . -type d -empty -delete"; + # remove empty directories, leftover from the src filter + preBuild = "find . -type d -empty -delete"; - src = lib.sources.cleanSourceWith { - inherit filter; - src = lib.sources.cleanSource root; - }; + src = lib.sources.cleanSourceWith { + inherit filter; + src = lib.sources.cleanSource root; + }; - langdeps_ = if isEmpty target.langdeps then - [ ] + langdeps_ = + if isEmpty target.langdeps + then [] else lib.attrsets.attrVals target.langdeps (lib.attrsets.getAttrFromPath - (lib.strings.splitString "." target.packageSet) bild); + (lib.strings.splitString "." target.packageSet) + bild); - sysdeps_ = if isEmpty target.sysdeps then - [ ] - else - lib.attrsets.attrVals target.sysdeps pkgs; + sysdeps_ = + if isEmpty target.sysdeps + then [] + else lib.attrsets.attrVals target.sysdeps pkgs; - rundeps_ = if isEmpty target.rundeps then - [ ] - else - lib.attrsets.attrVals target.rundeps pkgs; + rundeps_ = + if isEmpty target.rundeps + then [] + else lib.attrsets.attrVals target.rundeps pkgs; - CODEROOT = "."; + CODEROOT = "."; - builders = { - base = stdenv.mkDerivation rec { - inherit name src CODEROOT preBuild; - buildInputs = langdeps_ ++ sysdeps_; - installPhase = "install -D ${name} $out/bin/${name}"; - buildPhase = compileLine; - }; + builders = { + base = stdenv.mkDerivation rec { + inherit name src CODEROOT preBuild; + buildInputs = langdeps_ ++ sysdeps_; + installPhase = "install -D ${name} $out/bin/${name}"; + buildPhase = compileLine; + }; - haskell = stdenv.mkDerivation rec { - inherit name src CODEROOT preBuild; - nativeBuildInputs = [ makeWrapper ]; - buildInputs = sysdeps_ ++ [ + haskell = stdenv.mkDerivation rec { + inherit name src CODEROOT preBuild; + nativeBuildInputs = [makeWrapper]; + buildInputs = + sysdeps_ + ++ [ (haskell.ghcWith (p: (lib.attrsets.attrVals target.langdeps p))) ]; - buildPhase = compileLine; - installPhase = '' - install -D ${name} $out/bin/${name} - wrapProgram $out/bin/${name} \ - --prefix PATH : ${lib.makeBinPath rundeps_} - ''; - }; + buildPhase = compileLine; + installPhase = '' + install -D ${name} $out/bin/${name} + wrapProgram $out/bin/${name} \ + --prefix PATH : ${lib.makeBinPath rundeps_} + ''; + }; - c = stdenv.mkDerivation rec { - inherit name src CODEROOT preBuild; - buildInputs = langdeps_ ++ sysdeps_; - installPhase = "install -D ${name} $out/bin/${name}"; - buildPhase = lib.strings.concatStringsSep " " [ - compileLine - (if isEmpty langdeps_ then - "" - else - "$(pkg-config --cflags ${ - lib.strings.concatStringsSep " " target.langdeps - })") - (if isEmpty sysdeps_ then - "" - else - "$(pkg-config --libs ${ - lib.strings.concatStringsSep " " target.sysdeps - })") - ]; - }; + c = stdenv.mkDerivation rec { + inherit name src CODEROOT preBuild; + buildInputs = langdeps_ ++ sysdeps_; + installPhase = "install -D ${name} $out/bin/${name}"; + buildPhase = lib.strings.concatStringsSep " " [ + compileLine + ( + if isEmpty langdeps_ + then "" + else "$(pkg-config --cflags ${ + lib.strings.concatStringsSep " " target.langdeps + })" + ) + ( + if isEmpty sysdeps_ + then "" + else "$(pkg-config --libs ${ + lib.strings.concatStringsSep " " target.sysdeps + })" + ) + ]; + }; - python = python.buildPythonApplication rec { - inherit name src CODEROOT; - nativeBuildInputs = [ makeWrapper ]; - propagatedBuildInputs = langdeps_ ++ sysdeps_ ++ rundeps_; - buildInputs = sysdeps_; - nativeCheckInputs = [ pkgs.ruff python.packages.mypy ]; - checkPhase = '' - . ${commonBash} - cp ${../../pyproject.toml} ./pyproject.toml - check ruff format --exclude 'setup.py' --check . - # ignore EXE here to support run.sh shebangs - check ruff check \ - --ignore EXE \ - --exclude 'setup.py' \ - --exclude '__init__.py' \ - . - touch ./py.typed - check python -m mypy \ - --explicit-package-bases \ - --no-error-summary \ - --exclude 'setup\.py$' \ - . - ''; - installCheck = '' - . ${commonBash} - check python -m ${mainModule} test - ''; - preBuild = '' - # remove empty directories, leftover from the src filter - find . -type d -empty -delete - # initialize remaining dirs as python modules - find . -type d -exec touch {}/__init__.py \; - # generate a minimal setup.py - cat > setup.py << EOF - from setuptools import find_packages, setup - setup( - name="${name}", - entry_points={"console_scripts":["${name} = ${mainModule}:main"]}, - version="0.0.0", - url="git://simatime.com/omni.git", - author="dev", - author_email="dev@simatime.com", - description="nil", - packages=find_packages(), - install_requires=[], - ) - EOF - ''; - pythonImportsCheck = [ mainModule ]; # sanity check - }; + python = python.buildPythonApplication rec { + inherit name src CODEROOT; + nativeBuildInputs = [makeWrapper]; + propagatedBuildInputs = langdeps_ ++ sysdeps_ ++ rundeps_; + buildInputs = sysdeps_; + nativeCheckInputs = [pkgs.ruff python.packages.mypy]; + checkPhase = '' + . ${commonBash} + cp ${../../pyproject.toml} ./pyproject.toml + check ruff format --exclude 'setup.py' --check . + # ignore EXE here to support run.sh shebangs + check ruff check \ + --ignore EXE \ + --exclude 'setup.py' \ + --exclude '__init__.py' \ + . + touch ./py.typed + check python -m mypy \ + --explicit-package-bases \ + --no-error-summary \ + --exclude 'setup\.py$' \ + . + ''; + installCheck = '' + . ${commonBash} + check python -m ${mainModule} test + ''; + preBuild = '' + # remove empty directories, leftover from the src filter + find . -type d -empty -delete + # initialize remaining dirs as python modules + find . -type d -exec touch {}/__init__.py \; + # generate a minimal setup.py + cat > setup.py << EOF + from setuptools import find_packages, setup + setup( + name="${name}", + entry_points={"console_scripts":["${name} = ${mainModule}:main"]}, + version="0.0.0", + url="git://simatime.com/omni.git", + author="dev", + author_email="dev@simatime.com", + description="nil", + packages=find_packages(), + install_requires=[], + ) + EOF + ''; + pythonImportsCheck = [mainModule]; # sanity check }; - in builders.${target.builder}; + }; + in + builders.${target.builder}; # the bild caller gives us the Analysis type, which is a hashmap, but i need to # return a single drv, so just take the first one for now. ideally i would only # pass Target, one at a time, (perhaps parallelized in haskell land) and then i # wouldn't need all of this let nesting -in builtins.head (lib.attrsets.mapAttrsToList build analysis) +in + builtins.head (lib.attrsets.mapAttrsToList build analysis) |