mirror of
				https://github.com/RGBCube/hjem
				synced 2025-10-31 05:32:44 +00:00 
			
		
		
		
	Merge pull request #44 from feel-co/generator
feat: add config generator options
This commit is contained in:
		
						commit
						a1a2680af8
					
				
					 4 changed files with 100 additions and 16 deletions
				
			
		|  | @ -49,6 +49,15 @@ may use to manage individual users' homes by leveraging the module system. | ||||||
|       # This can be used to generate config files with various |       # This can be used to generate config files with various | ||||||
|       # formats expected by different programs. |       # formats expected by different programs. | ||||||
|       ".config/bar".source = pkgs.writeTextFile "file-foo" "file contents"; |       ".config/bar".source = pkgs.writeTextFile "file-foo" "file contents"; | ||||||
|  | 
 | ||||||
|  |       # You can also use generators to transform Nix values | ||||||
|  |       ".config/baz" = { | ||||||
|  |         # Works with `pkgs.formats` too! | ||||||
|  |         generator = lib.generators.toJSON { }; | ||||||
|  |         value = { | ||||||
|  |           some = "contents"; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								flake.nix
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								flake.nix
									
										
									
									
									
								
							|  | @ -28,7 +28,7 @@ | ||||||
|     packages = forAllSystems (system: { |     packages = forAllSystems (system: { | ||||||
|       # Expose the 'smfh' instance used by Hjem as a package in the Hjem flake |       # Expose the 'smfh' instance used by Hjem as a package in the Hjem flake | ||||||
|       # outputs. This allows consuming the exact copy of smfh used by Hjem. |       # outputs. This allows consuming the exact copy of smfh used by Hjem. | ||||||
|       smfh = inputs.smfh.packages.${system}.smfh; |       inherit (inputs.smfh.packages.${system}) smfh; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     checks = forAllSystems (system: let |     checks = forAllSystems (system: let | ||||||
|  | @ -56,6 +56,8 @@ | ||||||
|         packages = attrValues { |         packages = attrValues { | ||||||
|           inherit |           inherit | ||||||
|             (pkgs) |             (pkgs) | ||||||
|  |             # formatter | ||||||
|  |             alejandra | ||||||
|             # cue validator |             # cue validator | ||||||
|             cue |             cue | ||||||
|             go |             go | ||||||
|  | @ -64,6 +66,22 @@ | ||||||
|       }; |       }; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.alejandra); |     formatter = forAllSystems ( | ||||||
|  |       system: let | ||||||
|  |         pkgs = nixpkgs.legacyPackages.${system}; | ||||||
|  |       in | ||||||
|  |         pkgs.writeShellApplication { | ||||||
|  |           name = "nix3-fmt-wrapper"; | ||||||
|  | 
 | ||||||
|  |           runtimeInputs = [ | ||||||
|  |             pkgs.alejandra | ||||||
|  |             pkgs.fd | ||||||
|  |           ]; | ||||||
|  | 
 | ||||||
|  |           text = '' | ||||||
|  |             fd "$@" -t f -e nix -x alejandra -q '{}' | ||||||
|  |           ''; | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -9,11 +9,11 @@ | ||||||
|   ... |   ... | ||||||
| }: let | }: let | ||||||
|   inherit (lib.attrsets) mapAttrsToList; |   inherit (lib.attrsets) mapAttrsToList; | ||||||
|   inherit (lib.strings) concatMapStringsSep concatLines; |   inherit (lib.strings) concatLines concatMapStringsSep; | ||||||
|   inherit (lib.modules) mkIf mkDefault mkDerivedConfig; |   inherit (lib.modules) mkDefault mkDerivedConfig mkIf mkMerge; | ||||||
|   inherit (lib.options) mkOption literalExpression mkEnableOption; |   inherit (lib.options) literalExpression mkEnableOption mkOption; | ||||||
|   inherit (lib.strings) hasPrefix; |   inherit (lib.strings) hasPrefix; | ||||||
|   inherit (lib.types) attrsOf bool lines listOf nullOr package path str submodule oneOf int; |   inherit (lib.types) addCheck anything attrsOf bool either functionTo int lines listOf nullOr package path str submodule oneOf; | ||||||
|   inherit (builtins) isList; |   inherit (builtins) isList; | ||||||
| 
 | 
 | ||||||
|   cfg = config; |   cfg = config; | ||||||
|  | @ -58,6 +58,32 @@ | ||||||
|           description = "Path of the source file or directory"; |           description = "Path of the source file or directory"; | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         generator = lib.mkOption { | ||||||
|  |           # functionTo doesn't actually check the return type, so do that ourselves | ||||||
|  |           type = addCheck (nullOr (functionTo (either options.source.type options.text.type))) (x: let | ||||||
|  |             generatedValue = x config.value; | ||||||
|  |             generatesDrv = options.source.type.check generatedValue; | ||||||
|  |             generatesStr = options.text.type.check generatedValue; | ||||||
|  |           in | ||||||
|  |             x != null -> (generatesDrv || generatesStr)); | ||||||
|  |           default = null; | ||||||
|  |           description = '' | ||||||
|  |             Function that when applied to `value` will create the `source` or `text` of the file. | ||||||
|  | 
 | ||||||
|  |             Detection is automatic, as we check if the `generator` generates a derivation or a string after applying to `value`. | ||||||
|  |           ''; | ||||||
|  |           example = literalExpression "lib.generators.toGitINI"; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         value = lib.mkOption { | ||||||
|  |           type = nullOr (attrsOf anything); | ||||||
|  |           default = null; | ||||||
|  |           description = "Value passed to the `generator`."; | ||||||
|  |           example = { | ||||||
|  |             user.email = "me@example.com"; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|         executable = mkOption { |         executable = mkOption { | ||||||
|           type = bool; |           type = bool; | ||||||
|           default = false; |           default = false; | ||||||
|  | @ -90,14 +116,30 @@ | ||||||
|         }; |         }; | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       config = { |       config = let | ||||||
|  |         generatedValue = config.generator config.value; | ||||||
|  |         hasGenerator = config.generator != null; | ||||||
|  |         generatesDrv = options.source.type.check generatedValue; | ||||||
|  |         generatesStr = options.text.type.check generatedValue; | ||||||
|  |       in | ||||||
|  |         mkMerge [ | ||||||
|  |           { | ||||||
|             target = mkDefault name; |             target = mkDefault name; | ||||||
|             source = mkIf (config.text != null) (mkDerivedConfig options.text (text: |             source = mkIf (config.text != null) (mkDerivedConfig options.text (text: | ||||||
|               pkgs.writeTextFile { |               pkgs.writeTextFile { | ||||||
|                 inherit name text; |                 inherit name text; | ||||||
|                 inherit (config) executable; |                 inherit (config) executable; | ||||||
|               })); |               })); | ||||||
|       }; |           } | ||||||
|  | 
 | ||||||
|  |           (lib.mkIf (hasGenerator && generatesDrv) { | ||||||
|  |             source = mkDefault generatedValue; | ||||||
|  |           }) | ||||||
|  | 
 | ||||||
|  |           (lib.mkIf (hasGenerator && generatesStr) { | ||||||
|  |             text = mkDefault generatedValue; | ||||||
|  |           }) | ||||||
|  |         ]; | ||||||
|     }); |     }); | ||||||
| in { | in { | ||||||
|   imports = [ |   imports = [ | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ in | ||||||
|     nodes = { |     nodes = { | ||||||
|       node1 = { |       node1 = { | ||||||
|         self, |         self, | ||||||
|  |         lib, | ||||||
|         pkgs, |         pkgs, | ||||||
|         ... |         ... | ||||||
|       }: { |       }: { | ||||||
|  | @ -22,9 +23,21 @@ in | ||||||
|           alice = { |           alice = { | ||||||
|             enable = true; |             enable = true; | ||||||
|             packages = [pkgs.hello]; |             packages = [pkgs.hello]; | ||||||
|             files.".config/foo" = { |             files = { | ||||||
|  |               ".config/foo" = { | ||||||
|                 text = "Hello world!"; |                 text = "Hello world!"; | ||||||
|               }; |               }; | ||||||
|  | 
 | ||||||
|  |               ".config/bar.json" = { | ||||||
|  |                 generator = lib.generators.toJSON {}; | ||||||
|  |                 value = {bar = true;}; | ||||||
|  |               }; | ||||||
|  | 
 | ||||||
|  |               ".config/baz.toml" = { | ||||||
|  |                 generator = (pkgs.formats.toml {}).generate "baz.toml"; | ||||||
|  |                 value = {baz = true;}; | ||||||
|  |               }; | ||||||
|  |             }; | ||||||
|           }; |           }; | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  | @ -47,6 +60,8 @@ in | ||||||
| 
 | 
 | ||||||
|       # Test file created by Hjem |       # Test file created by Hjem | ||||||
|       machine.succeed("[ -L ~alice/.config/foo ]") |       machine.succeed("[ -L ~alice/.config/foo ]") | ||||||
|  |       machine.succeed("[ -L ~alice/.config/bar.json ]") | ||||||
|  |       machine.succeed("[ -L ~alice/.config/baz.toml ]") | ||||||
| 
 | 
 | ||||||
|       # Test regular files, created by systemd-tmpfiles |       # Test regular files, created by systemd-tmpfiles | ||||||
|       machine.succeed("[ -d ~alice/user_tmpfiles_created ]") |       machine.succeed("[ -d ~alice/user_tmpfiles_created ]") | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 éclairevoyant
						éclairevoyant