summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Aristote <quentin@aristote.fr>2021-12-03 11:48:19 +0100
committerQuentin Aristote <quentin@aristote.fr>2021-12-03 11:48:19 +0100
commit6bb027dbeb3dedb6c65cb27274465105bccdfb18 (patch)
tree7613a6397d866617c5c71cb3c906d86f03baba75
initial commit
-rw-r--r--.gitignore1
-rw-r--r--default.nix14
-rw-r--r--modules/coq.nix35
-rw-r--r--modules/default.nix149
-rw-r--r--modules/golang.nix22
-rw-r--r--modules/latex.nix95
-rw-r--r--modules/nix.nix16
-rw-r--r--modules/ocaml.nix92
-rw-r--r--modules/python.nix52
9 files changed, 476 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..30fa1ce
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+config \ No newline at end of file
diff --git a/default.nix b/default.nix
new file mode 100644
index 0000000..9da8a93
--- /dev/null
+++ b/default.nix
@@ -0,0 +1,14 @@
+{ pkgs, settings }:
+
+let
+ lib = pkgs.lib;
+ defaultSettings = lib.optional (lib.pathExists ./config/default.nix) ./config;
+ module = lib.evalModules {
+ modules = [ settings ./modules ] ++ defaultSettings;
+ specialArgs.pkgs = pkgs;
+ };
+in
+pkgs.mkShell ({
+ inherit (module.config)
+ inputsFrom buildInputs nativeBuildInputs shellHook exitHook;
+})
diff --git a/modules/coq.nix b/modules/coq.nix
new file mode 100644
index 0000000..3a1dfef
--- /dev/null
+++ b/modules/coq.nix
@@ -0,0 +1,35 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.coq;
+ coqBuildInputs = (with cfg.coqPackages; [ coq ])
+ ++ (cfg.packages cfg.coqPackages);
+in {
+ options.coq = {
+ enable = mkEnableOption { name = "coq"; };
+ coqPackages = mkOption {
+ type = types.lazyAttrsOf types.package;
+ default = pkgs.coqPackages;
+ defaultText = literalExample "pkgs.coqPackages";
+ description = ''
+ The set of Coq packages from which to get Coq and its packages.
+ Use this option to set the version of Coq.
+ '';
+ };
+ packages = mkOption {
+ type = with types; functionTo (listOf package);
+ default = _: [ ];
+ defaultText = literalExample "_: [ ]";
+ description = ''
+ Coq packages that will be made available to the environment.
+ '';
+ example = literalExample ''
+ coqPackages: with coqPackages; [ autosubst ];
+ '';
+ };
+ };
+ config = mkIf cfg.enable {
+ buildInputs = coqBuildInputs;
+ };
+}
diff --git a/modules/default.nix b/modules/default.nix
new file mode 100644
index 0000000..fbe500d
--- /dev/null
+++ b/modules/default.nix
@@ -0,0 +1,149 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let cfg = config;
+in {
+ imports =
+ [ ./coq.nix ./golang.nix ./latex.nix ./nix.nix ./python.nix ./ocaml.nix ];
+
+ options = {
+ # Inputs
+ inputsFrom = mkOption {
+ type = types.listOf types.package;
+ default = [ ];
+ description = ''
+ The list of derivations whose inputs will be made available to the environment.
+ '';
+ example = literalExample ''
+ [ pkgs.python3 ]
+ '';
+ };
+ buildInputs = mkOption {
+ type = types.listOf types.package;
+ default = [ ];
+ description = ''
+ The list of derivations which will be made available to the environment.
+ '';
+ example = literalExample ''
+ [ pkgs.ocamlPackages.owl ]
+ '';
+ };
+ nativeBuildInputs = mkOption {
+ type = types.listOf types.package;
+ default = [ ];
+ description = ''
+ The list of derivations which will be made available to the environment at run-time.
+ '';
+ example = literalExample ''
+ [ pkgs.python3 ];
+ '';
+ };
+
+ # EnvVars
+ envVars = mkOption {
+ type = types.attrsOf (types.submodule {
+ options = {
+ reset = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ If `true`, reset the value of the variable before changing it.
+ If `false`, the new value is thus set as $VAR=$VAR:`config.envVars.VAR.value`.
+ '';
+ };
+ value = mkOption {
+ type = types.envVar;
+ default = "";
+ description = ''
+ The new value to give to the environment variable.
+ '';
+ };
+ };
+ });
+ default = { };
+ description = ''
+ Environment variables that will be made available to the environment.
+ '';
+ example = {
+ PATH = {
+ reset = true;
+ value = "~/.local/bin";
+ };
+ };
+ };
+ aliases = mkOption {
+ type = types.attrsOf types.str;
+ default = { };
+ description = ''
+ Aliases.
+ If direnv is enabled, they are installed as executables in
+ .direnv/aliases. They may then take arguments. This also means that
+ "recursive" aliases (e.g. ssh="export A=something ssh") will fail ; the
+ executable in the definition should be called by its full path (e.g.
+ $\{pkgs.openssh\}/bin/ssh).
+ '';
+ example = literalExample ''
+ { zz = "ls -la"; };
+ '';
+ };
+
+ # Misc
+ ## Whether the shell is to be loaded by direnv
+ direnv.enable = mkEnableOption "direnv";
+
+ # Hooks
+ shellHook = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Commands to run after initializing the environment.
+ '';
+ example = ''
+ alias ll="ls -l"
+ git status
+ '';
+ };
+ exitHook = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Commands to run when exiting the shell.
+ '';
+ example = ''
+ git clean
+ '';
+ };
+ };
+
+ config.shellHook = concatStringsSep "\n" (
+ # Environment variables are declared in a shell hook because simply adding the
+ # top-level arguments of pkgs.mkShell ovewrites the old values of the
+ # variables, which may be a problem, for example for PATH.
+ (let
+ dollar = "$";
+ makeEnvVarCommand = name:
+ { reset, value }:
+ ''
+ export "${name}"=${
+ optionalString (!reset) (''"${dollar}${name}":'')
+ }"${value}"'';
+ in (attrValues (mapAttrs makeEnvVarCommand cfg.envVars)))
+ ++ (if cfg.direnv.enable then
+ (let
+ aliasDir = ''"$PWD"/.direnv/aliases'';
+ makeAliasCommand = name: value:
+ let target = ''${aliasDir}/${name}'';
+ in ''
+ echo '#!${pkgs.bash}/bin/bash -e' > "${target}"
+ echo "${value}" >> "${target}"
+ chmod +x "${target}"
+ '';
+ in ([''
+ mkdir -p "${aliasDir}"
+ rm -f "${aliasDir}"/*
+ PATH="${aliasDir}":"$PATH" # $PATH has to come last for the alias to take effect
+ ''] ++ (attrValues (mapAttrs makeAliasCommand cfg.aliases))))
+ else
+ (let makeAliasCommand = name: value: ''alias "${name}"="${value}"'';
+ in (attrValues (mapAttrs makeAliasCommand cfg.aliases)))));
+}
diff --git a/modules/golang.nix b/modules/golang.nix
new file mode 100644
index 0000000..e6e0821
--- /dev/null
+++ b/modules/golang.nix
@@ -0,0 +1,22 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let cfg = config.golang;
+in {
+ options.golang = {
+ enable = mkEnableOption { name = "golang"; };
+ package = mkOption {
+ type = types.package;
+ default = pkgs.go;
+ defaultText = literalExample "pkgs.go";
+ description = ''
+ The package for Go. This sets the version of Go..
+ '';
+ example = literalExample "pkgs.go_1_15";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ buildInputs = [ cfg.package ] ++ (with pkgs; [ gofumpt golint ]);
+ };
+}
diff --git a/modules/latex.nix b/modules/latex.nix
new file mode 100644
index 0000000..0c06ec7
--- /dev/null
+++ b/modules/latex.nix
@@ -0,0 +1,95 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.latex;
+ latexmkFlags = concatStringsSep " " ([
+ (if cfg.latexmk.output.dvi.enable then "-dvi" else "-dvi-")
+ (if cfg.latexmk.output.ps.enable then "-ps" else "-ps-")
+ (if cfg.latexmk.output.pdf.enable then
+ ("-pdf" + cfg.latexmk.output.pdf.method)
+ else
+ "-pdf-")
+ (optionalString cfg.minted.enable "-shell-escape")
+ ] ++ (map (filename: ''-r "${filename}"'') cfg.latexmk.rc)
+ ++ cfg.latexmk.extraFlags);
+ latexBuildInput = cfg.texlive.combine ((cfg.packages cfg.texlive)
+ // (optionalAttrs cfg.latexmk.enable { inherit (cfg.texlive) latexmk; })
+ // (optionalAttrs cfg.minted.enable { inherit (cfg.texlive) minted; }));
+in {
+ options.latex = {
+ enable = mkEnableOption { name = "LaTex"; };
+
+ texlive = mkOption {
+ type = types.attrs;
+ default = pkgs.texlive;
+ defaultText = literalExample "pkgs.texlive";
+ description = ''
+ The package providing LaTex.
+ Use this option to set the version of LaTex.
+ '';
+ };
+
+ packages = mkOption {
+ type = with types; functionTo attrs;
+ default = tl: { inherit (tl) scheme-full; };
+ defaultText = literalExample "tl: { inherit (tl) scheme-full; }";
+ description = ''
+ Collection of packages that will be made available to the environment.
+ '';
+ example = literalExample ''
+ tl: {
+ inherit (tl) scheme-full calligra;
+ my-package = { pkgs = [ (pkgs.callPackage ./my-package.nix {}) ]; };
+ }
+ '';
+ };
+
+ latexmk = {
+ enable = mkEnableOption "latexmk";
+ output = {
+ dvi.enable = mkEnableOption "dvi output";
+ pdf = {
+ enable = mkEnableOption "pdf output";
+ method = mkOption {
+ type = types.enum [ "" "dvi" "lua" "ps" "xe" ];
+ default = "lua";
+ description = ''
+ Method by which to generate the pdf.
+ '';
+ };
+ };
+ ps.enable = mkEnableOption "ps output";
+ };
+ rc = mkOption {
+ type = types.listOf types.path;
+ default = [ ];
+ description = ''
+ List of LaTeXmk rc files to load.
+ '';
+ example = literalExample "[ ~/.config/latexmkrc ]";
+ };
+ extraFlags = mkOption {
+ # TODO vulnerable to shell injection
+ type = types.listOf types.str;
+ default = [ ];
+ description = ''
+ Flags to pass to latexmk.
+ '';
+ example = [ "-shell-escape" "-M" ];
+ };
+ };
+
+ minted.enable = mkEnableOption "minted";
+ };
+
+ config = mkIf cfg.enable {
+ buildInputs = [ latexBuildInput ] ++ (optional cfg.latexmk.enable pkgs.ps);
+ aliases.latexmk = mkIf cfg.latexmk.enable
+ "${latexBuildInput}/bin/latexmk ${latexmkFlags} \\$@";
+ python = mkIf cfg.minted.enable {
+ enable = true;
+ packages = ps: with ps; [ pygments ];
+ };
+ };
+}
diff --git a/modules/nix.nix b/modules/nix.nix
new file mode 100644
index 0000000..a960e28
--- /dev/null
+++ b/modules/nix.nix
@@ -0,0 +1,16 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let cfg = config.nix;
+in {
+ options.nix = { enable = mkEnableOption "nix"; };
+
+ config = mkIf cfg.enable {
+ buildInputs = with pkgs; [
+ nixfmt
+ nixos-option
+ nix-prefetch-scripts
+ nix-prefetch-github
+ ];
+ };
+}
diff --git a/modules/ocaml.nix b/modules/ocaml.nix
new file mode 100644
index 0000000..d5393b0
--- /dev/null
+++ b/modules/ocaml.nix
@@ -0,0 +1,92 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+with builtins;
+let
+ cfg = config.ocaml;
+ ocamlVersion = (parseDrvName cfg.ocamlPackages.ocaml.name).version;
+
+ tuaregPackages = optionals cfg.tuareg.enable (with pkgs; [ ocamlformat opam ])
+ ++ (with cfg.ocamlPackages; [ merlin ocp-indent utop ]);
+ userPackages = cfg.packages cfg.ocamlPackages;
+ ocamlBuildInputs = (with cfg.ocamlPackages; [ ocaml findlib ]) ++ (with pkgs;
+ if versionAtLeast ocamlVersion "4.12" then
+ [ dune_2 ]
+ else
+ (optional (versionAtLeast ocamlVersion "4.02") dune_1)) ++ tuaregPackages
+ ++ userPackages;
+
+ ocamlInit = pkgs.writeText "ocamlinit" (''
+ let () =
+ try Topdirs.dir_directory "${cfg.ocamlPackages.findlib}/lib/ocaml/${ocamlVersion}/site-lib"
+ with Not_found -> ()
+ ;;
+ #use "topfind";;
+ '' + (optionalString cfg.toplevel.list "#list;;")
+ + (optionalString cfg.toplevel.thread "#thread;;") + (concatStringsSep "\n"
+ (map (pkg: ''#require "${pkg.pname}";;'') userPackages))
+ + cfg.toplevel.extraInit);
+in {
+ options.ocaml = {
+ enable = mkEnableOption { name = "ocaml"; };
+ ocamlPackages = mkOption {
+ type = types.lazyAttrsOf types.package;
+ default = pkgs.ocamlPackages;
+ defaultText = literalExample "pkgs.ocamlPackages";
+ description = ''
+ The set of OCaml packages from which to get OCaml and its packages.
+ Use this option to set the version of OCaml.
+ '';
+ example = literalExample "pkgs.ocaml-ng.ocamlPackages_4_11";
+ };
+ packages = mkOption {
+ type = with types; functionTo (listOf package);
+ default = _: [ ];
+ defaultText = literalExample "_ : []";
+ description = ''
+ OCaml packages that will be made available to the environment.
+ '';
+ example = literalExample ''
+ ocamlPackages: with ocamlPackages; [ owl lwt ];
+ '';
+ };
+ toplevel = {
+ require = mkOption {
+ type = types.listOf types.str;
+ default = builtins.map (pkg: pkg.pname) cfg.packages;
+ defaultText = "builtins.map (pkg: pkg.pname) config.ocaml.packages";
+ description = ''
+ The list of names of packages to load when launching a top-level.
+ '';
+ example = [ "owl" "lwt" ];
+ };
+ # Whether to list loaded packages when launching a top-level.
+ list = mkEnableOption "#require list;;";
+ # Whether to enable threading when running a top-level.
+ thread = mkEnableOption "#require thread;;";
+ extraInit = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Additional commands to run when running a top-level.
+ '';
+ example = "Topfind.reset();;";
+ };
+ };
+ # Whether to load packages required by Tuareg (Emacs' OCaml mode).
+ tuareg.enable = mkEnableOption "tuareg";
+ };
+
+ config = mkIf cfg.enable {
+ buildInputs = ocamlBuildInputs;
+ aliases = {
+ utop = let
+ utops = builtins.filter
+ (p: match "(.*-utop)" (parseDrvName p.name).name != null)
+ ocamlBuildInputs;
+ utop = head utops;
+ in mkIf (utops != [ ]) ''${utop}/bin/utop -init "${ocamlInit}"'';
+ ocaml = ''${cfg.ocamlPackages.ocaml}/bin/ocaml -init "${ocamlInit}"'';
+ };
+ };
+}
diff --git a/modules/python.nix b/modules/python.nix
new file mode 100644
index 0000000..ce1154c
--- /dev/null
+++ b/modules/python.nix
@@ -0,0 +1,52 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.python;
+ pythonWithPackages = (cfg.python.withPackages cfg.packages).override {
+ ignoreCollisions = cfg.ignoreCollisions;
+ };
+in {
+ options.python = {
+ enable = mkEnableOption { name = "python"; };
+
+ python = mkOption {
+ type = types.package;
+ default = pkgs.python3;
+ defaultText = literalExample "pkgs.python3Minimal";
+ description = ''
+ The package providing python.
+ Use this option to set the version of Python.
+ '';
+ example = literalExample "pkgs.python310";
+ };
+
+ packages = mkOption {
+ type = with types; functionTo (listOf package);
+ default = _: [ ];
+ defaultText = literalExample "_: []";
+ description = ''
+ Python packages that will be made available to the environment.
+ '';
+ example = literalExample ''
+ pythonPackages: with pythonPackages; [
+ requests (callPackage ./my-package.nix {})
+ ];
+ '';
+ };
+
+ ignoreCollisions = mkEnableOption "ignoring collisions when building the Python environnement";
+ };
+
+ config = mkIf cfg.enable {
+ buildInputs = [ pythonWithPackages ];
+ # shellHook = ''
+ # # Tells pip to put packages into $PIP_PREFIX instead of the usual locations.
+ # # See https://pip.pypa.io/en/stable/user_guide/#environment-variables.
+ # export PIP_PREFIX=$(pwd)/_build/pip_packages
+ # export PYTHONPATH="$PIP_PREFIX/${cfg.python.sitePackages}:$PYTHONPATH"
+ # export PATH="$PIP_PREFIX/bin:$PATH"
+ # unset SOURCE_DATE_EPOCH
+ # '';
+ };
+}