diff --git a/README.md b/README.md new file mode 100644 index 0000000..b3a8e45 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# process-compose-flake +A [flake-parts](https://github.com/hercules-ci/flake-parts) module for [process-compose](https://github.com/F1bonacc1/process-compose). + +This `flake-parts` module allows you to declare one or more `process-compose` configurations using Nix attribute sets. It will generate corresponding `apps` and `packages` that wrap `process-compose` with the given configuration. + +This module is practical for local development e.g. if you have a lot of runtime dependencies that depend on each other. Stop executing these programs imperatively over and over again in a specific order, and stop the need to write complicated shell scripts to automate this. `process-compose` gives you a process dashboard for monitoring, inspecting logs for each process, and much more, all of this in a TUI. + +## Usage +Let's say you want to have a `devShell` that makes a command `watch-server` available, that you can use to spin up your projects `backend-server`, `frontend-server`, and `proxy-server`. + +To achieve this using `process-compose-flake` you can simply add the following code to the `perSystem` function in your `flake-parts` flake. +``` +process-compose.configs = { + watch-server.processes = { + backend-server.command = "${self'.apps.backend-server.program} --port 9000"; + frontend-server.command = "${self'.apps.frontend-server.program} --port 9001"; + proxy-server.command = + let + proxyConfig = pkgs.writeTextFile { + name = "proxy.conf"; + text = '' + ... + ''; + }; + in + "${self'.apps.proxy-server.program} -c ${proxyConfig} -p 8000"; + }; +}; +``` + +`process-compose-flake` will generate the following two outputs for you: + - `apps.${system}.watch-server` + - `packages.${system}.watch-server` + +Using the `apps` output you can spin up the processes by running `nix run .#watch-server`. + +The `package` output in turn can be used to make the `watch-server` command available in your `devShell`: +``` +devShells = { + default = pkgs.mkShell { + name = "my-shell"; + nativeBuildInputs = [ + self'.packages.watch-server + ]; + }; +}; +``` + +You can enter your devShell by running `nix develop` and run `watch-server` to run your processes. diff --git a/flake-module.nix b/flake-module.nix new file mode 100644 index 0000000..83981f4 --- /dev/null +++ b/flake-module.nix @@ -0,0 +1,87 @@ +{ self, lib, flake-parts-lib, ... }: +let + inherit (flake-parts-lib) + mkPerSystemOption; + inherit (lib) + mdDoc + mkOption + types + literalExpression; +in +{ + options = { + perSystem = mkPerSystemOption + ({ config, self', inputs', pkgs, system, ... }: { + options.process-compose = mkOption { + description = mdDoc '' + process-compose-flake: creates [process-compose](https://github.com/F1bonacc1/process-compose) + executables from process-compose configurations written as Nix attribute sets. + ''; + type = types.submodule { + options = { + package = mkOption { + type = types.package; + default = pkgs.process-compose; + }; + configs = mkOption { + type = types.attrsOf (pkgs.formats.yaml { }).type; + default = { }; + example = + # apps.${system}.watch-server and packages.${system}.watch-server become available + # execute `nix run .#watch-server` or incude packages.${system}.watch-server + # as a nativeBuildInput to your devShell + literalExpression '' + { + watch-server = { + processes = { + backend = "''${pkgs.simple-http-server}"; + frontend = "''${pkgs.simple-http-server}"; + }; + }; + }; + ''; + description = mdDoc '' + For each attribute `x = process-compose config` a flake app and package `x` is added to the flake. + Which runs process-compose with the declared config. + ''; + }; + }; + }; + }; + }); + }; + config = { + perSystem = { config, self', inputs', pkgs, ... }: + let + toYAMLFile = + attrs: + pkgs.runCommand "toYamlFile" { buildInputs = [ pkgs.yq-go ]; } '' + yq -P '.' ${pkgs.writeTextFile { name = "tmp.json"; text = (builtins.toJSON attrs); }} > $out + ''; + packages = pkgs.lib.mapAttrs + (name: processComposeConfig: + pkgs.writeShellApplication { + inherit name; + runtimeInputs = [ config.process-compose.package ]; + text = '' + process-compose -f ${toYAMLFile processComposeConfig} "$@" + ''; + } + ) + config.process-compose.configs; + in + { + inherit packages; + apps = pkgs.lib.mapAttrs' + (name: _: { + inherit name; + value = { + type = "app"; + program = packages.${name}; + }; + }) + config.process-compose.configs; + }; + }; +} + diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..1d342c2 --- /dev/null +++ b/flake.nix @@ -0,0 +1,5 @@ +{ + outputs = { self, ... }: { + flakeModule = ./flake-module.nix; + }; +}