<commit_before>{ config, lib, pkgs }:

with lib;

let
  cfg = config.systemd;
  lndir = "${pkgs.xorg.lndir}/bin/lndir";
in rec {

  shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s);

  mkPathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""];

  makeUnit = name: unit:
    if unit.enable then
      pkgs.runCommand "unit-${mkPathSafeName name}"
        { preferLocalBuild = true;
          allowSubstitutes = false;
          inherit (unit) text;
        }
        ''
          mkdir -p $out
          echo -n "$text" > $out/${shellEscape name}
        ''
    else
      pkgs.runCommand "unit-${mkPathSafeName name}-disabled"
        { preferLocalBuild = true;
          allowSubstitutes = false;
        }
        ''
          mkdir -p $out
          ln -s /dev/null $out/${shellEscape name}
        '';

  boolValues = [true false "yes" "no"];

  digits = map toString (range 0 9);

  isByteFormat = s:
    let
      l = reverseList (stringToCharacters s);
      suffix = head l;
      nums = tail l;
    in elem suffix (["K" "M" "G" "T"] ++ digits)
      && all (num: elem num digits) nums;

  assertByteFormat = name: group: attr:
    optional (attr ? ${name} && ! isByteFormat attr.${name})
      "Systemd ${group} field `${name}' must be in byte format [0-9]+[KMGT].";

  hexChars = stringToCharacters "0123456789abcdefABCDEF";

  isMacAddress = s: stringLength s == 17
    && flip all (splitString ":" s) (bytes:
      all (byte: elem byte hexChars) (stringToCharacters bytes)
    );

  assertMacAddress = name: group: attr:
    optional (attr ? ${name} && ! isMacAddress attr.${name})
      "Systemd ${group} field `${name}' must be a valid mac address.";

  isPort = i: i >= 0 && i <= 65535;

  assertPort = name: group: attr:
    optional (attr ? ${name} && ! isPort attr.${name})
      "Error on the systemd ${group} field `${name}': ${attr.name} is not a valid port number.";

  assertValueOneOf = name: values: group: attr:
    optional (attr ? ${name} && !elem attr.${name} values)
      "Systemd ${group} field `${name}' cannot have value `${toString attr.${name}}'.";

  assertHasField = name: group: attr:
    optional (!(attr ? ${name}))
      "Systemd ${group} field `${name}' must exist.";

  assertRange = name: min: max: group: attr:
    optional (attr ? ${name} && !(min <= attr.${name} && max >= attr.${name}))
      "Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]";

  assertMinimum = name: min: group: attr:
    optional (attr ? ${name} && attr.${name} < min)
      "Systemd ${group} field `${name}' must be greater than or equal to ${toString min}";

  assertOnlyFields = fields: group: attr:
    let badFields = filter (name: ! elem name fields) (attrNames attr); in
    optional (badFields != [ ])
      "Systemd ${group} has extra fields [${concatStringsSep " " badFields}].";

  assertInt = name: group: attr:
    optional (attr ? ${name} && !isInt attr.${name})
      "Systemd ${group} field `${name}' is not an integer";

  checkUnitConfig = group: checks: attrs: let
    # We're applied at the top-level type (attrsOf unitOption), so the actual
    # unit options might contain attributes from mkOverride that we need to
    # convert into single values before checking them.
    defs = mapAttrs (const (v:
      if v._type or "" == "override" then v.content else v
    )) attrs;
    errors = concatMap (c: c group defs) checks;
  in if errors == [] then true
     else builtins.trace (concatStringsSep "\n" errors) false;

  toOption = x:
    if x == true then "true"
    else if x == false then "false"
    else toString x;

  attrsToSection = as:
    concatStrings (concatLists (mapAttrsToList (name: value:
      map (x: ''
          ${name}=${toOption x}
        '')<commit_msg>nixos/systemd-lib: allow mkIf in unitOption<commit_after>{ config, lib, pkgs }:

with lib;

let
  cfg = config.systemd;
  lndir = "${pkgs.xorg.lndir}/bin/lndir";
in rec {

  shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s);

  mkPathSafeName = lib.replaceChars ["@" ":" "\\" "[" "]"] ["-" "-" "-" "" ""];

  makeUnit = name: unit:
    if unit.enable then
      pkgs.runCommand "unit-${mkPathSafeName name}"
        { preferLocalBuild = true;
          allowSubstitutes = false;
          inherit (unit) text;
        }
        ''
          mkdir -p $out
          echo -n "$text" > $out/${shellEscape name}
        ''
    else
      pkgs.runCommand "unit-${mkPathSafeName name}-disabled"
        { preferLocalBuild = true;
          allowSubstitutes = false;
        }
        ''
          mkdir -p $out
          ln -s /dev/null $out/${shellEscape name}
        '';

  boolValues = [true false "yes" "no"];

  digits = map toString (range 0 9);

  isByteFormat = s:
    let
      l = reverseList (stringToCharacters s);
      suffix = head l;
      nums = tail l;
    in elem suffix (["K" "M" "G" "T"] ++ digits)
      && all (num: elem num digits) nums;

  assertByteFormat = name: group: attr:
    optional (attr ? ${name} && ! isByteFormat attr.${name})
      "Systemd ${group} field `${name}' must be in byte format [0-9]+[KMGT].";

  hexChars = stringToCharacters "0123456789abcdefABCDEF";

  isMacAddress = s: stringLength s == 17
    && flip all (splitString ":" s) (bytes:
      all (byte: elem byte hexChars) (stringToCharacters bytes)
    );

  assertMacAddress = name: group: attr:
    optional (attr ? ${name} && ! isMacAddress attr.${name})
      "Systemd ${group} field `${name}' must be a valid mac address.";

  isPort = i: i >= 0 && i <= 65535;

  assertPort = name: group: attr:
    optional (attr ? ${name} && ! isPort attr.${name})
      "Error on the systemd ${group} field `${name}': ${attr.name} is not a valid port number.";

  assertValueOneOf = name: values: group: attr:
    optional (attr ? ${name} && !elem attr.${name} values)
      "Systemd ${group} field `${name}' cannot have value `${toString attr.${name}}'.";

  assertHasField = name: group: attr:
    optional (!(attr ? ${name}))
      "Systemd ${group} field `${name}' must exist.";

  assertRange = name: min: max: group: attr:
    optional (attr ? ${name} && !(min <= attr.${name} && max >= attr.${name}))
      "Systemd ${group} field `${name}' is outside the range [${toString min},${toString max}]";

  assertMinimum = name: min: group: attr:
    optional (attr ? ${name} && attr.${name} < min)
      "Systemd ${group} field `${name}' must be greater than or equal to ${toString min}";

  assertOnlyFields = fields: group: attr:
    let badFields = filter (name: ! elem name fields) (attrNames attr); in
    optional (badFields != [ ])
      "Systemd ${group} has extra fields [${concatStringsSep " " badFields}].";

  assertInt = name: group: attr:
    optional (attr ? ${name} && !isInt attr.${name})
      "Systemd ${group} field `${name}' is not an integer";

  checkUnitConfig = group: checks: attrs: let
    # We're applied at the top-level type (attrsOf unitOption), so the actual
    # unit options might contain attributes from mkOverride and mkIf that we need to
    # convert into single values before checking them.
    defs = mapAttrs (const (v:
      if v._type or "" == "override" then v.content
      else if v._type or "" == "if" then v.content
      else v
    )) attrs;
    errors = concatMap (c: c group defs) checks;
  in if errors == [] then true
     else builtins.trace (concatStringsSep "\n" errors) false;

  toOption = x:
    if x == true then "true"
    else if x == false then "false"
    else toString x;

  attrsToSection = as:
    concatStrings (concatLists (mapAttrsToList (name: value:
      map (x: ''
          ${name}=${toOption x}
        '')
{'fraction_non_alphanumeric': 0.15805272774732446, 'fraction_numerical': 0.005742625946228139, 'mean_word_length': 2.7785996055226825, 'pattern_counts': {'":': 4, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '964425', 'n_tokens_mistral': 2503, 'n_tokens_neox': 2413, 'n_words': 807}