Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow imperative usage with home-manager module #68

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 81 additions & 101 deletions module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,136 +4,116 @@ matugen: {
lib,
config,
...
} @ args: let
} @ inputs: let
cfg = config.programs.matugen;
osCfg = args.osConfig.programs.matugen or {};
osCfg = inputs.osConfig.programs.matugen or {};

configFormat = pkgs.formats.toml {};

capitalize = str: let
inherit (builtins) substring stringLength;
firstChar = substring 0 1 str;
restOfString = substring 1 (stringLength str) str;
in
lib.concatStrings [(lib.toUpper firstChar) restOfString];

# don't use ~, use $HOME
sanitizedTemplates =
builtins.mapAttrs (_: v: {
mode = capitalize cfg.variant;
input_path = builtins.toString v.input_path;
output_path = builtins.replaceStrings ["$HOME"] ["~"] v.output_path;
})
cfg.templates;

matugenConfig = configFormat.generate "matugen-config.toml" {
config = {};
templates = sanitizedTemplates;
};

# get matugen package
pkg = matugen.packages.${pkgs.system}.default;

themePackage = pkgs.runCommandLocal "matugen-themes-${cfg.variant}" {} ''
mkdir -p $out
cd $out
export HOME=$(pwd)

${pkg}/bin/matugen \
image ${cfg.wallpaper} \
${
if cfg.templates != {}
then "--config ${matugenConfig}"
else ""
} \
--mode ${cfg.variant} \
--type ${cfg.type} \
--json ${cfg.jsonFormat} \
--quiet \
> $out/theme.json
'';
colors = builtins.fromJSON (builtins.readFile "${themePackage}/theme.json");
tomlFormat = pkgs.formats.toml {};
in {
options.programs.matugen = {
enable = lib.mkEnableOption "Matugen declarative theming";

InioX marked this conversation as resolved.
Show resolved Hide resolved
package = lib.mkOption {
type = lib.types.package;
default = matugen.packages.${pkgs.system}.default;
description = "The matugen package to use";
};

extraPackages = lib.mkOption {
type = with lib.types; listOf package;
default = [];

example = lib.literalExpression ''with pkgs; [
sway # For swaymsg
glib # For gsettings
]'';
description = "Extra package available to matugen while generating templates";
};

wallpaper = lib.mkOption {
type = with lib.types; nullOr path;
default = osCfg.wallpaper or null;

example = "../wallpaper/astolfo.png";
description = "Path to `wallpaper` that matugen will generate the colorschemes from";
type = lib.types.path;
default = osCfg.wallpaper or "${pkgs.nixos-artwork.wallpapers.simple-blue}/share/backgrounds/nixos/nix-wallpaper-simple-blue.png";
defaultText = lib.literalExample ''
"${pkgs.nixos-artwork.wallpapers.simple-blue}/share/backgrounds/nixos/nix-wallpaper-simple-blue.png"
'';
};

templates = lib.mkOption {
type = with lib.types;
attrsOf (submodule {
type = with lib;
types.attrsOf (types.submodule {
options = {
input_path = lib.mkOption {
type = path;
description = "Path to the template";
input_path = mkOption {
type = types.path;

example = "./style.css";
description = "Path to the template";
};
output_path = lib.mkOption {
type = str;
description = "Path where the generated file will be written to";
example = "~/.config/sytle.css";
output_path = mkOption {
type = types.str;

example = ".config/style.css";
description = "Path relative to your homedirectory where the generated file will be written to";
};
};
});
default = osCfg.templates or {};

description = ''
Templates that have `@{placeholders}` which will be replaced by the respective colors.
See <https://github.com/InioX/matugen/wiki/Configuration#example-of-all-the-color-keywords> for a list of colors.
'';
};

type = lib.mkOption {
description = "Palette used when generating the colorschemes.";
type = lib.types.enum ["scheme-content" "scheme-expressive" "scheme-fidelity" "scheme-fruit-salad" "scheme-monochrome" "scheme-neutral" "scheme-rainbow" "scheme-tonal-spot"];
default = osCfg.palette or "scheme-tonal-spot";
example = "triadic";
};
settings = lib.mkOption {
inherit (tomlFormat) type;
default = osCfg.settings or {};

jsonFormat = lib.mkOption {
description = "Color format of the colorschemes.";
type = lib.types.enum ["rgb" "rgba" "hsl" "hsla" "hex" "strip"];
default = osCfg.jsonFormat or "strip";
example = "rgba";
};
example = ''
config.reload_apps_list = {
gtk_theme = true;
kitty = true;
}
'';
description = ''
Matugen configuration file in nix syntax.

variant = lib.mkOption {
description = "Colorscheme variant.";
type = lib.types.enum ["light" "dark" "amoled"];
default = osCfg.variant or "dark";
example = "light";
Written to {file}`$XDG_CONFIG_HOME/matugen/config.toml`
A manual for configuring matugen can be found at <https://github.com/InioX/matugen/wiki/Configuration>.
'';
};
};

theme.files = lib.mkOption {
type = lib.types.package;
readOnly = true;
default =
if builtins.hasAttr "templates" osCfg
then
if cfg.templates != osCfg.templates
then themePackage
else osCfg.theme.files
else themePackage;
description = "Generated theme files. Including only the variant chosen.";
config = let
package =
if cfg.extraPackages == []
then cfg.package
else pkgs.symlinkJoin {
name = "matugen-wrapped";
paths = [cfg.package];
buildInputs = [pkgs.makeWrapper];
postBuild = ''
wrapProgram $out/bin/matugen \
--prefix "PATH" ":" "${lib.makeBinPath cfg.extraPackages}"
'';
};
mergedCfg =
cfg.settings
// (
if cfg.templates != {}
then {inherit (cfg) templates;}
else {}
);

configFile = tomlFormat.generate "config.toml" mergedCfg;
in
lib.mkIf cfg.enable {
home.packages = [package];

home.activation.matugenCopyWallpapers = lib.hm.dag.entryAfter ["writeBoundary"] ''
${package}/bin/matugen image ${cfg.wallpaper} --config ${configFile}
'';

theme.colors = lib.mkOption {
inherit (pkgs.formats.json {}) type;
readOnly = true;
default =
if builtins.hasAttr "templates" osCfg
then
if cfg.templates != osCfg.templates
then colors
else osCfg.theme.colors
else colors;
description = "Generated theme colors. Includes all variants.";
xdg.configFile."matugen/config.toml".source =
lib.mkIf (mergedCfg != {}) configFile;
};
};
}
36 changes: 18 additions & 18 deletions src/util/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ impl Template {
(template.input_path.try_resolve()?.to_path_buf(), template.output_path.try_resolve()?.to_path_buf())
};

let output_path = if path_prefix.is_some() && !cfg!(windows) {
let prefix_path = PathBuf::from(path_prefix.as_ref().unwrap());
rebase(&output_path_absolute, &prefix_path, None)
.expect("failed to rebase output path")
} else {
output_path_absolute.to_path_buf()
};
debug!("out: {:?}", output_path);

if template.hook.is_some() {
format_hook(template, &engine, &mut render_data)?;
}
Expand All @@ -212,10 +221,10 @@ impl Template {
debug!(
"Trying to write the {} template to {}",
name,
output_path_absolute.display()
output_path.display()
);

let parent_folder = &output_path_absolute
let parent_folder = &output_path
.parent()
.wrap_err("Could not get the parent of the output path.")?;

Expand All @@ -227,16 +236,15 @@ impl Template {
debug!("{}", parent_folder.display());
let _ = create_dir_all(parent_folder).wrap_err(format!(
"Failed to create the {} folders.",
&output_path_absolute.display()
&output_path.display()
));
}

export_template(
&engine,
name,
&render_data,
path_prefix,
output_path_absolute,
output_path,
input_path_absolute,
i,
templates,
Expand All @@ -250,8 +258,7 @@ fn export_template(
engine: &Engine,
name: &String,
render_data: &Value,
path_prefix: &Option<PathBuf>,
output_path_absolute: PathBuf,
output_path: PathBuf,
input_path_absolute: PathBuf,
i: usize,
templates: &HashMap<String, Template>,
Expand All @@ -270,23 +277,16 @@ fn export_template(

Report::new(error).wrap_err(message)
})?;
let out = if path_prefix.is_some() && !cfg!(windows) {
let prefix_path = PathBuf::from(path_prefix.as_ref().unwrap());
rebase(&output_path_absolute, &prefix_path, None)
.expect("failed to rebase output path")
} else {
output_path_absolute.to_path_buf()
};
debug!("out: {:?}", out);

let mut output_file = OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(out)?;
.open(&output_path)?;
if output_file.metadata()?.permissions().readonly() {
error!(
"The <b><red>{}</> file is Read-Only",
&output_path_absolute.display()
&output_path.display()
);
}
output_file.write_all(data.as_bytes())?;
Expand All @@ -295,7 +295,7 @@ fn export_template(
i + 1,
&templates.len(),
name,
output_path_absolute.display()
output_path.display()
);
Ok(())
}
Expand Down