From 4c8f811caba4907304c8bc738f6da82c13d2debf Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Fri, 19 Jul 2024 13:50:15 +0800 Subject: [PATCH] wrapper-manager-fds/docs: update README Rather migrate it as part of the documentation content. --- README.adoc | 471 +--------------------- docs/content/en-US/project-overview.adoc | 474 +++++++++++++++++++++++ docs/content/en-US/quick-breakdown.adoc | 4 - docs/layouts/index.html | 2 +- 4 files changed, 476 insertions(+), 475 deletions(-) mode change 100644 => 120000 README.adoc create mode 100644 docs/content/en-US/project-overview.adoc delete mode 100644 docs/content/en-US/quick-breakdown.adoc diff --git a/README.adoc b/README.adoc deleted file mode 100644 index e11945e..0000000 --- a/README.adoc +++ /dev/null @@ -1,470 +0,0 @@ -= nix-wrapper-manager-fds -:toc: - - -wrapper-manager-fds is foodogsquared's reimagining of https://github.com/viperML/wrapper-manager/[wrapper-manager]. - -[CAUTION] -==== -wrapper-manager-fds is considered unstable and the author is still freely experimenting with various aspects of the project including the module options, library set API, and ease of use for third-partyuse. -Expect constant breakages here and put on a hard hat before exploring this part of the town. -==== - -As a recap, the original aim of wrapper-manager is to pave a way of configuring Nix environments through wrappers. -There has been https://discourse.nixos.org/t/declarative-wrappers/1775[interest on] https://github.com/NixOS/rfcs/pull/75[this feature] footnote:[I mean, a part of the nixpkgs package set has dedicated wrappers for some packages such as GIMP, Inkscape, and Blender.] and I sometimes configure programs through wrappers instead of the typical module system. -It has its use cases such as quickly creating variants of the same program for specific reasons (for example, creating specialized versions of yt-dlp for downloading audio, video, and more). -But why not create something more than that? -And that's how wrapper-manager-fds came to be. - -[#installation] -== Installation - -[#installation-channels] -=== Channels - -You can install wrapper-manager-fds with https://zero-to-nix.com/concepts/channels[Nix channels]. - -[source, shell] ----- -nix-channel --add https://github.com/foo-dogsquared/wrapper-manager-fds/archive/master.tar.gz wrapper-manager-fds -nix-channel --update ----- - -Then in your environment configuration, you'll have to import it. -For more details, see <>. - -[#installation-pinning-tool] -=== Pinning tool - -A recommended (non-flakes) way to install Nix dependencies is to use a pinning tool. -There are a handful of pinning tool out there but in this case, we'll use https://github.com/andir/npins[npins] as our tool of choice. -Assuming you have already initialized npins, you can simply add wrapper-manager-fds to your Nix project with the following command. - -[source, shell] ----- -npins add github foo-dogsquared wrapper-manager-fds ----- - -Similar to channels installation, you'll have to import the <> object. - -[#installation-manual-pinning] -=== Manual pinning - -Though not recommended, you could manually pin the Nix library yourself like in the following code. - -[source, nix] ----- -{ pkgs, ... }: - -let - wrapper-manager-fds = builtins.fetchTarball "https://github.com/foo-dogsquared/wrapper-manager-fds/archive/master.tar.gz"; - wrapperManager = import wrapper-manager-fds { }; - wrapperManagerLib = import wrapperManagerLib.lib { inherit pkgs; } -in -wrapperManagerLib.env.build { } ----- - -[#installation-flakes] -=== Flakes - -This project also has a https://zero-to-nix.com/concepts/flakes[flake object]. -In your flake definition, just import it as one of the inputs. -Unlike the other methods, the flake output is the user entrypoint so no need to import it or anything. - -[source, nix] ----- -{ - inputs.wrapper-manager-fds.url = "github:foo-dogsquared/wrapper-manager-fds"; - - outputs = { nixpkgs, ... }@inputs: { - nixosConfigurations.desktop = nixpkgs.lib.nixosSystem { - modules = [ - ./hosts/desktop.nix - inputs.wrapper-manager-fds.nixosModules.default - ]; - }; - }; -} ----- - -[#user-entrypoint] -=== User entrypoint - -Most of the things you need from the project are all retrieveable from the entrypoint of this project (`default.nix`) which is an attribute set closely structured from a typical Nix flake that you see. -For example, if you want the NixOS module for wrapper-manager, you could refer to `nixosModules.default`. -Here's the breakdown of the attrset entries in the entrypoint. - -* `lib` is an attribute set containing the main functions: `eval` and `build`. -(More details to use them are in <>.) - -* `nixosModules` contains a set of NixOS modules for wrapper-manager-fds integration. -You could get the main module with the `default` attribute. - -* `homeModules` are for home-manager modules and similarly structured to `nixosModules` attribute. - -* `wrapperManagerLib` contains a path intended to be imported within your Nix code. -It simply contains the library set that can be used outside of the wrapper-manager-fds module environment. - - -[#getting-started] -== Getting started - -Now that you have wrapper-manager-fds on the go, let's have a breakdown of what it is, exactly. -The project itself is made of different parts which you can use for different purposes. - -[#the-module-environment] -=== The module environment - -One part of the project is the module environment. -Just like https://github.com/nix-community/home-manager[home-manager] and https://github.com/nix-community/disko[disko] and https://github.com/viperML/wrapper-manager[the original source], wrapper-manager-fds comes with its own module environment. -Instead of a home environment from home-manager or an installation script from disko, wrapper-manager-fds module environment evaluates to a derivation containing a wrapper script. footnote:[While the original source also evaluates similar to that, it typically involves a set of wrappers inside of the same configuration environment rather than a single wrapper.] -This can be thought of as a declarative layer over `makeWrapper` build hook from nixpkgs. - -Here's a very simple example of a wrapper for Neofetch. - -[source, nix] ----- -{ lib, pkgs, ... }: - -{ - wrappers.neofetch = { - arg0 = lib.getExe' pkgs.neofetch "neofetch"; - appendArgs = [ - "--ascii_distro" "guix" - "--title_fqdn" "off" - "--os_arch" "off" - ]; - }; -} ----- - -Or if you want fastfetch... - -[source, nix] ----- -{ lib, pkgs, ... }: - -{ - wrappers.fastfetch = { - arg0 = lib.getExe' pkgs.fastfetch "fastfetch"; - appendArgs = [ "--logo" "Guix" ]; - env.NO_COLOR = "1"; - }; -} ----- - -Or even both in the same configuration (which you can do). - -[source, nix] ----- -{ - imports = [ - ./fastfetch.nix - ./neofetch.nix - ]; -} ----- - -You could even create https://specifications.freedesktop.org/desktop-entry-spec/latest/[XDG desktop entry] files useful for the application to be launched through an application launcher/menu. -For example, you could create an executable and a desktop entry to launch a custom Firefox profile in your home-manager configuration. - -.Creating a custom Firefox desktop entry launching a custom profile -[source, nix] ----- -{ config, lib, pkgs, ... }: - -{ - programs.firefox.profiles.custom-profile = { - # Put some profile-specific settings here. - }; - - wrapper-manager.packages.browsers = { - wrappers.firefox-custom-profile = { - arg0 = lib.getExe' config.programs.firefox.package "firefox"; - prependArgs = [ - "-P" "custom-profile" - ]; - xdg.desktopEntry = { - enable = true; - settings = { - desktopName = "Firefox (custom-profile)"; - startupNotify = true; - startupWMClass = "firefox"; - icon = "firefox"; - mimeTypes = [ - "text/html" - "application/xhtml+xml" - "application/vnd.mozilla.xul+xml" - "x-scheme-handler/http" - "x-scheme-handler/https" - ]; - }; - }; - }; - }; -} ----- - -[#as-a-library] -=== As a library - -wrapper-manager also comes with a library set which you can use to evaluate and build wrapper-manager packages yourself. -This is found in the `wrapperManagerLib` attribute from the user entrypoint where it needs an attribute set containing a nixpkgs instance in `pkgs`. - -[#src:example-lib-build] -.An example of importing wrapper-manager library -[source, nix] ----- -{ pkgs }: - -let - wrapper-manager = import (builtins.fetchgit { }) { }; - - wmLib = import wrapper-manager.wrapperManagerLib { inherit pkgs; }; -in -wmLib.env.build { - inherit pkgs; - modules = [ ./fastfetch.nix ]; - specialArgs.yourMomName = "Joe Mama"; -} ----- - -Here's a quick rundown of what you can do with the library. - -* Evaluate a wrapper-manager module with `env.eval` where it accepts an attrset similar to the <> containing a list of additional modules, the nixpkgs instance to be used, and `specialArgs` to be passed on to the `lib.evalModules` from nixpkgs. - -* Build a wrapper through `env.build` returning a derivation of the wrapper. -It accepts the same arguments as `env.eval`. - -There is also `lib` attribute if all you want to do is to build and/or evaluate a wrapper-manager configuration. -It only contains the function from `env` subset which contains `build` and `eval`. - -[#as-a-composable-module] -=== As a composable module - -The most user-friendly way of using wrapper-manager would be as a composable nixpkgs module of an existing environment. -wrapper-manager provides a Nix module specifically for NixOS and home-manager environment. footnote:[Any other environments are basically unsupported and if you like to use it outside of NixOS and home-manager, you're on your own.] -You can import them through the `{nixos,home}Modules.default` from the user entrypoint of the project. - -Most of the things set up here are implemented to make declaring wrappers ergonomic with the environment. -For a start, wrapper-manager-fds sets up a module namespace in `wrapper-manager`. -Here's a quick breakdown of the features that the module has. - -* Passes the wrapper-manager library through `wrapperManagerLib` module argument. -This is nice if you want to only use wrapper-manager to quickly create wrappers inside of the configuration without using the wrapper-manager NixOS/home-manager integration module. - -* You could declare wrappers through `wrapper-manager.packages.` where each of the attribute value is expected to be a wrapper-manager configuration to be added in its respective wider-scope environment. - -* You could include other modules through `wrapper-manager.sharedModules`. -This is useful for extending wrapper-manager inside of the configuration environment. - -Here's an example of adding wrappers through wrapper-manager inside of a home-manager configuration. -The following configuration will create a wrapped package for yt-dlp with an additional wrapper script named `yt-dlp-audio` and `yt-dlp-video`. - -.Installing yt-dlp with custom variants of it inside of a home-manager configuration -[source, nix] ----- -{ config, lib, pkgs, ... }: - -{ - home.packages = with pkgs; [ - flowtime - blanket - ]; - - wrapper-manager.packages = { - music-setup = { - basePackages = [ pkgs.yt-dlp ]; - wrappers.yt-dlp-audio = { - arg0 = lib.getExe' pkgs.yt-dlp "yt-dlp"; - prependArgs = [ - "--config-location" ./config/yt-dlp/audio.conf - ]; - }; - wrappers.yt-dlp-video = { - arg0 = lib.getExe' pkgs.yt-dlp "yt-dlp"; - prependArgs = [ - "--config-location" ./config/yt-dlp/video.conf - ]; - }; - }; - }; -} ----- - - -[#development] -== Development - -If you want to hack this hack, you'll need either Nix with flakes enabled (`experimental-features = nix-command flakes` in `nix.conf`) or not. -Either way, this should be enough to cater both flake- and non-flake users. - -This project supports the current stable and unstable version of NixOS. -Specifically, we're looking out for the nixpkgs instance both of these versions has. -As an implementation detail, we pin these branches through https://github.com/andir/npins[npins] which both flakes- and non-flake-based setups uses. -Just be familiar with it and you'll be fine for the most part. footnote:[Most likely, you don't even need to interact with it for the most part since handling update cadence is handled automatically through the remote CI.] - -Setting up the development environment should be easy enough. - -* For flake users, you can just reproduce the development environment with `nix develop`. -* For non-flake users, you can do the same with `nix-develop`. - -As an additional note, it is recommended to use something like direnv with `use flake` or `use nix` depending on your personal preferences to use flake or not. - -Take note there is a `Makefile` full of commands intended for easily interacting with the project but it is heavily assumed you're in the development environment of the project. - -[#development-library-set-and-modules] -=== Library set and modules - -This Nix project has a test infrastructure set up at link:./tests[./tests] covering the library set nad the wrapper-manager module environment. -For its library set, it makes use of the nixpkgs library and a JSON schema to validate if it passes the whole tests. -To make use of it, you can run it with the following commands. - -* For flake users, you can run `nix flake check`. -* For non-flake users, you can do the same with `nix-build tests/ -A libTestPkg` or `nix build -f tests/ libTestPkg`. - -The derivation output should be successfully built if all of the tests in the suite passes. -Otherwise, it should fail and you'll have to see the build log containing all of the tests that failed. - -On another note, there is a quicker way of checking the test suite with `nix eval -f tests lib` (or `nix-instantiate --eval --strict tests/ -A lib`) where it contains the raw test data which is useful if you don't want to essentially build a new derivation each time. -It is also quicker to eyeball results in this way especially if you're always working with the tests anyways. - -[#development-website] -=== Website - -This project also has a website set up with https://gohugo.io/[Hugo]. -The files that you need to see are in link:./docs[./docs] directory. - -* For flake users, you can build the website with `nix build .#website`. -* For non-flake users, you can do the same with `nix-build docs/`. - -There is also a dedicated development environment placed in `docs/shell.nix` but this should be a part of the primary development environment already. -You can enter it with `nix develop .#website` or `nix-shell docs/`. - -Just take note that the website also requires the NixOS options which comes in a JSON file. -This should be already taken care of in the package definition of the website but otherwise it is something that you'll have to be aware of. - -The more important task to developing this part of the project is continuously getting feedback from it. -You can do so simply with the following commands: - -* For flake users, `nix develop --command hugo -s ./docs serve`. -* For non-flake users, `nix-shell docs --command hugo -s ./docs serve`. -* If you're using `Makefile` of this project, `make docs-serve`. - -[#development-nix] -=== Nix environment - -As for developing the environment with Nix itself, it is very much preferred to make wrapper-manager-fds work with non-flake setups. -This also includes the workflow of the development itself for the purpose of easier time bootstrapping wrapper-manager-fds. - -Due to the unfortunate situation with flakes as an experimental feature, it is more like a second-class citizen in terms of support. -This is because it is pretty easy to make a flake with non-flake tools compared to vice versa. footnote:[flake-compat is great and all but it holds back wrapper-manager-fds in making it easy to bootstrap if we rely on it.] - -Here's an exhaustive guidelines that you have to keep in mind when developing related files within the project: - -* This project uses https://calver.org/[calendar versioning] following software versioning of the upstream. -The unstable branches are basically deployed with development versions of this project. - -* Only the current stable branch and the unstable branch of NixOS is supported. - -* The preferred default nixpkgs branch at development is `nixos-unstable`. - -* There shouldn't be any user consumables that requires anything from the npins sources. - - -[#goals-and-non-goals] -== Goals and non-goals - -As a Nix project, wrapper-manager-fds aims for the following goals. - -* Create an ecosystem of creating them wrappers, mainly through its library set and the module environment. - -* Make creating wrappers ergonomic for its users. -Not necessarily user-friendly but it should easy enough to get started while allowing some flexibility, yeah? - -* Make a nice environment for creating custom wrappers which is already quite possible thanks to the heavy lifting of the nixpkgs module system. - - -[#faq] -== Frequently asked questions (FAQ) - -[qanda] -Is this compatible with the original wrapper-manager?:: -Nope. -It is a reimagining with a completely different way of using it so it won't be fully compatible with it from the start. - -Why reimplement this anyways?:: -For funsies and also because there are some things I find not so great with using the project. -https://github.com/viperML/wrapper-manager/tree/307eb5c38c8b5102c39617a59b63929efac7b1a7[As of this writing], using wrapper-manager to simply create wrappers anywhere is a pain. - -Why not just incorporate the wanted changes into the original implementation?:: -While it could be done, there will be some unwanted major changes into the project which would cause inconvenience to its users anyways so it isn't a good idea. - -Can't you just create a wrapper with `pkgs.makeWrapper` and such from nixpkgs?:: -Yeah, you can. -There's nobody stopping you from doing so and surely there's no hitman preparing to assissinate right behind you as you about to deny wrapper-manager-fds and smugly type `make` in `makeWrapper`. -In fact, wrapper-manager uses `makeWrapper` as the main ingredient. -Just think of wrapper-manager as a declarative version of that among the bajillion ways of making wrappers in the Nix ecosystem. -+ -As an additional point, there are still use cases for it even with a simple `pkgs.writeShellScriptBin`. -In fact, if you have a situation like say having to create a one-off wrapper script to be added in a NixOS system, you can simply do the following: -+ -[source, nix] ----- -let - ytdlpAudio = pkgs.writeScriptBin "yt-dlp-audio" '' - ${pkgs.yt-dlp}/bin/yt-dlp --config-location "${../../config/yt-dlp/audio.conf}" $@ - ''; -in -{ - environment.systemPackages = [ ytdlpAudio ]; -} ----- -+ -BAM! -No need for wrapper-manager! - -Why use the module system?:: -Because screw you, that's why!!! -Am I stupid and lazy for basically using a battle-hardened configuration system library such as nixpkgs module system? footnote:[The answer is yes to both!] -+ -Seriously though, the main reason is pretty simple: it is quite established and a battle-hardened part in the Nix ecosystem. -It has gone through the test of time and the numerous 339 users of the entire Nix ecosystem are quite adamant in the declarative aspect of the Nix thingy. -So... why not use it. - -Any problems (and impending explosions) when using this project?:: -As far as I can tell, not much (especially explosions) but there are a few caveats you need to know. -Just know this is something the author is trying to resolve. -+ --- -* wrapper-manager-fds is not great at handling double wrappers. -It just naively wraps a package and goes on its merry way. - -* wrapper-manager-fds doesn't handle any replacement for the related files very well. -This is especially noticeable in large desktop-adjacent packages such as Inkscape, Firefox, and Blender with a bunch of plugins and whatnot where they have their own wrappers. -This means you cannot set `programs.NAME.package` or something similar with it. --- - - -[#acknowledgements] -== Acknowledgements - -I found a bunch of things for inspiration (READ: to steal ideas from). -Here's a list of resources I've found. - -* The original source of the reimagining, of course: https://github.com/viperML/wrapper-manager[wrapper-manager]. - -* https://github.com/NixOS/rfcs/pull/75[Nix RFC 75] which also comes https://github.com/NixOS/nixpkgs/pull/85103[with its implementation and discussion around what works and whatnot]. - -* https://discourse.nixos.org/t/pre-rfc-module-system-for-wrappers-in-nixpkgs/42281[This NixOS Discourse post loudly thinking about the same idea.] - - -[#copyright] -== Copyright - -This project is licensed under MIT License (SPDX identifier: https://spdx.org/licenses/MIT.html[`MIT`]). -Just see link:./LICENSE[`./LICENSE`] for full text and details and whatnot. - -The documentation (except for the code examples), on the other hand, is licensed under https://www.gnu.org/licenses/fdl-1.3.txt[GNU Free Documentation License] v1.3 only with no "Invariants" section (SPDX identifier: https://spdx.org/licenses/GFDL-1.3-no-invariants-only[`GFDL-1.3-no-invariants-only`]) -You can see either the link or link:./docs/LICENSE[`./docs/LICENSE`] for more info. -The code examples, similar to the project codebase, are licensed under MIT with the same conditions apply and all that jazz. diff --git a/README.adoc b/README.adoc new file mode 120000 index 0000000..9f4dec8 --- /dev/null +++ b/README.adoc @@ -0,0 +1 @@ +docs/content/en-US/project-overview.adoc \ No newline at end of file diff --git a/docs/content/en-US/project-overview.adoc b/docs/content/en-US/project-overview.adoc new file mode 100644 index 0000000..273aeba --- /dev/null +++ b/docs/content/en-US/project-overview.adoc @@ -0,0 +1,474 @@ +--- +title: Project overview +--- += nix-wrapper-manager-fds +:toc: + + +wrapper-manager-fds is foodogsquared's reimagining of https://github.com/viperML/wrapper-manager/[wrapper-manager]. + +[CAUTION] +==== +wrapper-manager-fds is considered unstable and the author is still freely experimenting with various aspects of the project including the module options, library set API, and ease of use for third-partyuse. +Expect constant breakages here and put on a hard hat before exploring this part of the town. +==== + +As a recap, the original aim of wrapper-manager is to pave a way of configuring Nix environments through wrappers. +There has been https://discourse.nixos.org/t/declarative-wrappers/1775[interest on] https://github.com/NixOS/rfcs/pull/75[this feature] footnote:[I mean, a part of the nixpkgs package set has dedicated wrappers for some packages such as GIMP, Inkscape, and Blender.] and I sometimes configure programs through wrappers instead of the typical module system. +It has its use cases such as quickly creating variants of the same program for specific reasons (for example, creating specialized versions of yt-dlp for downloading audio, video, and more). +But why not create something more than that? +And that's how wrapper-manager-fds came to be. + +[#installation] +== Installation + +[#installation-channels] +=== Channels + +You can install wrapper-manager-fds with https://zero-to-nix.com/concepts/channels[Nix channels]. + +[source, shell] +---- +nix-channel --add https://github.com/foo-dogsquared/wrapper-manager-fds/archive/master.tar.gz wrapper-manager-fds +nix-channel --update +---- + +Then in your environment configuration, you'll have to import it. +For more details, see <>. + +[#installation-pinning-tool] +=== Pinning tool + +A recommended (non-flakes) way to install Nix dependencies is to use a pinning tool. +There are a handful of pinning tool out there but in this case, we'll use https://github.com/andir/npins[npins] as our tool of choice. +Assuming you have already initialized npins, you can simply add wrapper-manager-fds to your Nix project with the following command. + +[source, shell] +---- +npins add github foo-dogsquared wrapper-manager-fds +---- + +Similar to channels installation, you'll have to import the <> object. + +[#installation-manual-pinning] +=== Manual pinning + +Though not recommended, you could manually pin the Nix library yourself like in the following code. + +[source, nix] +---- +{ pkgs, ... }: + +let + wrapper-manager-fds = builtins.fetchTarball "https://github.com/foo-dogsquared/wrapper-manager-fds/archive/master.tar.gz"; + wrapperManager = import wrapper-manager-fds { }; + wrapperManagerLib = import wrapperManagerLib.lib { inherit pkgs; } +in +wrapperManagerLib.env.build { } +---- + +[#installation-flakes] +=== Flakes + +This project also has a https://zero-to-nix.com/concepts/flakes[flake object]. +In your flake definition, just import it as one of the inputs. +Unlike the other methods, the flake output is the user entrypoint so no need to import it or anything. + +[source, nix] +---- +{ + inputs.wrapper-manager-fds.url = "github:foo-dogsquared/wrapper-manager-fds"; + + outputs = { nixpkgs, ... }@inputs: { + nixosConfigurations.desktop = nixpkgs.lib.nixosSystem { + modules = [ + ./hosts/desktop.nix + inputs.wrapper-manager-fds.nixosModules.default + ]; + }; + }; +} +---- + +[#user-entrypoint] +=== User entrypoint + +Most of the things you need from the project are all retrieveable from the entrypoint of this project (`default.nix`) which is an attribute set closely structured from a typical Nix flake that you see. +For example, if you want the NixOS module for wrapper-manager, you could refer to `nixosModules.default`. +Here's the breakdown of the attrset entries in the entrypoint. + +* `lib` is an attribute set containing the main functions: `eval` and `build`. +(More details to use them are in <>.) + +* `nixosModules` contains a set of NixOS modules for wrapper-manager-fds integration. +You could get the main module with the `default` attribute. + +* `homeModules` are for home-manager modules and similarly structured to `nixosModules` attribute. + +* `wrapperManagerLib` contains a path intended to be imported within your Nix code. +It simply contains the library set that can be used outside of the wrapper-manager-fds module environment. + + +[#getting-started] +== Getting started + +Now that you have wrapper-manager-fds on the go, let's have a breakdown of what it is, exactly. +The project itself is made of different parts which you can use for different purposes. + +[#the-module-environment] +=== The module environment + +One part of the project is the module environment. +Just like https://github.com/nix-community/home-manager[home-manager] and https://github.com/nix-community/disko[disko] and https://github.com/viperML/wrapper-manager[the original source], wrapper-manager-fds comes with its own module environment. +Instead of a home environment from home-manager or an installation script from disko, wrapper-manager-fds module environment evaluates to a derivation containing a wrapper script. footnote:[While the original source also evaluates similar to that, it typically involves a set of wrappers inside of the same configuration environment rather than a single wrapper.] +This can be thought of as a declarative layer over `makeWrapper` build hook from nixpkgs. + +Here's a very simple example of a wrapper for Neofetch. + +[source, nix] +---- +{ lib, pkgs, ... }: + +{ + wrappers.neofetch = { + arg0 = lib.getExe' pkgs.neofetch "neofetch"; + appendArgs = [ + "--ascii_distro" "guix" + "--title_fqdn" "off" + "--os_arch" "off" + ]; + }; +} +---- + +Or if you want fastfetch... + +[source, nix] +---- +{ lib, pkgs, ... }: + +{ + wrappers.fastfetch = { + arg0 = lib.getExe' pkgs.fastfetch "fastfetch"; + appendArgs = [ "--logo" "Guix" ]; + env.NO_COLOR = "1"; + }; +} +---- + +Or even both in the same configuration (which you can do). + +[source, nix] +---- +{ + imports = [ + ./fastfetch.nix + ./neofetch.nix + ]; +} +---- + +You could even create https://specifications.freedesktop.org/desktop-entry-spec/latest/[XDG desktop entry] files useful for the application to be launched through an application launcher/menu. +For example, you could create an executable and a desktop entry to launch a custom Firefox profile in your home-manager configuration. + +.Creating a custom Firefox desktop entry launching a custom profile +[source, nix] +---- +{ config, lib, pkgs, ... }: + +{ + programs.firefox.profiles.custom-profile = { + # Put some profile-specific settings here. + }; + + wrapper-manager.packages.browsers = { + wrappers.firefox-custom-profile = { + arg0 = lib.getExe' config.programs.firefox.package "firefox"; + prependArgs = [ + "-P" "custom-profile" + ]; + xdg.desktopEntry = { + enable = true; + settings = { + desktopName = "Firefox (custom-profile)"; + startupNotify = true; + startupWMClass = "firefox"; + icon = "firefox"; + mimeTypes = [ + "text/html" + "application/xhtml+xml" + "application/vnd.mozilla.xul+xml" + "x-scheme-handler/http" + "x-scheme-handler/https" + ]; + }; + }; + }; + }; +} +---- + +[#as-a-library] +=== As a library + +wrapper-manager also comes with a library set which you can use to evaluate and build wrapper-manager packages yourself. +This is found in the `wrapperManagerLib` attribute from the user entrypoint where it needs an attribute set containing a nixpkgs instance in `pkgs`. + +[#src:example-lib-build] +.An example of importing wrapper-manager library +[source, nix] +---- +{ pkgs }: + +let + wrapper-manager = import (builtins.fetchgit { }) { }; + + wmLib = import wrapper-manager.wrapperManagerLib { inherit pkgs; }; +in +wmLib.env.build { + inherit pkgs; + modules = [ ./fastfetch.nix ]; + specialArgs.yourMomName = "Joe Mama"; +} +---- + +Here's a quick rundown of what you can do with the library. + +* Evaluate a wrapper-manager module with `env.eval` where it accepts an attrset similar to the <> containing a list of additional modules, the nixpkgs instance to be used, and `specialArgs` to be passed on to the `lib.evalModules` from nixpkgs. + +* Build a wrapper through `env.build` returning a derivation of the wrapper. +It accepts the same arguments as `env.eval`. + +There is also `lib` attribute if all you want to do is to build and/or evaluate a wrapper-manager configuration. +It only contains the function from `env` subset which contains `build` and `eval`. + +[#as-a-composable-module] +=== As a composable module + +The most user-friendly way of using wrapper-manager would be as a composable nixpkgs module of an existing environment. +wrapper-manager provides a Nix module specifically for NixOS and home-manager environment. footnote:[Any other environments are basically unsupported and if you like to use it outside of NixOS and home-manager, you're on your own.] +You can import them through the `{nixos,home}Modules.default` from the user entrypoint of the project. + +Most of the things set up here are implemented to make declaring wrappers ergonomic with the environment. +For a start, wrapper-manager-fds sets up a module namespace in `wrapper-manager`. +Here's a quick breakdown of the features that the module has. + +* Passes the wrapper-manager library through `wrapperManagerLib` module argument. +This is nice if you want to only use wrapper-manager to quickly create wrappers inside of the configuration without using the wrapper-manager NixOS/home-manager integration module. + +* You could declare wrappers through `wrapper-manager.packages.` where each of the attribute value is expected to be a wrapper-manager configuration to be added in its respective wider-scope environment. + +* You could include other modules through `wrapper-manager.sharedModules`. +This is useful for extending wrapper-manager inside of the configuration environment. + +Here's an example of adding wrappers through wrapper-manager inside of a home-manager configuration. +The following configuration will create a wrapped package for yt-dlp with an additional wrapper script named `yt-dlp-audio` and `yt-dlp-video`. + +.Installing yt-dlp with custom variants of it inside of a home-manager configuration +[source, nix] +---- +{ config, lib, pkgs, ... }: + +{ + home.packages = with pkgs; [ + flowtime + blanket + ]; + + wrapper-manager.packages = { + music-setup = { + basePackages = [ pkgs.yt-dlp ]; + wrappers.yt-dlp-audio = { + arg0 = lib.getExe' pkgs.yt-dlp "yt-dlp"; + prependArgs = [ + "--config-location" ./config/yt-dlp/audio.conf + ]; + }; + wrappers.yt-dlp-video = { + arg0 = lib.getExe' pkgs.yt-dlp "yt-dlp"; + prependArgs = [ + "--config-location" ./config/yt-dlp/video.conf + ]; + }; + }; + }; +} +---- + + +[#development] +== Development + +If you want to hack this hack, you'll need either Nix with flakes enabled (`experimental-features = nix-command flakes` in `nix.conf`) or not. +Either way, this should be enough to cater both flake- and non-flake users. + +This project supports the current stable and unstable version of NixOS. +Specifically, we're looking out for the nixpkgs instance both of these versions has. +As an implementation detail, we pin these branches through https://github.com/andir/npins[npins] which both flakes- and non-flake-based setups uses. +Just be familiar with it and you'll be fine for the most part. footnote:[Most likely, you don't even need to interact with it for the most part since handling update cadence is handled automatically through the remote CI.] + +Setting up the development environment should be easy enough. + +* For flake users, you can just reproduce the development environment with `nix develop`. +* For non-flake users, you can do the same with `nix-develop`. + +As an additional note, it is recommended to use something like direnv with `use flake` or `use nix` depending on your personal preferences to use flake or not. + +Take note there is a `Makefile` full of commands intended for easily interacting with the project but it is heavily assumed you're in the development environment of the project. + +[#development-library-set-and-modules] +=== Library set and modules + +This Nix project has a test infrastructure set up at link:./tests[./tests] covering the library set nad the wrapper-manager module environment. +For its library set, it makes use of the nixpkgs library and a JSON schema to validate if it passes the whole tests. +To make use of it, you can run it with the following commands. + +* For flake users, you can run `nix flake check`. +* For non-flake users, you can do the same with `nix-build tests/ -A libTestPkg` or `nix build -f tests/ libTestPkg`. + +The derivation output should be successfully built if all of the tests in the suite passes. +Otherwise, it should fail and you'll have to see the build log containing all of the tests that failed. + +On another note, there is a quicker way of checking the test suite with `nix eval -f tests lib` (or `nix-instantiate --eval --strict tests/ -A lib`) where it contains the raw test data which is useful if you don't want to essentially build a new derivation each time. +It is also quicker to eyeball results in this way especially if you're always working with the tests anyways. + +[#development-website] +=== Website + +This project also has a website set up with https://gohugo.io/[Hugo]. +The files that you need to see are in link:./docs[./docs] directory. + +* For flake users, you can build the website with `nix build .#website`. +* For non-flake users, you can do the same with `nix-build docs/`. + +There is also a dedicated development environment placed in `docs/shell.nix` but this should be a part of the primary development environment already. +You can enter it with `nix develop .#website` or `nix-shell docs/`. + +Just take note that the website also requires the NixOS options which comes in a JSON file. +This should be already taken care of in the package definition of the website but otherwise it is something that you'll have to be aware of. + +The more important task to developing this part of the project is continuously getting feedback from it. +You can do so simply with the following commands: + +* For flake users, `nix develop --command hugo -s ./docs serve`. +* For non-flake users, `nix-shell docs --command hugo -s ./docs serve`. +* If you're using `Makefile` of this project, `make docs-serve`. + +[#development-nix] +=== Nix environment + +As for developing the environment with Nix itself, it is very much preferred to make wrapper-manager-fds work with non-flake setups. +This also includes the workflow of the development itself for the purpose of easier time bootstrapping wrapper-manager-fds. + +Due to the unfortunate situation with flakes as an experimental feature, it is more like a second-class citizen in terms of support. +This is because it is pretty easy to make a flake with non-flake tools compared to vice versa. footnote:[flake-compat is great and all but it holds back wrapper-manager-fds in making it easy to bootstrap if we rely on it.] + +Here's an exhaustive guidelines that you have to keep in mind when developing related files within the project: + +* This project uses https://calver.org/[calendar versioning] following software versioning of the upstream. +The unstable branches are basically deployed with development versions of this project. + +* Only the current stable branch and the unstable branch of NixOS is supported. + +* The preferred default nixpkgs branch at development is `nixos-unstable`. + +* There shouldn't be any user consumables that requires anything from the npins sources. + + +[#goals-and-non-goals] +== Goals and non-goals + +As a Nix project, wrapper-manager-fds aims for the following goals. + +* Create an ecosystem of creating them wrappers, mainly through its library set and the module environment. + +* Make creating wrappers ergonomic for its users. +Not necessarily user-friendly but it should easy enough to get started while allowing some flexibility, yeah? + +* Make a nice environment for creating custom wrappers which is already quite possible thanks to the heavy lifting of the nixpkgs module system. + + +[#faq] +== Frequently asked questions (FAQ) + +[qanda] +Is this compatible with the original wrapper-manager?:: +Nope. +It is a reimagining with a completely different way of using it so it won't be fully compatible with it from the start. + +Why reimplement this anyways?:: +For funsies and also because there are some things I find not so great with using the project. +https://github.com/viperML/wrapper-manager/tree/307eb5c38c8b5102c39617a59b63929efac7b1a7[As of this writing], using wrapper-manager to simply create wrappers anywhere is a pain. + +Why not just incorporate the wanted changes into the original implementation?:: +While it could be done, there will be some unwanted major changes into the project which would cause inconvenience to its users anyways so it isn't a good idea. +Plus it also justifies me implementing a bunch of features that would otherwise be deemed inconsistent with the project. + +Can't you just create a wrapper with `pkgs.makeWrapper` and such from nixpkgs?:: +Yeah, you can. +There's nobody stopping you from doing so and surely there's no hitman preparing to assissinate right behind you as you about to deny wrapper-manager-fds and smugly type `make` in `makeWrapper`. +In fact, wrapper-manager uses `makeWrapper` as the main ingredient. +Just think of wrapper-manager as a declarative version of that among the bajillion ways of making wrappers in the Nix ecosystem. ++ +As an additional point, there are still use cases for it even with a simple `pkgs.writeShellScriptBin`. +In fact, if you have a situation like say having to create a one-off wrapper script to be added in a NixOS system, you can simply do the following: ++ +[source, nix] +---- +let + ytdlpAudio = pkgs.writeScriptBin "yt-dlp-audio" '' + ${pkgs.yt-dlp}/bin/yt-dlp --config-location "${../../config/yt-dlp/audio.conf}" $@ + ''; +in +{ + environment.systemPackages = [ ytdlpAudio ]; +} +---- ++ +BAM! +No need for wrapper-manager! + +Why use the module system?:: +Because screw you, that's why!!! +Am I stupid and lazy for basically using a battle-hardened configuration system library such as nixpkgs module system? footnote:[The answer is yes to both!] ++ +Seriously though, the main reason is pretty simple: it is quite established and a battle-hardened part in the Nix ecosystem. +It has gone through the test of time and the numerous 339 users of the entire Nix ecosystem are quite adamant in the declarative aspect of the Nix thingy. +So... why not use it. + +Any problems (and impending explosions) when using this project?:: +As far as I can tell, not much (especially explosions) but there are a few caveats you need to know. +Just know this is something the author is trying to resolve. ++ +-- +* wrapper-manager-fds is not great at handling double wrappers. +It just naively wraps a package and goes on its merry way. + +* wrapper-manager-fds doesn't handle any replacement for the related files very well. +This is especially noticeable in large desktop-adjacent packages such as Inkscape, Firefox, and Blender with a bunch of plugins and whatnot where they have their own wrappers. +This means you cannot set `programs.NAME.package` or something similar with it. +-- + + +[#acknowledgements] +== Acknowledgements + +I found a bunch of things for inspiration (READ: to steal ideas from). +Here's a list of resources I've found. + +* The original source of the reimagining, of course: https://github.com/viperML/wrapper-manager[wrapper-manager]. + +* https://github.com/NixOS/rfcs/pull/75[Nix RFC 75] which also comes https://github.com/NixOS/nixpkgs/pull/85103[with its implementation and discussion around what works and whatnot]. + +* https://discourse.nixos.org/t/pre-rfc-module-system-for-wrappers-in-nixpkgs/42281[This NixOS Discourse post loudly thinking about the same idea.] + + +[#copyright] +== Copyright + +This project is licensed under MIT License (SPDX identifier: https://spdx.org/licenses/MIT.html[`MIT`]). +Just see link:./LICENSE[`./LICENSE`] for full text and details and whatnot. + +The documentation (except for the code examples), on the other hand, is licensed under https://www.gnu.org/licenses/fdl-1.3.txt[GNU Free Documentation License] v1.3 only with no "Invariants" section (SPDX identifier: https://spdx.org/licenses/GFDL-1.3-no-invariants-only[`GFDL-1.3-no-invariants-only`]) +You can see either the link or link:./docs/LICENSE[`./docs/LICENSE`] for more info. +The code examples, similar to the project codebase, are licensed under MIT with the same conditions apply and all that jazz. diff --git a/docs/content/en-US/quick-breakdown.adoc b/docs/content/en-US/quick-breakdown.adoc deleted file mode 100644 index 01fb9c9..0000000 --- a/docs/content/en-US/quick-breakdown.adoc +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Quick breakdown ---- -include::../../../README.adoc[] diff --git a/docs/layouts/index.html b/docs/layouts/index.html index 405c9ff..3877670 100644 --- a/docs/layouts/index.html +++ b/docs/layouts/index.html @@ -1 +1 @@ -{{ with .GetPage "/quick-breakdown" }}{{ .Render "single" }}{{ end }} +{{ with .GetPage "/project-overview" }}{{ .Render "single" }}{{ end }}