diff --git a/.gitignore b/.gitignore index 019f773..581da8a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ backup/ result +.env + *.nix.bak *.nix~ /nix/store/ diff --git a/flake.lock b/flake.lock index 29da067..e79f8d6 100644 --- a/flake.lock +++ b/flake.lock @@ -18,45 +18,6 @@ "type": "github" } }, - "flake-parts_2": { - "inputs": { - "nixpkgs-lib": [ - "nixvim", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1738453229, - "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "home-manager": { "inputs": { "nixpkgs": [ @@ -64,11 +25,11 @@ ] }, "locked": { - "lastModified": 1741955947, - "narHash": "sha256-2lbURKclgKqBNm7hVRtWh0A7NrdsibD0EaWhahUVhhY=", + "lastModified": 1742670145, + "narHash": "sha256-xQ2F9f+ICAGBp/nNv3ddD2U4ZvzuLOci0u/5lyMXPvk=", "owner": "nix-community", "repo": "home-manager", - "rev": "4e12151c9e014e2449e0beca2c0e9534b96a26b4", + "rev": "63e77d09a133ac641a0c204e7cfb0c97e133706d", "type": "github" }, "original": { @@ -77,45 +38,17 @@ "type": "github" } }, - "ixx": { - "inputs": { - "flake-utils": [ - "nixvim", - "nuschtosSearch", - "flake-utils" - ], - "nixpkgs": [ - "nixvim", - "nuschtosSearch", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1729958008, - "narHash": "sha256-EiOq8jF4Z/zQe0QYVc3+qSKxRK//CFHMB84aYrYGwEs=", - "owner": "NuschtOS", - "repo": "ixx", - "rev": "9fd01aad037f345350eab2cd45e1946cc66da4eb", - "type": "github" - }, - "original": { - "owner": "NuschtOS", - "ref": "v0.0.6", - "repo": "ixx", - "type": "github" - } - }, "nix-gaming": { "inputs": { "flake-parts": "flake-parts", "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1742089599, - "narHash": "sha256-1yBAFE5yEGEjSWZ8BuPt9Yknq+cFwzW6Q86gs5rMkGI=", + "lastModified": 1742607855, + "narHash": "sha256-lUF/tpSON29qNIqhECX/Ue4qVmI3FOvMaW4iUnK49C4=", "owner": "fufexan", "repo": "nix-gaming", - "rev": "bbf6f68ec16cead3c29d5ba33d5c52956dfaefdf", + "rev": "9818734e2117dac703767585d48b805fad3e7a5e", "type": "github" }, "original": { @@ -157,11 +90,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1741862977, - "narHash": "sha256-prZ0M8vE/ghRGGZcflvxCu40ObKaB+ikn74/xQoNrGQ=", + "lastModified": 1742512142, + "narHash": "sha256-8XfURTDxOm6+33swQJu/hx6xw1Tznl8vJJN5HwVqckg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "cdd2ef009676ac92b715ff26630164bb88fec4e0", + "rev": "7105ae3957700a9646cc4b766f5815b23ed0c682", "type": "github" }, "original": { @@ -171,72 +104,11 @@ "type": "github" } }, - "nixvim": { - "inputs": { - "flake-parts": "flake-parts_2", - "nixpkgs": [ - "nixpkgs" - ], - "nuschtosSearch": "nuschtosSearch" - }, - "locked": { - "lastModified": 1741814789, - "narHash": "sha256-NbHsnnNwiYUcUaS4z8XK2tYpo3G8NXEKxaKkzMgMiLk=", - "owner": "nix-community", - "repo": "nixvim", - "rev": "33097dcf776d1fad0ff3842096c4e3546312f251", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixvim", - "type": "github" - } - }, - "nuschtosSearch": { - "inputs": { - "flake-utils": "flake-utils", - "ixx": "ixx", - "nixpkgs": [ - "nixvim", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1738508923, - "narHash": "sha256-4DaDrQDAIxlWhTjH6h/+xfG05jt3qDZrZE/7zDLQaS4=", - "owner": "NuschtOS", - "repo": "search", - "rev": "86e2038290859006e05ca7201425ea5b5de4aecb", - "type": "github" - }, - "original": { - "owner": "NuschtOS", - "repo": "search", - "type": "github" - } - }, "root": { "inputs": { "home-manager": "home-manager", "nix-gaming": "nix-gaming", - "nixpkgs": "nixpkgs_2", - "nixvim": "nixvim" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" + "nixpkgs": "nixpkgs_2" } } }, diff --git a/flake.nix b/flake.nix index 91184c3..57f5809 100644 --- a/flake.nix +++ b/flake.nix @@ -7,46 +7,48 @@ url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; - nixvim = { - url = "github:nix-community/nixvim"; - inputs.nixpkgs.follows = "nixpkgs"; - }; nix-gaming = { url = "github:fufexan/nix-gaming"; }; }; - outputs = { self, nixpkgs, home-manager, nixvim, nix-gaming, ... }@inputs: - let - system = "x86_64-linux"; - customPkgsOverlay = final: prev: import ./pkgs { + outputs = { + self, + nixpkgs, + home-manager, + nix-gaming, + ... + } @ inputs: let + system = "x86_64-linux"; + customPkgsOverlay = final: prev: + import ./pkgs { pkgs = prev; lib = prev.lib; }; - pkgs = import nixpkgs { + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + overlays = [customPkgsOverlay]; + }; + lib = nixpkgs.lib; + in { + nixosConfigurations = { + nixos = lib.nixosSystem { inherit system; - config.allowUnfree = true; - overlays = [ customPkgsOverlay ]; - }; - lib = nixpkgs.lib; - in { - nixosConfigurations = { - nixos = lib.nixosSystem { - inherit system; - specialArgs = { inherit inputs; }; - modules = [ - { nixpkgs.overlays = [ customPkgsOverlay ]; } - ./hosts/configuration.nix - ]; - }; - }; - - homeConfigurations = { - "cobray" = home-manager.lib.homeManagerConfiguration { - inherit pkgs; - extraSpecialArgs = { inherit inputs; }; - modules = [ ./home-manager/cobray.nix ]; - }; + specialArgs = {inherit inputs;}; + modules = [ + {nixpkgs.overlays = [customPkgsOverlay];} + ./hosts/configuration.nix + ]; }; }; + + homeConfigurations = { + "cobray" = home-manager.lib.homeManagerConfiguration { + inherit pkgs; + extraSpecialArgs = {inherit inputs;}; + modules = [./home-manager/cobray.nix]; + }; + }; + }; } diff --git a/home-manager/cobray.nix b/home-manager/cobray.nix index d8f5207..02189a3 100644 --- a/home-manager/cobray.nix +++ b/home-manager/cobray.nix @@ -1,12 +1,13 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { imports = [ - ./modules/cava.nix ./modules/dunst.nix ./modules/fish.nix ./modules/ghostty.nix - ./modules/i3.nix ./modules/lazygit.nix ./modules/nvim.nix ./modules/picom.nix @@ -27,10 +28,10 @@ gnused gnugrep findutils + yazi htop btop nvtopPackages.full arandr - nitrogen ]; } diff --git a/home-manager/modules/cava.nix b/home-manager/modules/cava.nix deleted file mode 100644 index 909564f..0000000 --- a/home-manager/modules/cava.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - home.packages = with pkgs; [ - cava - ]; -} diff --git a/home-manager/modules/dunst.nix b/home-manager/modules/dunst.nix index 16686d6..df6dd53 100644 --- a/home-manager/modules/dunst.nix +++ b/home-manager/modules/dunst.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ dunst ]; diff --git a/home-manager/modules/fish.nix b/home-manager/modules/fish.nix index e8df928..9673e14 100644 --- a/home-manager/modules/fish.nix +++ b/home-manager/modules/fish.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ fish-rust starship @@ -10,5 +13,4 @@ fd ripgrep ]; - } diff --git a/home-manager/modules/ghostty.nix b/home-manager/modules/ghostty.nix index 6eff39b..f6bfb42 100644 --- a/home-manager/modules/ghostty.nix +++ b/home-manager/modules/ghostty.nix @@ -1,7 +1,11 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ - ghostty + ghostty + fastfetch ]; } diff --git a/home-manager/modules/i3.nix b/home-manager/modules/i3.nix deleted file mode 100644 index 3587262..0000000 --- a/home-manager/modules/i3.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - home.packages = with pkgs; [ - dmenu - i3status - i3lock - i3blocks - feh - yazi - udiskie - ]; -} diff --git a/home-manager/modules/lazygit.nix b/home-manager/modules/lazygit.nix index 0fbbd60..b35c895 100644 --- a/home-manager/modules/lazygit.nix +++ b/home-manager/modules/lazygit.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ lazygit ]; diff --git a/home-manager/modules/nvim.nix b/home-manager/modules/nvim.nix index 0732de2..5a0004e 100644 --- a/home-manager/modules/nvim.nix +++ b/home-manager/modules/nvim.nix @@ -2,18 +2,47 @@ { home.packages = with pkgs; [ neovim - ripgrep + gnugrep fd + fzf nodejs gcc + git + luajit + luaPackages.luarocks + nil + lua-language-server + curl + unzip + alejandra ]; - xdg.configFile."nvim" = { - source = builtins.fetchGit { - url = "https://github.com/alsaiduq-lab/dotfiles.git"; - ref = "dev"; - rev = "99e2cab828459373bc7524690668fdd209b3f517"; - }; + home.sessionVariables = { + LUA_PATH = "${pkgs.luajit}/share/lua/5.1/?.lua;${pkgs.luajit}/share/lua/5.1/?/init.lua;;"; + LUA_CPATH = "${pkgs.luajit}/lib/lua/5.1/?.so;;"; + }; + + home.sessionPath = [ + "$HOME/.local/share/nvim/mason/bin" + ]; + + xdg.configFile."nvim" = let + nvimConfigPath = "${config.home.homeDirectory}/.config/nvim"; + # nvimDotfiles = builtins.fetchGit { + # url = "https://github.com/alsaiduq-lab/nvim-dotfiles.git"; + # ref = "master"; + # rev = "71155b4a4b63d9974f1bc3b66303d6f7e5e06871"; + # }; + in { + source = pkgs.emptyDirectory; recursive = true; + enable = !builtins.pathExists nvimConfigPath; + onChange = '' + echo "Neovim config at ${nvimConfigPath} was ${ + if builtins.pathExists nvimConfigPath + then "skipped (already exists)" + else "installed" + }" + ''; }; } diff --git a/home-manager/modules/picom.nix b/home-manager/modules/picom.nix index b522b47..cd0ea0f 100644 --- a/home-manager/modules/picom.nix +++ b/home-manager/modules/picom.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ picom ]; diff --git a/home-manager/modules/polybar.nix b/home-manager/modules/polybar.nix index f33dd5f..6e49875 100644 --- a/home-manager/modules/polybar.nix +++ b/home-manager/modules/polybar.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ polybar ]; diff --git a/home-manager/modules/rofi.nix b/home-manager/modules/rofi.nix index 72dc8ae..511832f 100644 --- a/home-manager/modules/rofi.nix +++ b/home-manager/modules/rofi.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ rofi ]; diff --git a/home-manager/modules/starship.nix b/home-manager/modules/starship.nix index 1a32fbe..1e60569 100644 --- a/home-manager/modules/starship.nix +++ b/home-manager/modules/starship.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ starship ]; diff --git a/home-manager/modules/zellij.nix b/home-manager/modules/zellij.nix index d7da232..a668691 100644 --- a/home-manager/modules/zellij.nix +++ b/home-manager/modules/zellij.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { home.packages = with pkgs; [ zellij ]; diff --git a/hosts/configuration.nix b/hosts/configuration.nix index b68c0a0..194087a 100644 --- a/hosts/configuration.nix +++ b/hosts/configuration.nix @@ -1,10 +1,13 @@ # Edit this configuration file to define what should be installed on # your system. Help is available in the configuration.nix(5) man page # and in the NixOS manual (accessible by running 'nixos-help'). - -{ config, pkgs, lib, inputs, ... }: - { + config, + pkgs, + lib, + inputs, + ... +}: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix diff --git a/hosts/hardware-configuration.nix b/hosts/hardware-configuration.nix index 350633c..8b598b7 100644 --- a/hosts/hardware-configuration.nix +++ b/hosts/hardware-configuration.nix @@ -14,7 +14,7 @@ boot.extraModulePackages = [ ]; fileSystems."/" = - { device = "/dev/disk/by-uuid/07f76e3c-2dcf-4cda-99bf-657f1dc5885f"; + { device = "/dev/disk/by-uuid/b7877a82-a67d-4362-ad36-ac513d7c0fc6"; fsType = "ext4"; }; diff --git a/hosts/local-packages.nix b/hosts/local-packages.nix index 7251c41..7d89de7 100644 --- a/hosts/local-packages.nix +++ b/hosts/local-packages.nix @@ -1,18 +1,24 @@ { config, pkgs, lib, ... }: - let customPkgs = import ../pkgs { inherit pkgs lib; }; -in -{ +in { + imports = [ + ../modules/python.nix + ]; + python.enable = true; environment.systemPackages = with pkgs; [ - # Applications - brave - ghostty + (python311.withPackages (pyPkgs: with pyPkgs; [ + requests + pip + virtualenv + ipython + ])) + python3Packages.pip + black + ruff + brave # TODO: make a module to save browser stuff vesktop - neovim git - fastfetch - # Development tools nodejs wget curl @@ -20,8 +26,13 @@ in gnumake gcc socat + ffmpeg + gnused gdb + stdenv.cc.cc.lib + nix-prefetch-git binutils + hashcat cmake ninja pkg-config @@ -31,40 +42,12 @@ in gawk obs-studio lazygit - # Java ecosystem jdk17 + bun maven gradle visualvm jdt-language-server - (python310.withPackages (ps: with ps; [ - virtualenv - ipython - i3ipc - xlib - six - psutil - pynvml - pyqtgraph - pyqt6 - numpy - pandas - matplotlib - scipy - requests - click - typer - rich - pyyaml - pytz - onnxruntime - opencv4 - pillow - ] ++ [ customPkgs.python-rembg ])) - uv - ruff - black - mypy htop btop nvtopPackages.full @@ -79,9 +62,7 @@ in deno redis cloudflared - # Rust ecosystem rustup - rust-analyzer cargo-edit cargo-watch cargo-outdated @@ -91,19 +72,16 @@ in pkg-config libxml2 zlib - # Haskell ecosystem ghc cabal-install stack haskell-language-server - # Database tools postgresql sqlite - # Version control tools + spotify git-lfs gitAndTools.gh gitAndTools.diff-so-fancy - # misc ani-cli yt-dlp nmap @@ -112,5 +90,14 @@ in unzip starship flameshot + yarn + mpv + httpie + wrk + nodePackages.pnpm + zlib.dev ]; + environment.shellAliases = { + python = "python3.11"; + }; } diff --git a/modules/audio.nix b/modules/audio.nix index b8278a3..2ca23c8 100644 --- a/modules/audio.nix +++ b/modules/audio.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { security.rtkit.enable = true; services.pipewire = { enable = true; diff --git a/modules/bluetooth.nix b/modules/bluetooth.nix index 6d2e332..e704bde 100644 --- a/modules/bluetooth.nix +++ b/modules/bluetooth.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { hardware.bluetooth = { enable = true; powerOnBoot = true; diff --git a/modules/boot.nix b/modules/boot.nix index 73e42ab..d313ed0 100644 --- a/modules/boot.nix +++ b/modules/boot.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { # Bootloader boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; diff --git a/modules/default.nix b/modules/default.nix index 7431c84..c0fda17 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { imports = [ ./audio.nix ./bluetooth.nix @@ -16,7 +19,7 @@ ./steam.nix ./timezone.nix ./user.nix - ./man.nix + ./python.nix ]; # Enable CUPS to print documents. diff --git a/modules/docker.nix b/modules/docker.nix index 1427194..76407d8 100644 --- a/modules/docker.nix +++ b/modules/docker.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { virtualisation.docker = { enable = true; enableOnBoot = true; diff --git a/modules/env.nix b/modules/env.nix index 262e214..ef6077b 100644 --- a/modules/env.nix +++ b/modules/env.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { environment.shellInit = '' if [ -d $HOME/.cargo/bin ]; then export PATH=$PATH:$HOME/.cargo/bin @@ -11,7 +14,7 @@ EDITOR = "nvim"; VISUAL = "nvim"; TERM = "ghostty"; - GTK_THEME = "Adwaita:dark"; + GTK_THEME = lib.mkDefault "Adwaita:dark"; CC = "${pkgs.gcc}/bin/gcc"; PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" [ pkgs.openssl.dev diff --git a/modules/fonts.nix b/modules/fonts.nix index 5740871..2ce9a49 100644 --- a/modules/fonts.nix +++ b/modules/fonts.nix @@ -1,16 +1,32 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: let + clear-sans = pkgs.stdenv.mkDerivation { + name = "clear-sans"; + src = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/resir014/Clear-Sans-Webfont/97eec13/fonts/TTF/ClearSans-Regular.ttf"; + sha256 = "0vzhy3l056gj5vkcs1kglr4mr0546fq093v78i4ri8xni7w1m0dv"; + }; + dontUnpack = true; + installPhase = '' + mkdir -p $out/share/fonts/truetype + cp $src $out/share/fonts/truetype/ClearSans-Regular.ttf + ''; + }; +in { fonts = { packages = with pkgs; [ noto-fonts noto-fonts-cjk-sans noto-fonts-cjk-serif noto-fonts-emoji - (nerdfonts.override { fonts = [ "0xProto" "FiraCode" "JetBrainsMono" "Hack" "Noto" "NerdFontsSymbolsOnly" ]; }) + (nerdfonts.override {fonts = ["0xProto" "FiraCode" "JetBrainsMono" "Hack" "Noto" "NerdFontsSymbolsOnly"];}) ipafont kochi-substitute - # Custom BinaryClock font + clear-sans (stdenv.mkDerivation { name = "binary-clock-font"; src = fetchurl { @@ -27,10 +43,10 @@ fontconfig = { enable = true; defaultFonts = { - monospace = [ "JetBrains Mono" "Noto Sans Mono CJK JP" ]; - sansSerif = [ "Noto Sans" "Noto Sans CJK JP" ]; - serif = [ "Noto Serif" "Noto Serif CJK JP" ]; - emoji = [ "Noto Color Emoji" ]; + monospace = ["0xProto Nerd Font" "Noto Sans Mono CJK JP"]; + sansSerif = ["Clear Sans" "Noto Sans CJK JP"]; + serif = ["Noto Serif" "Noto Serif CJK JP"]; + emoji = ["Noto Color Emoji"]; }; }; }; diff --git a/modules/home-manager.nix b/modules/home-manager.nix index 49c119c..1e08aff 100644 --- a/modules/home-manager.nix +++ b/modules/home-manager.nix @@ -1,5 +1,10 @@ -{ config, pkgs, lib, inputs, ... }: { + config, + pkgs, + lib, + inputs, + ... +}: { imports = [ inputs.home-manager.nixosModules.home-manager ]; diff --git a/modules/i3-xfce.nix b/modules/i3-xfce.nix index b44033c..78450c9 100644 --- a/modules/i3-xfce.nix +++ b/modules/i3-xfce.nix @@ -1,8 +1,12 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: let + customPkgs = import ../pkgs {inherit pkgs lib;}; +in { services.xserver.enable = true; - services.xserver.xkb = { layout = "us"; variant = ""; @@ -24,8 +28,14 @@ i3-auto-layout ]; extraSessionCommands = '' - # Set random wallpaper - ${pkgs.feh}/bin/feh --randomize --bg-fill ~/wallpapers/* || ${pkgs.feh}/bin/feh --bg-fill ${pkgs.nixos-artwork.wallpapers.nineish-dark-gray}/share/backgrounds/nixos/nineish-dark-gray.png & + ${pkgs.feh}/bin/feh --randomize --bg-fill ~/wallpapers/* 2>/dev/null || ${pkgs.feh}/bin/feh --bg-fill ${pkgs.nixos-artwork.wallpapers.nineish-dark-gray}/share/backgrounds/nixos/nineish-dark-gray.png & + + export GSETTINGS_SCHEMA_DIR="${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}/glib-2.0/schemas" + export XDG_DATA_DIRS="${pkgs.gsettings-desktop-schemas}/share:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:${pkgs.tokyonight-gtk-theme}/share:${customPkgs.vivid-icons}/share:$XDG_DATA_DIRS" + + ${pkgs.glib}/bin/gsettings set org.gnome.desktop.interface gtk-theme "Tokyonight-Dark" || echo "Failed to set GTK theme" > /tmp/theme-debug.log + ${pkgs.glib}/bin/gsettings set org.gnome.desktop.interface icon-theme "Vivid-Icons-Dark" || ${pkgs.glib}/bin/gsettings set org.gnome.desktop.interface icon-theme "Papirus-Dark" || echo "Failed to set icon theme" > /tmp/theme-debug.log + ${pkgs.glib}/bin/gsettings set org.gnome.desktop.interface cursor-theme "capitaine-cursors" || echo "Failed to set cursor theme" > /tmp/theme-debug.log ''; }; @@ -34,52 +44,115 @@ noDesktop = true; enableXfwm = false; }; + services.xserver.displayManager.lightdm = { enable = true; - background = "#000000"; + background = "${pkgs.nixos-artwork.wallpapers.simple-dark-gray}/share/backgrounds/nixos/nixos-wallpaper.png"; greeters.gtk = { enable = true; - theme.name = "Adwaita-dark"; - iconTheme.name = "Papirus-Dark"; + theme = { + package = pkgs.tokyonight-gtk-theme; + name = "Tokyonight-Dark"; + }; + iconTheme = { + package = customPkgs.vivid-icons; + name = "Vivid-Icons-Dark"; + }; + cursorTheme = { + package = pkgs.capitaine-cursors; + name = "capitaine-cursors"; + }; + extraConfig = '' + [greeter] + font-name=Clear Sans 10 + cursor-theme-name=capitaine-cursors + ''; }; }; + services.displayManager.defaultSession = "xfce+i3"; services.displayManager.autoLogin = { enable = true; user = "cobray"; }; - environment.etc."xdg/autostart/i3-setup.desktop" = { - text = '' - [Desktop Entry] - Type=Application - Name=i3 Setup - Exec=${pkgs.bash}/bin/bash -c "${pkgs.feh}/bin/feh --randomize --bg-fill ~/wallpapers/* || ${pkgs.feh}/bin/feh --bg-fill ${pkgs.nixos-artwork.wallpapers.nineish-dark-gray}/share/backgrounds/nixos/nineish-dark-gray.png" - Terminal=false - X-GNOME-Autostart-enabled=true - ''; - mode = "0644"; + + qt = { + enable = true; + platformTheme = "gtk2"; }; - qt.enable = true; - qt.platformTheme = "gnome"; - qt.style = "adwaita-dark"; - environment.etc."gtk-3.0/settings.ini".text = '' - [Settings] - gtk-application-prefer-dark-theme=1 - gtk-theme-name=Adwaita-dark - gtk-icon-theme-name=Papirus-Dark - gtk-font-name=Sans 10 - ''; + environment.etc = { + "gtk-2.0/gtkrc".text = '' + gtk-theme-name="Tokyonight-Dark" + gtk-icon-theme-name="Vivid-Icons-Dark" + gtk-font-name="Clear Sans 10" + gtk-cursor-theme-name="capitaine-cursors" + gtk-cursor-theme-size=24 + ''; + "gtk-3.0/settings.ini".text = '' + [Settings] + gtk-application-prefer-dark-theme=1 + gtk-theme-name=Tokyonight-Dark + gtk-icon-theme-name=Vivid-Icons-Dark + gtk-font-name=Clear Sans 10 + gtk-cursor-theme-name=capitaine-cursors + gtk-cursor-theme-size=24 + ''; + "gtk-4.0/settings.ini".text = '' + [Settings] + gtk-application-prefer-dark-theme=1 + gtk-theme-name=Tokyonight-Dark + gtk-icon-theme-name=Vivid-Icons-Dark + gtk-font-name=Clear Sans 10 + gtk-cursor-theme-name=capitaine-cursors + gtk-cursor-theme-size=24 + ''; + }; + + environment.variables = { + GTK_THEME = "Tokyonight-Dark"; + ICON_THEME = "Vivid-Icons-Dark"; + XCURSOR_THEME = "capitaine-cursors"; + XCURSOR_SIZE = "24"; + }; environment.systemPackages = with pkgs; [ arandr nitrogen xclip lxappearance + gnome-themes-extra + gsettings-desktop-schemas + adwaita-qt arc-theme arc-icon-theme papirus-icon-theme numix-icon-theme-circle candy-icons - ]; + capitaine-cursors + tokyonight-gtk-theme + nix-prefetch-git + ] ++ (with customPkgs; [ + vivid-icons + ]); + + services.xserver.desktopManager.session = [{ + name = "xfce+i3"; + start = '' + export XDG_DATA_DIRS="${pkgs.tokyonight-gtk-theme}/share:${customPkgs.vivid-icons}/share:$XDG_DATA_DIRS" + ${pkgs.xfce.xfce4-session}/bin/xfce4-session --with-ck-launch & + ${pkgs.i3-gaps}/bin/i3 + ''; + }]; + + programs.dconf.enable = true; + programs.dconf.profiles.user.databases = [{ + settings = { + "org/gnome/desktop/interface" = { + icon-theme = "Vivid-Icons-Dark"; + gtk-theme = "Tokyonight-Dark"; + cursor-theme = "capitaine-cursors"; + }; + }; + }]; } diff --git a/modules/man.nix b/modules/man.nix deleted file mode 100644 index bc93b5c..0000000 --- a/modules/man.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ config, pkgs, lib, ... }: -{ - documentation = { - enable = true; - dev.enable = true; - doc.enable = true; - info.enable = true; - man = { - enable = true; - generateCaches = true; - }; - nixos.enable = true; - }; - - environment.pathsToLink = [ "/share/man" "/share/doc" ]; - - environment.systemPackages = with pkgs; [ - man-pages - man-pages-posix - stdmanpages - docutils - python311Packages.docutils - python311Packages.docstr-coverage - python310Packages.docutils - python310Packages.docstr-coverage - texlivePackages.documentation - docbook5 - docbook-xsl-ns - docbook-xsl-nons - doctoc - doctave - documentation-highlighter - ]; - - environment.variables = { - MANPATH = [ - "${config.system.path}/share/man" - "${pkgs.man-pages}/share/man" - "${pkgs.man-pages-posix}/share/man" - ]; - }; -} diff --git a/modules/net.nix b/modules/net.nix index 1f58b1e..bb2230f 100644 --- a/modules/net.nix +++ b/modules/net.nix @@ -1,7 +1,17 @@ -{ config, pkgs, lib, ... }: - { - networking.wireless.enable = false; # Enables wireless support via wpa_supplicant. + config, + pkgs, + lib, + ... +}: { + environment.systemPackages = with pkgs; [ + networkmanager_dmenu + ]; + + networking.firewall.allowedTCPPorts = [ 57621 ]; + networking.firewall.allowedUDPPorts = [ 5353 ]; + + networking.wireless.enable = false; # Enables wireless support via wpa_supplicant. networking.hostName = "nixos"; # Configure network proxy if necessary # networking.proxy.default = "http://user:password@proxy:port/"; diff --git a/modules/nixos.nix b/modules/nixos.nix index c3b53ee..b2bc73e 100644 --- a/modules/nixos.nix +++ b/modules/nixos.nix @@ -1,12 +1,15 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { nixpkgs.config.allowUnfree = true; programs.nix-index.enable = true; programs.command-not-found.enable = false; nix.settings = { auto-optimise-store = true; - experimental-features = [ "nix-command" "flakes" ]; + experimental-features = ["nix-command" "flakes"]; substituters = [ "https://cache.nixos.org" ]; diff --git a/modules/nvidia.nix b/modules/nvidia.nix index a28cab2..27234b6 100644 --- a/modules/nvidia.nix +++ b/modules/nvidia.nix @@ -1,11 +1,14 @@ -{ config, pkgs, lib, ... }: - { - services.xserver.videoDrivers = [ "nvidia" ]; + config, + pkgs, + lib, + ... +}: { + services.xserver.videoDrivers = ["nvidia"]; hardware.nvidia = { - modesetting.enable = true; - powerManagement.enable = true; + modesetting.enable = false; + powerManagement.enable = false; # Set to true for RTX 4000 series and newer GPUs open = true; package = config.boot.kernelPackages.nvidiaPackages.stable; @@ -13,6 +16,7 @@ }; environment.systemPackages = with pkgs; [ - #cudaPackages.cudatoolkit + cudaPackages.cudatoolkit + glxinfo ]; } diff --git a/modules/python.nix b/modules/python.nix new file mode 100644 index 0000000..d34d709 --- /dev/null +++ b/modules/python.nix @@ -0,0 +1,49 @@ +{ config, pkgs, lib, ... }: + +let + customPkgs = pkgs.callPackage ../pkgs { inherit pkgs lib; }; +in { + options.python = { + enable = lib.mkEnableOption "System Python Environment"; + }; + config = lib.mkIf config.python.enable { + environment.systemPackages = with pkgs; [ + (python311.withPackages (pyPkgs: with pyPkgs; [ + numpy + python-pymatting + python-opencv-headless + python-rembg + i3ipc + pandas + matplotlib + scipy + requests + pip + virtualenv + ipython + six + psutil + pynvml + pyqtgraph + pyqt6 + click + typer + rich + pyyaml + pytz + pillow + ])) + python3Packages.pip + black + ruff + uv + ]; + environment.variables = { + PIP_PREFIX = "$HOME/.local"; + PYTHONPATH = "$HOME/.local/lib/python3.11/site-packages"; + }; + environment.shellAliases = { + python = "python3.11"; + }; + }; +} diff --git a/modules/steam.nix b/modules/steam.nix index be187ed..89d21b5 100644 --- a/modules/steam.nix +++ b/modules/steam.nix @@ -1,6 +1,11 @@ -{ config, pkgs, lib, inputs, system, ... }: - { + config, + pkgs, + lib, + inputs, + system, + ... +}: { programs.steam = { enable = true; remotePlay.openFirewall = true; diff --git a/modules/timezone.nix b/modules/timezone.nix index 23bf6b9..cb9f39e 100644 --- a/modules/timezone.nix +++ b/modules/timezone.nix @@ -1,6 +1,9 @@ -{ config, pkgs, lib, ... }: - { + config, + pkgs, + lib, + ... +}: { time.timeZone = "America/Edmonton"; i18n.defaultLocale = "en_CA.UTF-8"; } diff --git a/modules/user.nix b/modules/user.nix index 0638ed9..66928eb 100644 --- a/modules/user.nix +++ b/modules/user.nix @@ -1,15 +1,16 @@ -{ config, pkgs, lib, ... }: - -let - fish-rust = pkgs.callPackage ../pkgs/fish-rust { }; -in - { + config, + pkgs, + lib, + ... +}: let + fish-rust = pkgs.callPackage ../pkgs/fish-rust {}; +in { # Define a user account. Don't forget to set a password with 'passwd'. users.users.cobray = { isNormalUser = true; description = "Mon Aie"; - extraGroups = [ "networkmanager" "wheel" "docker" "video" ]; + extraGroups = ["networkmanager" "wheel" "docker" "video"]; shell = fish-rust; packages = with pkgs; [ # User-specific packages can be defined here diff --git a/pkgs/default.nix b/pkgs/default.nix index 4836427..aed9492 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -1,17 +1,44 @@ -{ pkgs ? import {}, lib ? pkgs.lib }: - -let - python-pymatting = pkgs.callPackage ./python-pymatting { - inherit (pkgs) lib fetchPypi; - python310Packages = pkgs.python310.pkgs; - }; -in { + pkgs ? import {}, + lib ? pkgs.lib, +}: { fish-rust = pkgs.callPackage ./fish-rust {}; - python-pymatting = python-pymatting; + python-pymatting = pkgs.callPackage ./python-pymatting { + inherit lib; + fetchPypi = pkgs.fetchPypi; + python311Packages = pkgs.python311Packages; + }; + python-opencv-headless = pkgs.callPackage ./python-opencv-headless { + inherit lib; + fetchPypi = pkgs.fetchPypi; + cmake = pkgs.cmake; + pkg-config = pkgs.pkg-config; + stdenv = pkgs.stdenv; + makeWrapper = pkgs.makeWrapper; + python311Packages = pkgs.python311Packages; + }; python-rembg = pkgs.callPackage ./python-rembg { - inherit (pkgs) lib fetchPypi; - python310Packages = pkgs.python310.pkgs; - inherit python-pymatting; + inherit lib; + fetchPypi = pkgs.fetchPypi; + python-pymatting = pkgs.callPackage ./python-pymatting { + inherit lib; + fetchPypi = pkgs.fetchPypi; + python311Packages = pkgs.python311Packages; + }; + python-opencv-headless = pkgs.callPackage ./python-opencv-headless { + inherit lib; + fetchPypi = pkgs.fetchPypi; + cmake = pkgs.cmake; + pkg-config = pkgs.pkg-config; + stdenv = pkgs.stdenv; + makeWrapper = pkgs.makeWrapper; + python311Packages = pkgs.python311Packages; + }; + python311Packages = pkgs.python311Packages; + }; + vivid-icons = pkgs.callPackage ./vivid-icons { + inherit lib; + stdenv = pkgs.stdenv; + fetchFromGitHub = pkgs.fetchFromGitHub; }; } diff --git a/pkgs/fish-rust/default.nix b/pkgs/fish-rust/default.nix index 0b4ecd2..0f09311 100644 --- a/pkgs/fish-rust/default.nix +++ b/pkgs/fish-rust/default.nix @@ -1,8 +1,14 @@ -{ lib, rustPlatform, fetchgit, ncurses, python3Packages, gettext }: - +{ + lib, + rustPlatform, + fetchgit, + ncurses, + python3Packages, + gettext, +}: rustPlatform.buildRustPackage rec { pname = "fish"; - version = "4.1-2025-03-16-rust"; + version = "4.1-2025-03-16-rust-${builtins.substring 0 7 "642ec399ca17bbde973dc20461335396fe922e4c"}"; src = fetchgit { url = "https://github.com/fish-shell/fish-shell.git"; @@ -19,12 +25,8 @@ rustPlatform.buildRustPackage rec { }; }; - buildInputs = [ ncurses gettext ]; - nativeBuildInputs = with python3Packages; [ - sphinx - sphinx_rtd_theme - gettext - ]; + buildInputs = [ncurses gettext]; + nativeBuildInputs = with python3Packages; [sphinx sphinx_rtd_theme]; preBuild = '' export FISH_BUILD_VERSION="${version}" @@ -32,23 +34,11 @@ rustPlatform.buildRustPackage rec { ''; postInstall = '' - export HOME=$(mktemp -d) - mkdir -p $HOME/.local/share/fish/install - - if [ ! -f $HOME/.config/fish/config.fish ]; then - $out/bin/fish --install - fi - - mkdir -p $out/share/fish - cp -r $HOME/.local/share/fish/install/* $out/share/fish/ 2>/dev/null || true - mkdir -p $out/share/fish/tools cp $src/share/tools/create_manpage_completions.py $out/share/fish/tools/ cp $src/share/tools/deroff.py $out/share/fish/tools/ chmod +x $out/share/fish/tools/create_manpage_completions.py chmod +x $out/share/fish/tools/deroff.py - - rm -rf $HOME ''; doCheck = false; @@ -59,6 +49,7 @@ rustPlatform.buildRustPackage rec { license = licenses.gpl2; platforms = platforms.unix; mainProgram = "fish"; + maintainers = ["Cobray"]; }; passthru.shellPath = "/bin/fish"; diff --git a/pkgs/python-opencv-headless/default.nix b/pkgs/python-opencv-headless/default.nix new file mode 100644 index 0000000..3bc9fdf --- /dev/null +++ b/pkgs/python-opencv-headless/default.nix @@ -0,0 +1,55 @@ +{ lib +, python311Packages +, fetchPypi +, stdenv +, makeWrapper +, cmake +, pkg-config +}: + +python311Packages.buildPythonPackage rec { + pname = "opencv-python-headless"; + version = "4.11.0.86"; + format = "setuptools"; + + src = fetchPypi { + pname = "opencv-python-headless"; + inherit version; + format = "setuptools"; + sha256 = "mW6ygspLQ+xqOXJBTeDiMx9dnNorQQkaSXOcGfuEN5g="; + }; + + nativeBuildInputs = with python311Packages; [ + cmake + pkg-config + makeWrapper + scikit-build + ]; + + buildInputs = with python311Packages; [ + scikit-build + ]; + + propagatedBuildInputs = with python311Packages; [ + numpy + setuptools + ]; + + dontUseCmakeConfigure = true; + + doCheck = false; + + pythonImportsCheck = [ "cv2" ]; + + postFixup = '' + wrapPythonProgramsIn "$out/lib/python3.11/site-packages" "${stdenv.cc.cc.lib}" + ''; + + meta = with lib; { + description = "Wrapper package for OpenCV python bindings (headless)"; + homepage = "https://github.com/opencv/opencv-python"; + license = licenses.mit; + platforms = platforms.linux; + maintainers = with maintainers; [ "Cobray" ]; + }; +} diff --git a/pkgs/python-pymatting/default.nix b/pkgs/python-pymatting/default.nix index 32f88af..14f282d 100644 --- a/pkgs/python-pymatting/default.nix +++ b/pkgs/python-pymatting/default.nix @@ -1,22 +1,33 @@ -{ lib, python310Packages, fetchPypi }: - -python310Packages.buildPythonPackage rec { +{ + lib, + python311Packages, + fetchPypi, +}: +python311Packages.buildPythonPackage rec { pname = "pymatting"; version = "1.1.13"; - format = "setuptools"; + format = "pyproject"; src = fetchPypi { inherit pname version; - sha256 = "sha256-LNt8S++s3e9Netwt6ONKJy3mOdYIrlwKCGE9+kJTgQE="; # Updated hash + hash = "sha256-LNt8S++s3e9Netwt6ONKJy3mOdYIrlwKCGE9+kJTgQE="; }; - propagatedBuildInputs = with python310Packages; [ + nativeBuildInputs = with python311Packages; [ + setuptools + poetry-core + ]; + + propagatedBuildInputs = with python311Packages; [ numpy scipy pillow numba ]; + buildInputs = [ + ]; + doCheck = false; meta = with lib; { @@ -24,5 +35,6 @@ python310Packages.buildPythonPackage rec { homepage = "https://github.com/pymatting/pymatting"; license = licenses.mit; platforms = platforms.all; + maintainers = with maintainers; [ "Cobray" ]; }; } diff --git a/pkgs/python-rembg/default.nix b/pkgs/python-rembg/default.nix index d2c009b..2a51257 100644 --- a/pkgs/python-rembg/default.nix +++ b/pkgs/python-rembg/default.nix @@ -1,40 +1,39 @@ -{ lib, python310Packages, fetchPypi, python-pymatting }: - -python310Packages.buildPythonPackage rec { +{ lib +, python311Packages +, fetchPypi +, python-pymatting +, python-opencv-headless +}: +python311Packages.buildPythonPackage rec { pname = "rembg"; version = "2.0.50"; - format = "setuptools"; - + format = "pyproject"; src = fetchPypi { inherit pname version; - sha256 = "0dgq291bj4w6jkcyz7lvp1vba2nczfnmxa2acl2sqib5p8cpzjvc"; + sha256 = "bMt/GbplRawFZUqoXq37zAq1dribnu/ZlIYTuUIS+DU="; }; - - nativeBuildInputs = with python310Packages; [ - setuptools + nativeBuildInputs = with python311Packages; [ poetry-core + setuptools ]; - - propagatedBuildInputs = with python310Packages; [ + propagatedBuildInputs = with python311Packages; [ numpy - pillow onnxruntime - opencv4 - requests - aiohttp - asynctest - click - filetype + pillow pooch - pympler - python-pymatting scikit-image scipy tqdm + aiohttp + pytorch-bin + ] ++ [ + python-opencv-headless + python-pymatting ]; - + pythonRemoveDeps = [ "opencv-python-headless" ]; + dontPrecompilePages = true; + doInstallCheck = false; doCheck = false; - meta = with lib; { description = "Tool to remove image backgrounds"; homepage = "https://github.com/danielgatis/rembg"; diff --git a/pkgs/template.nix b/pkgs/template.nix new file mode 100644 index 0000000..4450b79 --- /dev/null +++ b/pkgs/template.nix @@ -0,0 +1,1350 @@ +{ + buildPackages, + gixy, + lib, + libiconv, + makeBinaryWrapper, + mkNugetDeps, + mkNugetSource, + pkgs, + stdenv, +}: +let + inherit (lib) + concatMapStringsSep + elem + escapeShellArg + last + optionalString + strings + types + ; +in +rec { + /** + `makeScriptWriter` returns a derivation which creates an executable script. + + # Inputs + + config (AttrSet) + : `interpreter` (String) + : the [interpreter](https://en.wikipedia.org/wiki/Shebang_(Unix)) to use for the script. + : `check` (String) + : A command to check the script. For example, this could be a linting check. + : `makeWrapperArgs` (Optional, [ String ], Default: []) + : Arguments forwarded to (`makeWrapper`)[#fun-makeWrapper]. + + `nameOrPath` (String) + : The name of the script or the path to the script. + + When a `string` starting with "/" is passed, the script will be created at the specified path in $out. + I.e. `"/bin/hello"` will create a script at `$out/bin/hello`. + + Any other `string` is interpreted as a filename. + It must be a [POSIX filename](https://en.wikipedia.org/wiki/Filename) starting with a letter, digit, dot, or underscore. + Spaces or special characters are not allowed. + + `content` (String) + : The content of the script. + + :::{.note} + This function is used as base implementation for other high-level writer functions. + + For example, `writeBash` can (roughly) be implemented as: + + ```nix + writeBash = makeScriptWriter { interpreter = "${pkgs.bash}/bin/bash"; } + ``` + ::: + + # Examples + :::{.example} + ## `pkgs.writers.makeScriptWriter` dash example + + ```nix-repl + :b makeScriptWriter { interpreter = "${pkgs.dash}/bin/dash"; } "hello" "echo hello world" + -> /nix/store/indvlr9ckmnv4f0ynkmasv2h4fxhand0-hello + ``` + + The above example creates a script named `hello` that outputs `hello world` when executed. + + ```sh + > /nix/store/indvlr9ckmnv4f0ynkmasv2h4fxhand0-hello + hello world + ``` + ::: + + :::{.example} + ## `pkgs.writers.makeScriptWriter` python example + + ```nix-repl + :b makeScriptWriter { interpreter = "${pkgs.python3}/bin/python"; } "python-hello" "print('hello world')" + -> /nix/store/4kvby1hqr45ffcdrvfpnpj62hanskw93-python-hello + ``` + + ```sh + > /nix/store/4kvby1hqr45ffcdrvfpnpj62hanskw93-python-hello + hello world + ``` + ::: + */ + makeScriptWriter = + { + interpreter, + check ? "", + makeWrapperArgs ? [ ], + }: + nameOrPath: content: + assert + (types.path.check nameOrPath) + || (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null); + assert (types.path.check content) || (types.str.check content); + let + nameIsPath = types.path.check nameOrPath; + name = last (builtins.split "/" nameOrPath); + path = if nameIsPath then nameOrPath else "/bin/${name}"; + # The inner derivation which creates the executable under $out/bin (never at $out directly) + # This is required in order to support wrapping, as wrapped programs consist of + # at least two files: the executable and the wrapper. + inner = + pkgs.runCommandLocal name + ( + { + inherit makeWrapperArgs; + nativeBuildInputs = [ makeBinaryWrapper ]; + meta.mainProgram = name; + } + // ( + if (types.str.check content) then + { + inherit content interpreter; + passAsFile = [ "content" ]; + } + else + { + inherit interpreter; + contentPath = content; + } + ) + ) + '' + # On darwin a script cannot be used as an interpreter in a shebang but + # there doesn't seem to be a limit to the size of shebang and multiple + # arguments to the interpreter are allowed. + if [[ -n "${toString pkgs.stdenvNoCC.hostPlatform.isDarwin}" ]] && isScript $interpreter + then + wrapperInterpreterLine=$(head -1 "$interpreter" | tail -c+3) + # Get first word from the line (note: xargs echo remove leading spaces) + wrapperInterpreter=$(echo "$wrapperInterpreterLine" | xargs echo | cut -d " " -f1) + + if isScript $wrapperInterpreter + then + echo "error: passed interpreter ($interpreter) is a script which has another script ($wrapperInterpreter) as an interpreter, which is not supported." + exit 1 + fi + + # This should work as long as wrapperInterpreter is a shell, which is + # the case for programs wrapped with makeWrapper, like + # python3.withPackages etc. + interpreterLine="$wrapperInterpreterLine $interpreter" + else + interpreterLine=$interpreter + fi + + echo "#! $interpreterLine" > $out + cat "$contentPath" >> $out + ${optionalString (check != "") '' + ${check} $out + ''} + chmod +x $out + + # Relocate executable + # Wrap it if makeWrapperArgs are specified + mv $out tmp + mkdir -p $out/$(dirname "${path}") + mv tmp $out/${path} + if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then + wrapProgram $out/${path} ''${makeWrapperArgs[@]} + fi + ''; + in + if nameIsPath then + inner + # In case nameOrPath is a name, the user intends the executable to be located at $out. + # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}. + # This breaks the override pattern. + # In case this turns out to be a problem, we can still add more magic + else + pkgs.runCommandLocal name { } '' + ln -s ${inner}/bin/${name} $out + ''; + + /** + `makeBinWriter` returns a derivation which compiles the given script into an executable format. + + :::{.note} + This function is the base implementation for other compile language `writers`, such as `writeHaskell` and `writeRust`. + ::: + + # Inputs + + config (AttrSet) + : `compileScript` (String) + : The script that compiles the given content into an executable. + + : `strip` (Boolean, Default: true) + : Whether to [strip](https://nixos.org/manual/nixpkgs/stable/#ssec-fixup-phase) the executable or not. + + : `makeWrapperArgs` (Optional, [ String ], Default: []) + : Arguments forwarded to (`makeWrapper`)[#fun-makeWrapper] + + `nameOrPath` (String) + : The name of the script or the path to the script. + + When a `string` starting with "/" is passed, the script will be created at the specified path in $out. + For example, `"/bin/hello"` will create a script at `$out/bin/hello`. + + Any other `string` is interpreted as a filename. + It must be a [POSIX filename](https://en.wikipedia.org/wiki/Filename) starting with a letter, digit, dot, or underscore. + Spaces or special characters are not allowed. + + # Examples + :::{.example} + ## `pkgs.writers.makeBinWriter` example + + ```c + // main.c + #include + + int main() + { + printf("Hello, World!\n"); + return 0; + } + ``` + + ```nix-repl + :b makeBinWriter { compileScript = "${pkgs.gcc}/bin/gcc -o $out $contentPath"; } "hello" ./main.c + out -> /nix/store/f6crc8mwj3lvcxqclw7n09cm8nb6kxbh-hello + ``` + + The above example creates an executable named `hello` that outputs `Hello, World!` when executed. + + ```sh + > /nix/store/f6crc8mwj3lvcxqclw7n09cm8nb6kxbh-hello + Hello, World! + ``` + ::: + */ + makeBinWriter = + { + compileScript, + strip ? true, + makeWrapperArgs ? [ ], + }: + nameOrPath: content: + assert + (types.path.check nameOrPath) + || (builtins.match "([0-9A-Za-z._])[0-9A-Za-z._-]*" nameOrPath != null); + assert (types.path.check content) || (types.str.check content); + let + nameIsPath = types.path.check nameOrPath; + name = last (builtins.split "/" nameOrPath); + path = if nameIsPath then nameOrPath else "/bin/${name}"; + # The inner derivation which creates the executable under $out/bin (never at $out directly) + # This is required in order to support wrapping, as wrapped programs consist of at least two files: the executable and the wrapper. + inner = + pkgs.runCommandLocal name + ( + { + inherit makeWrapperArgs; + nativeBuildInputs = [ makeBinaryWrapper ]; + meta.mainProgram = name; + } + // ( + if (types.str.check content) then + { + inherit content; + passAsFile = [ "content" ]; + } + else + { contentPath = content; } + ) + ) + '' + ${compileScript} + ${lib.optionalString strip "${lib.getBin buildPackages.bintools-unwrapped}/bin/${buildPackages.bintools-unwrapped.targetPrefix}strip -S $out"} + # Sometimes binaries produced for darwin (e. g. by GHC) won't be valid + # mach-o executables from the get-go, but need to be corrected somehow + # which is done by fixupPhase. + ${lib.optionalString pkgs.stdenvNoCC.hostPlatform.isDarwin "fixupPhase"} + mv $out tmp + mkdir -p $out/$(dirname "${path}") + mv tmp $out/${path} + if [ -n "''${makeWrapperArgs+''${makeWrapperArgs[@]}}" ]; then + wrapProgram $out/${path} ''${makeWrapperArgs[@]} + fi + ''; + in + if nameIsPath then + inner + # In case nameOrPath is a name, the user intends the executable to be located at $out. + # This is achieved by creating a separate derivation containing a symlink at $out linking to ${inner}/bin/${name}. + # This breaks the override pattern. + # In case this turns out to be a problem, we can still add more magic + else + pkgs.runCommandLocal name { } '' + ln -s ${inner}/bin/${name} $out + ''; + + /** + Like writeScript but the first line is a shebang to bash + Can be called with or without extra arguments. + + # Examples + :::{.example} + + ## Without arguments + + ```nix + writeBash "example" '' + echo hello world + '' + ``` + + ## With arguments + + ```nix + writeBash "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeBash = + name: argsOrScript: + if lib.isAttrs argsOrScript && !lib.isDerivation argsOrScript then + makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.bash}"; }) name + else + makeScriptWriter { interpreter = "${lib.getExe pkgs.bash}"; } name argsOrScript; + + /** + Like writeScriptBin but the first line is a shebang to bash + + Can be called with or without extra arguments. + + ## Examples + :::{.example} + ## `pkgs.writers.writeBashBin` example without arguments + + ```nix + writeBashBin "example" '' + echo hello world + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeBashBin` example with arguments + + ```nix + writeBashBin "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeBashBin = name: writeBash "/bin/${name}"; + + /** + Like writeScript but the first line is a shebang to dash + + Can be called with or without extra arguments. + + # Example + :::{.example} + ## `pkgs.writers.writeDash` example without arguments + + ```nix + writeDash "example" '' + echo hello world + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeDash` example with arguments + + ```nix + writeDash "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeDash = + name: argsOrScript: + if lib.isAttrs argsOrScript && !lib.isDerivation argsOrScript then + makeScriptWriter (argsOrScript // { interpreter = "${lib.getExe pkgs.dash}"; }) name + else + makeScriptWriter { interpreter = "${lib.getExe pkgs.dash}"; } name argsOrScript; + + /** + Like writeScriptBin but the first line is a shebang to dash + + Can be called with or without extra arguments. + + # Examples + :::{.example} + ## `pkgs.writers.writeDashBin` without arguments + + ```nix + writeDashBin "example" '' + echo hello world + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeDashBin` with arguments + + ```nix + writeDashBin "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeDashBin = name: writeDash "/bin/${name}"; + + /** + Like writeScript but the first line is a shebang to fish + + Can be called with or without extra arguments. + + :::{.example} + ## `pkgs.writers.writeFish` without arguments + + ```nix + writeFish "example" '' + echo hello world + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeFish` with arguments + + ```nix + writeFish "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeFish = + name: argsOrScript: + if lib.isAttrs argsOrScript && !lib.isDerivation argsOrScript then + makeScriptWriter ( + argsOrScript + // { + interpreter = "${lib.getExe pkgs.fish} --no-config"; + check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only + } + ) name + else + makeScriptWriter { + interpreter = "${lib.getExe pkgs.fish} --no-config"; + check = "${lib.getExe pkgs.fish} --no-config --no-execute"; # syntax check only + } name argsOrScript; + + /** + Like writeScriptBin but the first line is a shebang to fish + + Can be called with or without extra arguments. + + # Examples + :::{.example} + ## `pkgs.writers.writeFishBin` without arguments + + ```nix + writeFishBin "example" '' + echo hello world + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeFishBin` with arguments + + ```nix + writeFishBin "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeFishBin = name: writeFish "/bin/${name}"; + + /** + writeBabashka takes a name, an attrset with babashka interpreter and linting check (both optional) + and some babashka source code and returns an executable. + + `pkgs.babashka-unwrapped` is used as default interpreter for small closure size. If dependencies needed, use `pkgs.babashka` instead. Pass empty string to check to disable the default clj-kondo linting. + + # Examples + :::{.example} + ## `pkgs.writers.writeBabashka` with empty arguments + + ```nix + writeBabashka "example" { } '' + (println "hello world") + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeBabashka` with arguments + + ```nix + writeBabashka "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + (require '[babashka.tasks :as tasks]) + (tasks/shell "hello" "-g" "Hello babashka!") + '' + ``` + ::: + + :::{.note} + Babashka needs Java for fetching dependencies. Wrapped babashka contains jdk, + pass wrapped version `pkgs.babashka` to babashka if dependencies are required. + + For example: + + ```nix + writeBabashka "example" + { + babashka = pkgs.babashka; + } + '' + (require '[babashka.deps :as deps]) + (deps/add-deps '{:deps {medley/medley {:mvn/version "1.3.0"}}}) + (require '[medley.core :as m]) + (prn (m/index-by :id [{:id 1} {:id 2}])) + '' + ``` + ::: + + :::{.note} + Disable clj-kondo linting: + + ```nix + writeBabashka "example" + { + check = ""; + } + '' + (println "hello world") + '' + ``` + ::: + */ + writeBabashka = + name: + { + makeWrapperArgs ? [ ], + babashka ? pkgs.babashka-unwrapped, + check ? "${lib.getExe pkgs.clj-kondo} --lint", + ... + }@args: + makeScriptWriter ( + (builtins.removeAttrs args [ + "babashka" + ]) + // { + interpreter = "${lib.getExe babashka}"; + } + ) name; + + /** + writeBabashkaBin takes the same arguments as writeBabashka but outputs a directory + (like writeScriptBin) + */ + writeBabashkaBin = name: writeBabashka "/bin/${name}"; + + /** + `writeGuile` returns a derivation that creates an executable Guile script. + + # Inputs + + `nameOrPath` (String) + : Name of or path to the script. The semantics is the same as that of + `makeScriptWriter`. + + `config` (AttrSet) + : `guile` (Optional, Derivation, Default: `pkgs.guile`) + : Guile package used for the script. + : `libraries` (Optional, [ Derivation ], Default: []) + : Extra Guile libraries exposed to the script. + : `r6rs` and `r7rs` (Optional, Boolean, Default: false) + : Whether to adapt Guile’s initial environment to better support R6RS/ + R7RS. See the [Guile Reference Manual](https://www.gnu.org/software/guile/manual/html_node/index.html) + for details. + : `srfi` (Optional, [ Int ], Default: []) + : SRFI module to be loaded into the interpreter before evaluating a + script file or starting the REPL. See the Guile Reference Manual to + know which SRFI are supported. + : Other attributes are directly passed to `makeScriptWriter`. + + `content` (String) + : Content of the script. + + # Examples + + :::{.example} + ## `pkgs.writers.writeGuile` with default config + + ```nix + writeGuile "guile-script" { } + '' + (display "Hello, world!") + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeGuile` with SRFI-1 enabled and extra libraries + + ```nix + writeGuile "guile-script" { + libraries = [ pkgs.guile-semver ]; + srfi = [ 1 ]; + } + '' + (use-modules (semver)) + (make-semver 1 (third '(2 3 4)) 5) ; => # + '' + ``` + ::: + */ + writeGuile = + nameOrPath: + { + guile ? pkgs.guile, + libraries ? [ ], + r6rs ? false, + r7rs ? false, + srfi ? [ ], + ... + }@config: + content: + assert builtins.all builtins.isInt srfi; + let + finalGuile = pkgs.buildEnv { + name = "guile-env"; + paths = [ guile ] ++ libraries; + passthru = { + inherit (guile) siteDir siteCcacheDir; + }; + meta.mainProgram = guile.meta.mainProgram or "guile"; + }; + in + makeScriptWriter + ( + (builtins.removeAttrs config [ + "guile" + "libraries" + "r6rs" + "r7rs" + "srfi" + ]) + // { + interpreter = "${lib.getExe finalGuile} \\"; + makeWrapperArgs = [ + "--set" + "GUILE_LOAD_PATH" + "${finalGuile}/${finalGuile.siteDir}:${finalGuile}/lib/scheme-libs" + "--set" + "GUILE_LOAD_COMPILED_PATH" + "${finalGuile}/${finalGuile.siteCcacheDir}:${finalGuile}/lib/libobj" + "--set" + "LD_LIBRARY_PATH" + "${finalGuile}/lib/ffi" + "--set" + "DYLD_LIBRARY_PATH" + "${finalGuile}/lib/ffi" + ]; + } + ) + nameOrPath + /* + Spaces, newlines and tabs are significant for the "meta switch" of Guile, so + certain complication must be made to ensure correctness. + */ + ( + lib.concatStringsSep "\n" [ + (lib.concatStringsSep " " ( + [ "--no-auto-compile" ] + ++ lib.optional r6rs "--r6rs" + ++ lib.optional r7rs "--r7rs" + ++ lib.optional (srfi != [ ]) ("--use-srfi=" + concatMapStringsSep "," builtins.toString srfi) + ++ [ "-s" ] + )) + "!#" + content + ] + ); + + /** + writeGuileBin takes the same arguments as writeGuile but outputs a directory + (like writeScriptBin) + */ + writeGuileBin = name: writeGuile "/bin/${name}"; + + /** + writeHaskell takes a name, an attrset with libraries and haskell version (both optional) + and some haskell source code and returns an executable. + + # Examples + :::{.example} + ## `pkgs.writers.writeHaskell` usage example + + ```nix + writeHaskell "missiles" { libraries = [ pkgs.haskellPackages.acme-missiles ]; } '' + import Acme.Missiles + + main = launchMissiles + ''; + ``` + ::: + */ + writeHaskell = + name: + { + ghc ? pkgs.ghc, + ghcArgs ? [ ], + libraries ? [ ], + makeWrapperArgs ? [ ], + strip ? true, + threadedRuntime ? true, + }: + let + appendIfNotSet = el: list: if elem el list then list else list ++ [ el ]; + ghcArgs' = if threadedRuntime then appendIfNotSet "-threaded" ghcArgs else ghcArgs; + + in + makeBinWriter { + compileScript = '' + cp $contentPath tmp.hs + ${(ghc.withPackages (_: libraries))}/bin/ghc ${lib.escapeShellArgs ghcArgs'} tmp.hs + mv tmp $out + ''; + inherit makeWrapperArgs strip; + } name; + + /** + writeHaskellBin takes the same arguments as writeHaskell but outputs a directory (like writeScriptBin) + */ + writeHaskellBin = name: writeHaskell "/bin/${name}"; + + /** + writeNim takes a name, an attrset with an optional Nim compiler, and some + Nim source code, returning an executable. + + # Examples + :::{.example} + ## `pkgs.writers.writeNim` usage example + + ```nix + writeNim "hello-nim" { nim = pkgs.nim2; } '' + echo "hello nim" + ''; + ``` + ::: + */ + writeNim = + name: + { + makeWrapperArgs ? [ ], + nim ? pkgs.nim2, + nimCompileOptions ? { }, + strip ? true, + }: + let + nimCompileCmdArgs = lib.cli.toGNUCommandLineShell { optionValueSeparator = ":"; } ( + { + d = "release"; + nimcache = "."; + } + // nimCompileOptions + ); + in + makeBinWriter { + compileScript = '' + cp $contentPath tmp.nim + ${lib.getExe nim} compile ${nimCompileCmdArgs} tmp.nim + mv tmp $out + ''; + inherit makeWrapperArgs strip; + } name; + + /** + writeNimBin takes the same arguments as writeNim but outputs a directory + (like writeScriptBin) + */ + writeNimBin = name: writeNim "/bin/${name}"; + + /** + Like writeScript but the first line is a shebang to nu + + Can be called with or without extra arguments. + + # Examples + :::{.example} + ## `pkgs.writers.writeNu` without arguments + + ```nix + writeNu "example" '' + echo hello world + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeNu` with arguments + + ```nix + writeNu "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeNu = + name: argsOrScript: + if lib.isAttrs argsOrScript && !lib.isDerivation argsOrScript then + makeScriptWriter ( + argsOrScript // { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; } + ) name + else + makeScriptWriter { interpreter = "${lib.getExe pkgs.nushell} --no-config-file"; } name argsOrScript; + + /** + Like writeScriptBin but the first line is a shebang to nu + + Can be called with or without extra arguments. + + # Examples + :::{.example} + ## `pkgs.writers.writeNuBin` without arguments + + ```nix + writeNuBin "example" '' + echo hello world + '' + ``` + ::: + + :::{.example} + ## `pkgs.writers.writeNuBin` with arguments + + ```nix + writeNuBin "example" + { + makeWrapperArgs = [ + "--prefix" "PATH" ":" "${lib.makeBinPath [ pkgs.hello ]}" + ]; + } + '' + hello + '' + ``` + ::: + */ + writeNuBin = name: writeNu "/bin/${name}"; + + /** + makeRubyWriter takes ruby and compatible rubyPackages and produces ruby script writer, + If any libraries are specified, ruby.withPackages is used as interpreter, otherwise the "bare" ruby is used. + */ + makeRubyWriter = + ruby: rubyPackages: buildRubyPackages: name: + { + libraries ? [ ], + ... + }@args: + makeScriptWriter ( + (builtins.removeAttrs args [ "libraries" ]) + // { + interpreter = + if libraries == [ ] then "${ruby}/bin/ruby" else "${(ruby.withPackages (ps: libraries))}/bin/ruby"; + # Rubocop doesn't seem to like running in this fashion. + #check = (writeDash "rubocop.sh" '' + # exec ${lib.getExe buildRubyPackages.rubocop} "$1" + #''); + } + ) name; + + /** + Like writeScript but the first line is a shebang to ruby + + # Examples + :::{.example} + ## `pkgs.writers.writeRuby` usage example + + ```nix + writeRuby "example" { libraries = [ pkgs.rubyPackages.git ]; } '' + puts "hello world" + '' + ``` + + ::: + */ + writeRuby = makeRubyWriter pkgs.ruby pkgs.rubyPackages buildPackages.rubyPackages; + + writeRubyBin = name: writeRuby "/bin/${name}"; + + /** + makeLuaWriter takes lua and compatible luaPackages and produces lua script writer, + which validates the script with luacheck at build time. If any libraries are specified, + lua.withPackages is used as interpreter, otherwise the "bare" lua is used. + */ + makeLuaWriter = + lua: luaPackages: buildLuaPackages: name: + { + libraries ? [ ], + ... + }@args: + makeScriptWriter ( + (builtins.removeAttrs args [ "libraries" ]) + // { + interpreter = lua.interpreter; + # if libraries == [] + # then lua.interpreter + # else (lua.withPackages (ps: libraries)).interpreter + # This should support packages! I just cant figure out why some dependency collision happens whenever I try to run this. + check = ( + writeDash "luacheck.sh" '' + exec ${buildLuaPackages.luacheck}/bin/luacheck "$1" + '' + ); + } + ) name; + + /** + writeLua takes a name an attributeset with libraries and some lua source code and + returns an executable (should also work with luajit) + + # Examples + :::{.example} + ## `pkgs.writers.writeLua` usage example + + ```nix + writeLua "test_lua" { libraries = [ pkgs.luaPackages.say ]; } '' + s = require("say") + s:set_namespace("en") + + s:set('money', 'I have %s dollars') + s:set('wow', 'So much money!') + + print(s('money', {1000})) -- I have 1000 dollars + + s:set_namespace("fr") -- switch to french! + s:set('wow', "Tant d'argent!") + + print(s('wow')) -- Tant d'argent! + s:set_namespace("en") -- switch back to english! + print(s('wow')) -- So much money! + '' + ``` + + ::: + */ + writeLua = makeLuaWriter pkgs.lua pkgs.luaPackages buildPackages.luaPackages; + + writeLuaBin = name: writeLua "/bin/${name}"; + + writeRust = + name: + { + makeWrapperArgs ? [ ], + rustc ? pkgs.rustc, + rustcArgs ? [ ], + strip ? true, + }: + let + darwinArgs = lib.optionals stdenv.hostPlatform.isDarwin [ "-L${lib.getLib libiconv}/lib" ]; + in + makeBinWriter { + compileScript = '' + cp "$contentPath" tmp.rs + PATH=${lib.makeBinPath [ pkgs.gcc ]} ${rustc}/bin/rustc ${lib.escapeShellArgs rustcArgs} ${lib.escapeShellArgs darwinArgs} -o "$out" tmp.rs + ''; + inherit makeWrapperArgs strip; + } name; + + writeRustBin = name: writeRust "/bin/${name}"; + + /** + writeJS takes a name an attributeset with libraries and some JavaScript sourcecode and + returns an executable + + # Inputs + + `name` + + : 1\. Function argument + + `attrs` + + : 2\. Function argument + + `content` + + : 3\. Function argument + + # Examples + :::{.example} + ## `pkgs.writers.writeJS` usage example + + ```nix + writeJS "example" { libraries = [ pkgs.uglify-js ]; } '' + var UglifyJS = require("uglify-js"); + var code = "function add(first, second) { return first + second; }"; + var result = UglifyJS.minify(code); + console.log(result.code); + '' + ``` + + ::: + */ + writeJS = + name: + { + libraries ? [ ], + }: + content: + let + node-env = pkgs.buildEnv { + name = "node"; + paths = libraries; + pathsToLink = [ "/lib/node_modules" ]; + }; + in + writeDash name '' + export NODE_PATH=${node-env}/lib/node_modules + exec ${lib.getExe pkgs.nodejs} ${pkgs.writeText "js" content} "$@" + ''; + + /** + writeJSBin takes the same arguments as writeJS but outputs a directory (like writeScriptBin) + */ + writeJSBin = name: writeJS "/bin/${name}"; + + awkFormatNginx = builtins.toFile "awkFormat-nginx.awk" '' + awk -f + {sub(/^[ \t]+/,"");idx=0} + /\{/{ctx++;idx=1} + /\}/{ctx--} + {id="";for(i=idx;i $out + gixy $out + ''; + + /** + writePerl takes a name an attributeset with libraries and some perl sourcecode and + returns an executable + + # Examples + :::{.example} + ## `pkgs.writers.writePerl` usage example + + ```nix + writePerl "example" { libraries = [ pkgs.perlPackages.boolean ]; } '' + use boolean; + print "Howdy!\n" if true; + '' + ``` + + ::: + */ + writePerl = + name: + { + libraries ? [ ], + ... + }@args: + makeScriptWriter ( + (builtins.removeAttrs args [ "libraries" ]) + // { + interpreter = "${lib.getExe (pkgs.perl.withPackages (p: libraries))}"; + } + ) name; + + /** + writePerlBin takes the same arguments as writePerl but outputs a directory (like writeScriptBin) + */ + writePerlBin = name: writePerl "/bin/${name}"; + + /** + makePythonWriter takes python and compatible pythonPackages and produces python script writer, + which validates the script with flake8 at build time. If any libraries are specified, + python.withPackages is used as interpreter, otherwise the "bare" python is used. + + # Inputs + + `python` + + : 1\. Function argument + + `pythonPackages` + + : 2\. Function argument + + `buildPythonPackages` + + : 3\. Function argument + + `name` + + : 4\. Function argument + + `attrs` + + : 5\. Function argument + */ + makePythonWriter = + python: pythonPackages: buildPythonPackages: name: + { + libraries ? [ ], + flakeIgnore ? [ ], + doCheck ? true, + ... + }@args: + let + ignoreAttribute = + optionalString (flakeIgnore != [ ]) + "--ignore ${concatMapStringsSep "," escapeShellArg flakeIgnore}"; + in + makeScriptWriter ( + (builtins.removeAttrs args [ + "libraries" + "flakeIgnore" + "doCheck" + ]) + // { + interpreter = + if pythonPackages != pkgs.pypy2Packages || pythonPackages != pkgs.pypy3Packages then + if libraries == [ ] then python.interpreter else (python.withPackages (ps: libraries)).interpreter + else + python.interpreter; + check = optionalString (python.isPy3k && doCheck) ( + writeDash "pythoncheck.sh" '' + exec ${buildPythonPackages.flake8}/bin/flake8 --show-source ${ignoreAttribute} "$1" + '' + ); + } + ) name; + + /** + writePyPy2 takes a name an attributeset with libraries and some pypy2 sourcecode and + returns an executable + + # Examples + :::{.example} + ## `pkgs.writers.writePyPy2` usage example + + ```nix + writePyPy2 "test_pypy2" { libraries = [ pkgs.pypy2Packages.enum ]; } '' + from enum import Enum + + class Test(Enum): + a = "success" + + print Test.a + '' + ``` + + ::: + */ + writePyPy2 = makePythonWriter pkgs.pypy2 pkgs.pypy2Packages buildPackages.pypy2Packages; + + /** + writePyPy2Bin takes the same arguments as writePyPy2 but outputs a directory (like writeScriptBin) + */ + writePyPy2Bin = name: writePyPy2 "/bin/${name}"; + + /** + writePython3 takes a name an attributeset with libraries and some python3 sourcecode and + returns an executable + + # Examples + :::{.example} + ## `pkgs.writers.writePython3` usage example + + ```nix + writePython3 "test_python3" { libraries = [ pkgs.python3Packages.pyyaml ]; } '' + import yaml + + y = yaml.safe_load(""" + - test: success + """) + print(y[0]['test']) + '' + ``` + + ::: + */ + writePython3 = makePythonWriter pkgs.python3 pkgs.python3Packages buildPackages.python3Packages; + + # writePython3Bin takes the same arguments as writePython3 but outputs a directory (like writeScriptBin) + writePython3Bin = name: writePython3 "/bin/${name}"; + + /** + writePyPy3 takes a name an attributeset with libraries and some pypy3 sourcecode and + returns an executable + + # Examples + :::{.example} + ## `pkgs.writers.writePyPy3` usage example + + ```nix + writePyPy3 "test_pypy3" { libraries = [ pkgs.pypy3Packages.pyyaml ]; } '' + import yaml + + y = yaml.safe_load(""" + - test: success + """) + print(y[0]['test']) + '' + ``` + + ::: + */ + writePyPy3 = makePythonWriter pkgs.pypy3 pkgs.pypy3Packages buildPackages.pypy3Packages; + + /** + writePyPy3Bin takes the same arguments as writePyPy3 but outputs a directory (like writeScriptBin) + */ + writePyPy3Bin = name: writePyPy3 "/bin/${name}"; + + makeFSharpWriter = + { + dotnet-sdk ? pkgs.dotnet-sdk, + fsi-flags ? "", + libraries ? _: [ ], + ... + }@args: + nameOrPath: + let + fname = last (builtins.split "/" nameOrPath); + path = if strings.hasSuffix ".fsx" nameOrPath then nameOrPath else "${nameOrPath}.fsx"; + _nugetDeps = mkNugetDeps { + name = "${fname}-nuget-deps"; + nugetDeps = libraries; + }; + + nuget-source = mkNugetSource { + name = "${fname}-nuget-source"; + description = "Nuget source with the dependencies for ${fname}"; + deps = [ _nugetDeps ]; + }; + + fsi = writeBash "fsi" '' + set -euo pipefail + export HOME=$NIX_BUILD_TOP/.home + export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 + export DOTNET_CLI_TELEMETRY_OPTOUT=1 + export DOTNET_NOLOGO=1 + export DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK=1 + script="$1"; shift + ( + ${lib.getExe dotnet-sdk} new nugetconfig + ${lib.getExe dotnet-sdk} nuget disable source nuget + ) > /dev/null + ${lib.getExe dotnet-sdk} fsi --quiet --nologo --readline- ${fsi-flags} "$@" < "$script" + ''; + + in + content: + makeScriptWriter + ( + (builtins.removeAttrs args [ + "dotnet-sdk" + "fsi-flags" + "libraries" + ]) + // { + interpreter = fsi; + } + ) + path + '' + #i "nuget: ${nuget-source}/lib" + ${content} + exit 0 + ''; + + writeFSharp = makeFSharpWriter { }; + + writeFSharpBin = name: writeFSharp "/bin/${name}"; +} diff --git a/pkgs/tokyo-night/default.nix b/pkgs/tokyo-night/default.nix new file mode 100644 index 0000000..2278384 --- /dev/null +++ b/pkgs/tokyo-night/default.nix @@ -0,0 +1,41 @@ +{ + lib, + stdenv, + fetchFromGitHub, + gtk-engine-murrine, + gnome-themes-extra, + bash, + sassc, +}: +stdenv.mkDerivation { + pname = "tokyo-night-gtk"; + version = "main"; + + src = fetchFromGitHub { + owner = "Fausto-Korpsvart"; + repo = "Tokyonight-GTK-Theme"; + rev = "4dc45d60bf35f50ebd9ee41f16ab63783f80dd64"; + sha256 = "0c7sp9n2pc70yy9msmbmcyhqbr63v1ssnsxk6vg10zwwc3wl19h0"; + }; + + nativeBuildInputs = [bash sassc]; + buildInputs = [gtk-engine-murrine gnome-themes-extra]; + propagatedUserEnvPkgs = [gtk-engine-murrine]; + + buildPhase = '' + bash ./install.sh --dest $out/share/themes -n Tokyonight + bash ./install.sh --dest $out/share/themes -n Tokyonight --tweaks storm + bash ./install.sh --dest $out/share/themes -n Tokyonight --tweaks storm black + bash ./install.sh --dest $out/share/themes -n Tokyonight --tweaks storm black outline + ''; + + installPhase = ""; + + meta = with lib; { + description = "Tokyo Night GTK Theme"; + homepage = "https://github.com/Fausto-Korpsvart/Tokyonight-GTK-Theme"; + license = licenses.gpl3; + platforms = platforms.all; + maintainers = ["Cobray"]; + }; +} diff --git a/pkgs/vivid-icons/default.nix b/pkgs/vivid-icons/default.nix new file mode 100644 index 0000000..a1393d0 --- /dev/null +++ b/pkgs/vivid-icons/default.nix @@ -0,0 +1,54 @@ +{ + lib, + stdenv, + fetchFromGitHub, + hicolor-icon-theme, +}: +stdenv.mkDerivation rec { + pname = "vivid-icons"; + version = "unstable-${builtins.substring 0 7 "fe8b8f1bdd3784dc838c125bb9e1b2d713f40e67"}"; + src = fetchFromGitHub { + owner = "L4ki"; + repo = "Vivid-Plasma-Themes"; + rev = "fe8b8f1bdd3784dc838c125bb9e1b2d713f40e67"; + sha256 = "UlZkxeWb2n5TexaQymeyEqAjKwDfonTXO2OYjICHl+U="; + }; + buildInputs = [hicolor-icon-theme]; + installPhase = '' + mkdir -p $out/share/icons + for dir in Vivid-Icons-*; do + if [ -d "$dir" ]; then + theme_name=$(basename "$dir") + dest_dir="$out/share/icons/$theme_name" + cp -r "$dir" "$dest_dir" + echo "[Icon Theme]" > "$dest_dir/index.theme" + echo "Name=$theme_name" >> "$dest_dir/index.theme" + echo "Comment=$theme_name icons" >> "$dest_dir/index.theme" + echo "Inherits=hicolor" >> "$dest_dir/index.theme" + directories="" + for size_dir in "$dest_dir"/*; do + if [ -d "$size_dir" ]; then + size=$(basename "$size_dir") + if [[ "$size" =~ ^[0-9]+x[0-9]+$ ]]; then + directories="$directories''${directories:+,}$size" + echo "[$size]" >> "$dest_dir/index.theme" + echo "Size=''${size%%x*}" >> "$dest_dir/index.theme" + echo "Context=Actions" >> "$dest_dir/index.theme" + echo "Type=Fixed" >> "$dest_dir/index.theme" + fi + fi + done + echo "Directories=$directories" >> "$dest_dir/index.theme" + fi + done + echo "Installed themes:" + ls -la $out/share/icons/ + ''; + meta = with lib; { + description = "Vivid Icons Theme"; + homepage = "https://github.com/L4ki/Vivid-Plasma-Themes"; + license = licenses.gpl3; + platforms = platforms.all; + maintainers = with maintainers; ["Cobray"]; + }; +}