From dafc50056e4ce16b0504abebc2587df388cd4694 Mon Sep 17 00:00:00 2001 From: Kevin Amado Date: Sat, 23 Nov 2024 14:39:03 -0700 Subject: [PATCH] feat: rebase Vladimir's pr --- src/alejandra/src/builder.rs | 5 +- src/alejandra/src/config.rs | 7 +- src/alejandra/src/format.rs | 3 +- src/alejandra/tests/cases/apply/out-tabs.nix | 114 ++ src/alejandra/tests/cases/assert/out-tabs.nix | 44 + .../tests/cases/attr_set/out-tabs.nix | 138 ++ src/alejandra/tests/cases/bin_op/out-tabs.nix | 49 + .../tests/cases/comment/out-tabs.nix | 115 ++ .../tests/cases/dynamic/out-tabs.nix | 16 + src/alejandra/tests/cases/error/out-tabs.nix | 1 + src/alejandra/tests/cases/idioms/out-tabs.nix | 19 + .../tests/cases/idioms_lib_1/out-tabs.nix | 12 + .../tests/cases/idioms_lib_2/out-tabs.nix | 539 ++++++++ .../tests/cases/idioms_nixos_1/out-tabs.nix | 380 ++++++ .../tests/cases/idioms_pkgs_1/out-tabs.nix | 18 + .../tests/cases/idioms_pkgs_2/out-tabs.nix | 44 + .../tests/cases/idioms_pkgs_3/out-tabs.nix | 380 ++++++ .../tests/cases/if_else/out-tabs.nix | 286 +++++ .../tests/cases/inherit/out-tabs.nix | 103 ++ .../cases/inherit_blank_trailing/out-tabs.nix | 31 + .../tests/cases/inherit_comment/out-tabs.nix | 7 + .../tests/cases/inherit_from/out-tabs.nix | 1116 ++++++++++++++++ .../tests/cases/key_value/out-tabs.nix | 120 ++ src/alejandra/tests/cases/lambda/out-tabs.nix | 71 ++ src/alejandra/tests/cases/let_in/out-tabs.nix | 92 ++ src/alejandra/tests/cases/lists/out-tabs.nix | 96 ++ .../tests/cases/monsters_1/out-tabs.nix | 255 ++++ .../tests/cases/monsters_2/out-tabs.nix | 30 + .../tests/cases/monsters_3/out-tabs.nix | 64 + .../tests/cases/monsters_4/out-tabs.nix | 516 ++++++++ .../tests/cases/monsters_5/out-tabs.nix | 130 ++ .../tests/cases/or_default/out-tabs.nix | 48 + src/alejandra/tests/cases/paren/out-tabs.nix | 165 +++ .../tests/cases/pat_bind/out-tabs.nix | 33 + .../tests/cases/pattern/out-tabs.nix | 1123 +++++++++++++++++ src/alejandra/tests/cases/root/out-tabs.nix | 12 + src/alejandra/tests/cases/select/out-tabs.nix | 55 + src/alejandra/tests/cases/string/out-tabs.nix | 91 ++ .../tests/cases/string_interpol/out-tabs.nix | 14 + src/alejandra/tests/cases/with/out-tabs.nix | 69 + src/alejandra/tests/fmt.rs | 8 +- src/alejandra_cli/src/config_options.rs | 12 +- 42 files changed, 6420 insertions(+), 11 deletions(-) create mode 100644 src/alejandra/tests/cases/apply/out-tabs.nix create mode 100644 src/alejandra/tests/cases/assert/out-tabs.nix create mode 100644 src/alejandra/tests/cases/attr_set/out-tabs.nix create mode 100644 src/alejandra/tests/cases/bin_op/out-tabs.nix create mode 100644 src/alejandra/tests/cases/comment/out-tabs.nix create mode 100644 src/alejandra/tests/cases/dynamic/out-tabs.nix create mode 100644 src/alejandra/tests/cases/error/out-tabs.nix create mode 100644 src/alejandra/tests/cases/idioms/out-tabs.nix create mode 100644 src/alejandra/tests/cases/idioms_lib_1/out-tabs.nix create mode 100644 src/alejandra/tests/cases/idioms_lib_2/out-tabs.nix create mode 100644 src/alejandra/tests/cases/idioms_nixos_1/out-tabs.nix create mode 100644 src/alejandra/tests/cases/idioms_pkgs_1/out-tabs.nix create mode 100644 src/alejandra/tests/cases/idioms_pkgs_2/out-tabs.nix create mode 100644 src/alejandra/tests/cases/idioms_pkgs_3/out-tabs.nix create mode 100644 src/alejandra/tests/cases/if_else/out-tabs.nix create mode 100644 src/alejandra/tests/cases/inherit/out-tabs.nix create mode 100644 src/alejandra/tests/cases/inherit_blank_trailing/out-tabs.nix create mode 100644 src/alejandra/tests/cases/inherit_comment/out-tabs.nix create mode 100644 src/alejandra/tests/cases/inherit_from/out-tabs.nix create mode 100644 src/alejandra/tests/cases/key_value/out-tabs.nix create mode 100644 src/alejandra/tests/cases/lambda/out-tabs.nix create mode 100644 src/alejandra/tests/cases/let_in/out-tabs.nix create mode 100644 src/alejandra/tests/cases/lists/out-tabs.nix create mode 100644 src/alejandra/tests/cases/monsters_1/out-tabs.nix create mode 100644 src/alejandra/tests/cases/monsters_2/out-tabs.nix create mode 100644 src/alejandra/tests/cases/monsters_3/out-tabs.nix create mode 100644 src/alejandra/tests/cases/monsters_4/out-tabs.nix create mode 100644 src/alejandra/tests/cases/monsters_5/out-tabs.nix create mode 100644 src/alejandra/tests/cases/or_default/out-tabs.nix create mode 100644 src/alejandra/tests/cases/paren/out-tabs.nix create mode 100644 src/alejandra/tests/cases/pat_bind/out-tabs.nix create mode 100644 src/alejandra/tests/cases/pattern/out-tabs.nix create mode 100644 src/alejandra/tests/cases/root/out-tabs.nix create mode 100644 src/alejandra/tests/cases/select/out-tabs.nix create mode 100644 src/alejandra/tests/cases/string/out-tabs.nix create mode 100644 src/alejandra/tests/cases/string_interpol/out-tabs.nix create mode 100644 src/alejandra/tests/cases/with/out-tabs.nix diff --git a/src/alejandra/src/builder.rs b/src/alejandra/src/builder.rs index a4554643..216d42f7 100644 --- a/src/alejandra/src/builder.rs +++ b/src/alejandra/src/builder.rs @@ -15,14 +15,13 @@ pub(crate) enum Step { #[derive(Clone)] pub(crate) struct BuildCtx { - pub _config: Config, + pub config: Config, pub force_wide: bool, pub force_wide_success: bool, pub indentation: usize, pub pos_old: crate::position::Position, pub path: String, pub vertical: bool, - pub indent: String, } pub(crate) fn build( @@ -100,7 +99,7 @@ fn build_step( add_token( builder, rnix::SyntaxKind::TOKEN_WHITESPACE, - &build_ctx.indent.repeat(build_ctx.indentation), + &build_ctx.config.indentation.repeat(build_ctx.indentation), ); } } diff --git a/src/alejandra/src/config.rs b/src/alejandra/src/config.rs index 5e659d3e..e7c11642 100644 --- a/src/alejandra/src/config.rs +++ b/src/alejandra/src/config.rs @@ -1,11 +1,14 @@ /// Configuration used by the formatter #[derive(Clone)] -pub struct Config {} +pub struct Config { + /// Indentation to use, e.g. `" "` (two spaces). + pub indentation: String, +} use std::default::Default; impl Default for Config { fn default() -> Self { - Self {} + Self { indentation: String::from(" ") } } } diff --git a/src/alejandra/src/format.rs b/src/alejandra/src/format.rs index 3bec33ed..dd3e89a9 100644 --- a/src/alejandra/src/format.rs +++ b/src/alejandra/src/format.rs @@ -32,14 +32,13 @@ pub fn in_memory( } let mut build_ctx = crate::builder::BuildCtx { - _config: config, + config, force_wide: false, force_wide_success: true, indentation: 0, path, pos_old: crate::position::Position::default(), vertical: true, - indent, }; let after = crate::builder::build(&mut build_ctx, ast.node().into()) diff --git a/src/alejandra/tests/cases/apply/out-tabs.nix b/src/alejandra/tests/cases/apply/out-tabs.nix new file mode 100644 index 00000000..a9a86e55 --- /dev/null +++ b/src/alejandra/tests/cases/apply/out-tabs.nix @@ -0,0 +1,114 @@ +[ + (a + b) + ( + (a b) + (a b) + (a + /* + b + */ + c) + ( + /* + a + */ + b + /* + c + */ + d + /* + e + */ + ) + ) + '' + otherModules=${ + pkgs.writeText "other-modules.json" + (l.toJSON + (l.mapAttrs + (pname: subOutputs: let + pkg = + subOutputs.packages."${pname}".overrideAttrs (old: { + buildScript = "true"; + installMethod = "copy"; + }); + in "${pkg}/lib/node_modules/${pname}/node_modules") + outputs.subPackages)) + } + '' + { + name1 = + function + arg + {asdf = 1;}; + + name2 = + function + arg + {asdf = 1;} + argument; + + name3 = + function + arg + {asdf = 1;} + {qwer = 12345;} + argument; + } + { + name1 = + function arg { + asdf = 1; + }; + + name2 = + function arg { + asdf = 1; + } + argument; + + name3 = + function arg { + asdf = 1; + } { + qwer = 12345; + } + argument; + } + { + name4 = + function + arg + {asdf = 1;} + { + qwer = 12345; + qwer2 = 54321; + } + argument; + } + { + option1 = + function arg {asdf = 1;} { + qwer = 12345; + qwer2 = 54321; + } + lastArg; + + option2 = + function arg {asdf = 1;} { + qwer = 12345; + qwer2 = 54321; + } + lastArg; + + option3 = + function arg {asdf = 1;} + { + qwer = 12345; + qwer2 = 54321; + } + lastArg; + } +] diff --git a/src/alejandra/tests/cases/assert/out-tabs.nix b/src/alejandra/tests/cases/assert/out-tabs.nix new file mode 100644 index 00000000..9a8f2c35 --- /dev/null +++ b/src/alejandra/tests/cases/assert/out-tabs.nix @@ -0,0 +1,44 @@ +[ + (assert b; e) + (assert b; + /* + d + */ + e) + (assert b; e) + (assert b; + /* + d + */ + e) + (assert + /* + a + */ + b; e) + (assert + /* + a + */ + b; + /* + d + */ + e) + (assert + /* + a + */ + b; e) + (assert + /* + a + */ + b; + /* + d + */ + e) + (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) + (assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) +] diff --git a/src/alejandra/tests/cases/attr_set/out-tabs.nix b/src/alejandra/tests/cases/attr_set/out-tabs.nix new file mode 100644 index 00000000..fbf6a29b --- /dev/null +++ b/src/alejandra/tests/cases/attr_set/out-tabs.nix @@ -0,0 +1,138 @@ +[ + {} + { + /* + a + */ + } + {a = 1;} + { + a = 1; + } + + {b = 1;} + { + b = 1; + /* + c + */ + } + { + /* + a + */ + b = 1; + } + { + /* + a + */ + b = 1; + /* + c + */ + } + + rec {c = 1;} + rec { + c = 1; + /* + d + */ + } + rec { + /* + b + */ + c = 1; + } + rec { + /* + b + */ + c = 1; + /* + d + */ + } + rec + /* + a + */ + { + c = 1; + } + rec + /* + a + */ + { + c = 1; + /* + d + */ + } + rec + /* + a + */ + { + /* + b + */ + c = 1; + } + rec + /* + a + */ + { + /* + b + */ + c = 1; + /* + d + */ + } + + { + a = rec { + a = { + a = rec { + a = { + a = rec {a = {a = rec {a = {a = rec {a = {};};};};};}; + }; + }; + }; + }; + } + + rec { + c = 1; + + e = 1; + } + + rec + /* + a + */ + { + /* + b + */ + + c = 1; + + /* + d + */ + + e = 1; + + /* + f + */ + } +] diff --git a/src/alejandra/tests/cases/bin_op/out-tabs.nix b/src/alejandra/tests/cases/bin_op/out-tabs.nix new file mode 100644 index 00000000..eb60f024 --- /dev/null +++ b/src/alejandra/tests/cases/bin_op/out-tabs.nix @@ -0,0 +1,49 @@ +[ + (1 + 1) + (1 + + + /**/ + 1) + (1 + /**/ + + 1) + (1 + /**/ + + + /**/ + 1) + (1 + /**/ + + + /**/ + (1 + /**/ + + + /**/ + (1 + /**/ + + + /**/ + 1))) + (1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1) + (1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1) +] diff --git a/src/alejandra/tests/cases/comment/out-tabs.nix b/src/alejandra/tests/cases/comment/out-tabs.nix new file mode 100644 index 00000000..d59e41b6 --- /dev/null +++ b/src/alejandra/tests/cases/comment/out-tabs.nix @@ -0,0 +1,115 @@ +[ + /**/ + /**/ + + /**/ + + /**/ + + /**/ + + /**/ + + /* + @ + */ + + /** + @ + */ + + /** + @ + @ + @ + */ + + /***/ + + /** + @ + * + */ + + /* + @ + @ + @ + */ + + /* + @ + @ + @ + */ + + /* + @ + @ + @ + */ + + /* + @ + @ + @ + */ + + /* + test + * test + */ + + [ + # 1 + #2 + a # 3 + b + c # 4 + #5 + + #6 + + d + #7 + ] + + { + a = 123; # comment + } + + { + # 1 + #2 + a = 1; # 3 + b = 1; + c = 1; # 4 + #5 + + #6 + + d = 1; + #7 + } + + (let + # 1 + #2 + a = 1; # 3 + b = 1; + c = 1; # 4 + #5 + + #6 + + d = 1; + #7 + in + d) + + ({ + a, # comment + b ? 2, # comment + }: + _) +] diff --git a/src/alejandra/tests/cases/dynamic/out-tabs.nix b/src/alejandra/tests/cases/dynamic/out-tabs.nix new file mode 100644 index 00000000..eaae9a97 --- /dev/null +++ b/src/alejandra/tests/cases/dynamic/out-tabs.nix @@ -0,0 +1,16 @@ +a +.${ + /* + b + */ + c + .${ + /* + d + */ + e.${f} + } + /* + g + */ +} diff --git a/src/alejandra/tests/cases/error/out-tabs.nix b/src/alejandra/tests/cases/error/out-tabs.nix new file mode 100644 index 00000000..471697a4 --- /dev/null +++ b/src/alejandra/tests/cases/error/out-tabs.nix @@ -0,0 +1 @@ +;-) diff --git a/src/alejandra/tests/cases/idioms/out-tabs.nix b/src/alejandra/tests/cases/idioms/out-tabs.nix new file mode 100644 index 00000000..13ed7b5c --- /dev/null +++ b/src/alejandra/tests/cases/idioms/out-tabs.nix @@ -0,0 +1,19 @@ +[ + { + meta = with lib; { + a = 1; + b = 2; + c = 3; + }; + } + + { + meta = with lib; + # comment + { + a = 1; + b = 2; + c = 3; + }; + } +] diff --git a/src/alejandra/tests/cases/idioms_lib_1/out-tabs.nix b/src/alejandra/tests/cases/idioms_lib_1/out-tabs.nix new file mode 100644 index 00000000..f427858e --- /dev/null +++ b/src/alejandra/tests/cases/idioms_lib_1/out-tabs.nix @@ -0,0 +1,12 @@ +{ + traceIf = + # Predicate to check + pred: + # Message that should be traced + msg: + # Value to return + x: + if pred + then trace msg x + else x; +} diff --git a/src/alejandra/tests/cases/idioms_lib_2/out-tabs.nix b/src/alejandra/tests/cases/idioms_lib_2/out-tabs.nix new file mode 100644 index 00000000..a1d572b6 --- /dev/null +++ b/src/alejandra/tests/cases/idioms_lib_2/out-tabs.nix @@ -0,0 +1,539 @@ +{lib}: rec { + ## Simple (higher order) functions + + /* + The identity function + For when you need a function that does “nothing”. + + Type: id :: a -> a + */ + id = + # The value to return + x: x; + + /* + The constant function + + Ignores the second argument. If called with only one argument, + constructs a function that always returns a static value. + + Type: const :: a -> b -> a + Example: + let f = const 5; in f 10 + => 5 + */ + const = + # Value to return + x: + # Value to ignore + y: x; + + /* + Pipes a value through a list of functions, left to right. + + Type: pipe :: a -> [] -> + Example: + pipe 2 [ + (x: x + 2) # 2 + 2 = 4 + (x: x * 2) # 4 * 2 = 8 + ] + => 8 + + # ideal to do text transformations + pipe [ "a/b" "a/c" ] [ + + # create the cp command + (map (file: ''cp "${src}/${file}" $out\n'')) + + # concatenate all commands into one string + lib.concatStrings + + # make that string into a nix derivation + (pkgs.runCommand "copy-to-out" {}) + + ] + => + + The output type of each function has to be the input type + of the next function, and the last function returns the + final value. + */ + pipe = val: functions: let + reverseApply = x: f: f x; + in + builtins.foldl' reverseApply val functions; + + # note please don’t add a function like `compose = flip pipe`. + # This would confuse users, because the order of the functions + # in the list is not clear. With pipe, it’s obvious that it + # goes first-to-last. With `compose`, not so much. + + ## Named versions corresponding to some builtin operators. + + /* + Concatenate two lists + + Type: concat :: [a] -> [a] -> [a] + + Example: + concat [ 1 2 ] [ 3 4 ] + => [ 1 2 3 4 ] + */ + concat = x: y: x ++ y; + + /* + boolean “or” + */ + or = x: y: x || y; + + /* + boolean “and” + */ + and = x: y: x && y; + + /* + bitwise “and” + */ + bitAnd = + builtins.bitAnd + or (import ./zip-int-bits.nix + (a: b: + if a == 1 && b == 1 + then 1 + else 0)); + + /* + bitwise “or” + */ + bitOr = + builtins.bitOr + or (import ./zip-int-bits.nix + (a: b: + if a == 1 || b == 1 + then 1 + else 0)); + + /* + bitwise “xor” + */ + bitXor = + builtins.bitXor + or (import ./zip-int-bits.nix + (a: b: + if a != b + then 1 + else 0)); + + /* + bitwise “not” + */ + bitNot = builtins.sub (-1); + + /* + Convert a boolean to a string. + + This function uses the strings "true" and "false" to represent + boolean values. Calling `toString` on a bool instead returns "1" + and "" (sic!). + + Type: boolToString :: bool -> string + */ + boolToString = b: + if b + then "true" + else "false"; + + /* + Merge two attribute sets shallowly, right side trumps left + + mergeAttrs :: attrs -> attrs -> attrs + + Example: + mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; } + => { a = 1; b = 3; c = 4; } + */ + mergeAttrs = + # Left attribute set + x: + # Right attribute set (higher precedence for equal keys) + y: x // y; + + /* + Flip the order of the arguments of a binary function. + + Type: flip :: (a -> b -> c) -> (b -> a -> c) + + Example: + flip concat [1] [2] + => [ 2 1 ] + */ + flip = f: a: b: f b a; + + /* + Apply function if the supplied argument is non-null. + + Example: + mapNullable (x: x+1) null + => null + mapNullable (x: x+1) 22 + => 23 + */ + mapNullable = + # Function to call + f: + # Argument to check for null before passing it to `f` + a: + if a == null + then a + else f a; + + # Pull in some builtins not included elsewhere. + inherit + (builtins) + pathExists + readFile + isBool + isInt + isFloat + add + sub + lessThan + seq + deepSeq + genericClosure + ; + + ## nixpkgs version strings + + /* + Returns the current full nixpkgs version number. + */ + version = release + versionSuffix; + + /* + Returns the current nixpkgs release number as string. + */ + release = lib.strings.fileContents ../.version; + + /* + Returns the current nixpkgs release code name. + + On each release the first letter is bumped and a new animal is chosen + starting with that new letter. + */ + codeName = "Quokka"; + + /* + Returns the current nixpkgs version suffix as string. + */ + versionSuffix = let + suffixFile = ../.version-suffix; + in + if pathExists suffixFile + then lib.strings.fileContents suffixFile + else "pre-git"; + + /* + Attempts to return the the current revision of nixpkgs and + returns the supplied default value otherwise. + + Type: revisionWithDefault :: string -> string + */ + revisionWithDefault = + # Default value to return if revision can not be determined + default: let + revisionFile = "${toString ./..}/.git-revision"; + gitRepo = "${toString ./..}/.git"; + in + if lib.pathIsGitRepo gitRepo + then lib.commitIdFromGitRepo gitRepo + else if lib.pathExists revisionFile + then lib.fileContents revisionFile + else default; + + nixpkgsVersion = builtins.trace "`lib.nixpkgsVersion` is deprecated, use `lib.version` instead!" version; + + /* + Determine whether the function is being called from inside a Nix + shell. + + Type: inNixShell :: bool + */ + inNixShell = builtins.getEnv "IN_NIX_SHELL" != ""; + + ## Integer operations + + /* + Return minimum of two numbers. + */ + min = x: y: + if x < y + then x + else y; + + /* + Return maximum of two numbers. + */ + max = x: y: + if x > y + then x + else y; + + /* + Integer modulus + + Example: + mod 11 10 + => 1 + mod 1 10 + => 1 + */ + mod = base: int: base - (int * (builtins.div base int)); + + ## Comparisons + + /* + C-style comparisons + + a < b, compare a b => -1 + a == b, compare a b => 0 + a > b, compare a b => 1 + */ + compare = a: b: + if a < b + then -1 + else if a > b + then 1 + else 0; + + /* + Split type into two subtypes by predicate `p`, take all elements + of the first subtype to be less than all the elements of the + second subtype, compare elements of a single subtype with `yes` + and `no` respectively. + + Type: (a -> bool) -> (a -> a -> int) -> (a -> a -> int) -> (a -> a -> int) + + Example: + let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in + + cmp "a" "z" => -1 + cmp "fooa" "fooz" => -1 + + cmp "f" "a" => 1 + cmp "fooa" "a" => -1 + # while + compare "fooa" "a" => 1 + */ + splitByAndCompare = + # Predicate + p: + # Comparison function if predicate holds for both values + yes: + # Comparison function if predicate holds for neither value + no: + # First value to compare + a: + # Second value to compare + b: + if p a + then + if p b + then yes a b + else -1 + else if p b + then 1 + else no a b; + + /* + Reads a JSON file. + + Type :: path -> any + */ + importJSON = path: + builtins.fromJSON (builtins.readFile path); + + /* + Reads a TOML file. + + Type :: path -> any + */ + importTOML = path: + builtins.fromTOML (builtins.readFile path); + + ## Warnings + + # See https://github.com/NixOS/nix/issues/749. Eventually we'd like these + # to expand to Nix builtins that carry metadata so that Nix can filter out + # the INFO messages without parsing the message string. + # + # Usage: + # { + # foo = lib.warn "foo is deprecated" oldFoo; + # bar = lib.warnIf (bar == "") "Empty bar is deprecated" bar; + # } + # + # TODO: figure out a clever way to integrate location information from + # something like __unsafeGetAttrPos. + + /* + Print a warning before returning the second argument. This function behaves + like `builtins.trace`, but requires a string message and formats it as a + warning, including the `warning: ` prefix. + + To get a call stack trace and abort evaluation, set the environment variable + `NIX_ABORT_ON_WARN=true` and set the Nix options `--option pure-eval false --show-trace` + + Type: string -> a -> a + */ + warn = + if lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") ["1" "true" "yes"] + then msg: builtins.trace "warning: ${msg}" (abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors.") + else msg: builtins.trace "warning: ${msg}"; + + /* + Like warn, but only warn when the first argument is `true`. + + Type: bool -> string -> a -> a + */ + warnIf = cond: msg: + if cond + then warn msg + else id; + + /* + Like the `assert b; e` expression, but with a custom error message and + without the semicolon. + + If true, return the identity function, `r: r`. + + If false, throw the error message. + + Calls can be juxtaposed using function application, as `(r: r) a = a`, so + `(r: r) (r: r) a = a`, and so forth. + + Type: bool -> string -> a -> a + + Example: + + throwIfNot (lib.isList overlays) "The overlays argument to nixpkgs must be a list." + lib.foldr (x: throwIfNot (lib.isFunction x) "All overlays passed to nixpkgs must be functions.") (r: r) overlays + pkgs + + */ + throwIfNot = cond: msg: + if cond + then x: x + else throw msg; + + /* + Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise. + + Example: + let colorVariants = ["bright" "dark" "black"] + in checkListOfEnum "color variants" [ "standard" "light" "dark" ] colorVariants; + => + error: color variants: bright, black unexpected; valid ones: standard, light, dark + + Type: String -> List ComparableVal -> List ComparableVal -> a -> a + */ + checkListOfEnum = msg: valid: given: let + unexpected = lib.subtractLists valid given; + in + lib.throwIfNot (unexpected == []) + "${msg}: ${builtins.concatStringsSep ", " (builtins.map builtins.toString unexpected)} unexpected; valid ones: ${builtins.concatStringsSep ", " (builtins.map builtins.toString valid)}"; + + info = msg: builtins.trace "INFO: ${msg}"; + + showWarnings = warnings: res: lib.foldr (w: x: warn w x) res warnings; + + ## Function annotations + + /* + Add metadata about expected function arguments to a function. + The metadata should match the format given by + builtins.functionArgs, i.e. a set from expected argument to a bool + representing whether that argument has a default or not. + setFunctionArgs : (a → b) → Map String Bool → (a → b) + + This function is necessary because you can't dynamically create a + function of the { a, b ? foo, ... }: format, but some facilities + like callPackage expect to be able to query expected arguments. + */ + setFunctionArgs = f: args: { + # TODO: Should we add call-time "type" checking like built in? + __functor = self: f; + __functionArgs = args; + }; + + /* + Extract the expected function arguments from a function. + This works both with nix-native { a, b ? foo, ... }: style + functions and functions with args set with 'setFunctionArgs'. It + has the same return type and semantics as builtins.functionArgs. + setFunctionArgs : (a → b) → Map String Bool. + */ + functionArgs = f: + if f ? __functor + then f.__functionArgs or (lib.functionArgs (f.__functor f)) + else builtins.functionArgs f; + + /* + Check whether something is a function or something + annotated with function args. + */ + isFunction = f: + builtins.isFunction f + || (f ? __functor && isFunction (f.__functor f)); + + /* + Convert the given positive integer to a string of its hexadecimal + representation. For example: + + toHexString 0 => "0" + + toHexString 16 => "10" + + toHexString 250 => "FA" + */ + toHexString = i: let + toHexDigit = d: + if d < 10 + then toString d + else + { + "10" = "A"; + "11" = "B"; + "12" = "C"; + "13" = "D"; + "14" = "E"; + "15" = "F"; + } + .${toString d}; + in + lib.concatMapStrings toHexDigit (toBaseDigits 16 i); + + /* + `toBaseDigits base i` converts the positive integer i to a list of its + digits in the given base. For example: + + toBaseDigits 10 123 => [ 1 2 3 ] + + toBaseDigits 2 6 => [ 1 1 0 ] + + toBaseDigits 16 250 => [ 15 10 ] + */ + toBaseDigits = base: i: let + go = i: + if i < base + then [i] + else let + r = i - ((i / base) * base); + q = (i - r) / base; + in + [r] ++ go q; + in + assert (base >= 2); + assert (i >= 0); + lib.reverseList (go i); +} diff --git a/src/alejandra/tests/cases/idioms_nixos_1/out-tabs.nix b/src/alejandra/tests/cases/idioms_nixos_1/out-tabs.nix new file mode 100644 index 00000000..ed80662c --- /dev/null +++ b/src/alejandra/tests/cases/idioms_nixos_1/out-tabs.nix @@ -0,0 +1,380 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + inherit (config.boot) kernelPatches; + inherit (config.boot.kernel) features randstructSeed; + inherit (config.boot.kernelPackages) kernel; + + kernelModulesConf = + pkgs.writeText "nixos.conf" + '' + ${concatStringsSep "\n" config.boot.kernelModules} + ''; +in { + ###### interface + + options = { + boot.kernel.features = + mkOption { + default = {}; + example = literalExpression "{ debug = true; }"; + internal = true; + description = '' + This option allows to enable or disable certain kernel features. + It's not API, because it's about kernel feature sets, that + make sense for specific use cases. Mostly along with programs, + which would have separate nixos options. + `grep features pkgs/os-specific/linux/kernel/common-config.nix` + ''; + }; + + boot.kernelPackages = + mkOption { + default = pkgs.linuxPackages; + type = types.unspecified // {merge = mergeEqualOption;}; + apply = kernelPackages: + kernelPackages.extend (self: super: { + kernel = + super.kernel.override (originalArgs: { + inherit randstructSeed; + kernelPatches = (originalArgs.kernelPatches or []) ++ kernelPatches; + features = lib.recursiveUpdate super.kernel.features features; + }); + }); + # We don't want to evaluate all of linuxPackages for the manual + # - some of it might not even evaluate correctly. + defaultText = literalExpression "pkgs.linuxPackages"; + example = literalExpression "pkgs.linuxKernel.packages.linux_5_10"; + description = '' + This option allows you to override the Linux kernel used by + NixOS. Since things like external kernel module packages are + tied to the kernel you're using, it also overrides those. + This option is a function that takes Nixpkgs as an argument + (as a convenience), and returns an attribute set containing at + the very least an attribute kernel. + Additional attributes may be needed depending on your + configuration. For instance, if you use the NVIDIA X driver, + then it also needs to contain an attribute + nvidia_x11. + ''; + }; + + boot.kernelPatches = + mkOption { + type = types.listOf types.attrs; + default = []; + example = literalExpression "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]"; + description = "A list of additional patches to apply to the kernel."; + }; + + boot.kernel.randstructSeed = + mkOption { + type = types.str; + default = ""; + example = "my secret seed"; + description = '' + Provides a custom seed for the RANDSTRUCT security + option of the Linux kernel. Note that RANDSTRUCT is + only enabled in NixOS hardened kernels. Using a custom seed requires + building the kernel and dependent packages locally, since this + customization happens at build time. + ''; + }; + + boot.kernelParams = + mkOption { + type = + types.listOf (types.strMatching ''([^"[:space:]]|"[^"]*")+'' + // { + name = "kernelParam"; + description = "string, with spaces inside double quotes"; + }); + default = []; + description = "Parameters added to the kernel command line."; + }; + + boot.consoleLogLevel = + mkOption { + type = types.int; + default = 4; + description = '' + The kernel console loglevel. All Kernel Messages with a log level smaller + than this setting will be printed to the console. + ''; + }; + + boot.vesa = + mkOption { + type = types.bool; + default = false; + description = '' + (Deprecated) This option, if set, activates the VESA 800x600 video + mode on boot and disables kernel modesetting. It is equivalent to + specifying [ "vga=0x317" "nomodeset" ] in the + option. This option is + deprecated as of 2020: Xorg now works better with modesetting, and + you might want a different VESA vga setting, anyway. + ''; + }; + + boot.extraModulePackages = + mkOption { + type = types.listOf types.package; + default = []; + example = literalExpression "[ config.boot.kernelPackages.nvidia_x11 ]"; + description = "A list of additional packages supplying kernel modules."; + }; + + boot.kernelModules = + mkOption { + type = types.listOf types.str; + default = []; + description = '' + The set of kernel modules to be loaded in the second stage of + the boot process. Note that modules that are needed to + mount the root file system should be added to + or + . + ''; + }; + + boot.initrd.availableKernelModules = + mkOption { + type = types.listOf types.str; + default = []; + example = ["sata_nv" "ext3"]; + description = '' + The set of kernel modules in the initial ramdisk used during the + boot process. This set must include all modules necessary for + mounting the root device. That is, it should include modules + for the physical device (e.g., SCSI drivers) and for the file + system (e.g., ext3). The set specified here is automatically + closed under the module dependency relation, i.e., all + dependencies of the modules list here are included + automatically. The modules listed here are available in the + initrd, but are only loaded on demand (e.g., the ext3 module is + loaded automatically when an ext3 filesystem is mounted, and + modules for PCI devices are loaded when they match the PCI ID + of a device in your system). To force a module to be loaded, + include it in . + ''; + }; + + boot.initrd.kernelModules = + mkOption { + type = types.listOf types.str; + default = []; + description = "List of modules that are always loaded by the initrd."; + }; + + boot.initrd.includeDefaultModules = + mkOption { + type = types.bool; + default = true; + description = '' + This option, if set, adds a collection of default kernel modules + to and + . + ''; + }; + + system.modulesTree = + mkOption { + type = types.listOf types.path; + internal = true; + default = []; + description = '' + Tree of kernel modules. This includes the kernel, plus modules + built outside of the kernel. Combine these into a single tree of + symlinks because modprobe only supports one directory. + ''; + # Convert the list of path to only one path. + apply = pkgs.aggregateModules; + }; + + system.requiredKernelConfig = + mkOption { + default = []; + example = + literalExpression '' + with config.lib.kernelConfig; [ + (isYes "MODULES") + (isEnabled "FB_CON_DECOR") + (isEnabled "BLK_DEV_INITRD") + ] + ''; + internal = true; + type = types.listOf types.attrs; + description = '' + This option allows modules to specify the kernel config options that + must be set (or unset) for the module to work. Please use the + lib.kernelConfig functions to build list elements. + ''; + }; + }; + + ###### implementation + + config = + mkMerge + [ + (mkIf config.boot.initrd.enable { + boot.initrd.availableKernelModules = + optionals config.boot.initrd.includeDefaultModules ([ + # Note: most of these (especially the SATA/PATA modules) + # shouldn't be included by default since nixos-generate-config + # detects them, but I'm keeping them for now for backwards + # compatibility. + + # Some SATA/PATA stuff. + "ahci" + "sata_nv" + "sata_via" + "sata_sis" + "sata_uli" + "ata_piix" + "pata_marvell" + + # Standard SCSI stuff. + "sd_mod" + "sr_mod" + + # SD cards and internal eMMC drives. + "mmc_block" + + # Support USB keyboards, in case the boot fails and we only have + # a USB keyboard, or for LUKS passphrase prompt. + "uhci_hcd" + "ehci_hcd" + "ehci_pci" + "ohci_hcd" + "ohci_pci" + "xhci_hcd" + "xhci_pci" + "usbhid" + "hid_generic" + "hid_lenovo" + "hid_apple" + "hid_roccat" + "hid_logitech_hidpp" + "hid_logitech_dj" + "hid_microsoft" + ] + ++ optionals pkgs.stdenv.hostPlatform.isx86 [ + # Misc. x86 keyboard stuff. + "pcips2" + "atkbd" + "i8042" + + # x86 RTC needed by the stage 2 init script. + "rtc_cmos" + ]); + + boot.initrd.kernelModules = + optionals config.boot.initrd.includeDefaultModules [ + # For LVM. + "dm_mod" + ]; + }) + + (mkIf (!config.boot.isContainer) { + system.build = {inherit kernel;}; + + system.modulesTree = [kernel] ++ config.boot.extraModulePackages; + + # Implement consoleLogLevel both in early boot and using sysctl + # (so you don't need to reboot to have changes take effect). + boot.kernelParams = + ["loglevel=${toString config.boot.consoleLogLevel}"] + ++ optionals config.boot.vesa ["vga=0x317" "nomodeset"]; + + boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel; + + boot.kernelModules = ["loop" "atkbd"]; + + # The Linux kernel >= 2.6.27 provides firmware. + hardware.firmware = [kernel]; + + # Create /etc/modules-load.d/nixos.conf, which is read by + # systemd-modules-load.service to load required kernel modules. + environment.etc = { + "modules-load.d/nixos.conf".source = kernelModulesConf; + }; + + systemd.services.systemd-modules-load = { + wantedBy = ["multi-user.target"]; + restartTriggers = [kernelModulesConf]; + serviceConfig = { + # Ignore failed module loads. Typically some of the + # modules in ‘boot.kernelModules’ are "nice to have but + # not required" (e.g. acpi-cpufreq), so we don't want to + # barf on those. + SuccessExitStatus = "0 1"; + }; + }; + + lib.kernelConfig = { + isYes = option: { + assertion = config: config.isYes option; + message = "CONFIG_${option} is not yes!"; + configLine = "CONFIG_${option}=y"; + }; + + isNo = option: { + assertion = config: config.isNo option; + message = "CONFIG_${option} is not no!"; + configLine = "CONFIG_${option}=n"; + }; + + isModule = option: { + assertion = config: config.isModule option; + message = "CONFIG_${option} is not built as a module!"; + configLine = "CONFIG_${option}=m"; + }; + + ### Usually you will just want to use these two + # True if yes or module + isEnabled = option: { + assertion = config: config.isEnabled option; + message = "CONFIG_${option} is not enabled!"; + configLine = "CONFIG_${option}=y"; + }; + + # True if no or omitted + isDisabled = option: { + assertion = config: config.isDisabled option; + message = "CONFIG_${option} is not disabled!"; + configLine = "CONFIG_${option}=n"; + }; + }; + + # The config options that all modules can depend upon + system.requiredKernelConfig = with config.lib.kernelConfig; + [ + # !!! Should this really be needed? + (isYes "MODULES") + (isYes "BINFMT_ELF") + ] + ++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT")); + + # nixpkgs kernels are assumed to have all required features + assertions = + if config.boot.kernelPackages.kernel ? features + then [] + else let + cfg = config.boot.kernelPackages.kernel.config; + in + map ( + attrs: { + assertion = attrs.assertion cfg; + inherit (attrs) message; + } + ) + config.system.requiredKernelConfig; + }) + ]; +} diff --git a/src/alejandra/tests/cases/idioms_pkgs_1/out-tabs.nix b/src/alejandra/tests/cases/idioms_pkgs_1/out-tabs.nix new file mode 100644 index 00000000..6e3826c2 --- /dev/null +++ b/src/alejandra/tests/cases/idioms_pkgs_1/out-tabs.nix @@ -0,0 +1,18 @@ +{ + stdenv, + lib, + fetchFrom, + ... +}: +stdenv.mkDerivation rec { + pname = "test"; + version = "0.0"; + src = + fetchFrom { + url = "example/${version}"; + }; + meta = with lib; { + maintainers = with maintainers; [someone]; + description = "something"; + }; +} diff --git a/src/alejandra/tests/cases/idioms_pkgs_2/out-tabs.nix b/src/alejandra/tests/cases/idioms_pkgs_2/out-tabs.nix new file mode 100644 index 00000000..e94310a2 --- /dev/null +++ b/src/alejandra/tests/cases/idioms_pkgs_2/out-tabs.nix @@ -0,0 +1,44 @@ +{ + lib, + stdenv, + fetchurl, + nixos, + testVersion, + testEqualDerivation, + hello, +}: +stdenv.mkDerivation rec { + pname = "hello"; + version = "2.12"; + + src = + fetchurl { + url = "mirror://gnu/hello/${pname}-${version}.tar.gz"; + sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g"; + }; + + doCheck = true; + + passthru.tests = { + version = testVersion {package = hello;}; + + invariant-under-noXlibs = + testEqualDerivation + "hello must not be rebuilt when environment.noXlibs is set." + hello + (nixos {environment.noXlibs = true;}).pkgs.hello; + }; + + meta = with lib; { + description = "A program that produces a familiar, friendly greeting"; + longDescription = '' + GNU Hello is a program that prints "Hello, world!" when you run it. + It is fully customizable. + ''; + homepage = "https://www.gnu.org/software/hello/manual/"; + changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${version}"; + license = licenses.gpl3Plus; + maintainers = [maintainers.eelco]; + platforms = platforms.all; + }; +} diff --git a/src/alejandra/tests/cases/idioms_pkgs_3/out-tabs.nix b/src/alejandra/tests/cases/idioms_pkgs_3/out-tabs.nix new file mode 100644 index 00000000..ed80662c --- /dev/null +++ b/src/alejandra/tests/cases/idioms_pkgs_3/out-tabs.nix @@ -0,0 +1,380 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + inherit (config.boot) kernelPatches; + inherit (config.boot.kernel) features randstructSeed; + inherit (config.boot.kernelPackages) kernel; + + kernelModulesConf = + pkgs.writeText "nixos.conf" + '' + ${concatStringsSep "\n" config.boot.kernelModules} + ''; +in { + ###### interface + + options = { + boot.kernel.features = + mkOption { + default = {}; + example = literalExpression "{ debug = true; }"; + internal = true; + description = '' + This option allows to enable or disable certain kernel features. + It's not API, because it's about kernel feature sets, that + make sense for specific use cases. Mostly along with programs, + which would have separate nixos options. + `grep features pkgs/os-specific/linux/kernel/common-config.nix` + ''; + }; + + boot.kernelPackages = + mkOption { + default = pkgs.linuxPackages; + type = types.unspecified // {merge = mergeEqualOption;}; + apply = kernelPackages: + kernelPackages.extend (self: super: { + kernel = + super.kernel.override (originalArgs: { + inherit randstructSeed; + kernelPatches = (originalArgs.kernelPatches or []) ++ kernelPatches; + features = lib.recursiveUpdate super.kernel.features features; + }); + }); + # We don't want to evaluate all of linuxPackages for the manual + # - some of it might not even evaluate correctly. + defaultText = literalExpression "pkgs.linuxPackages"; + example = literalExpression "pkgs.linuxKernel.packages.linux_5_10"; + description = '' + This option allows you to override the Linux kernel used by + NixOS. Since things like external kernel module packages are + tied to the kernel you're using, it also overrides those. + This option is a function that takes Nixpkgs as an argument + (as a convenience), and returns an attribute set containing at + the very least an attribute kernel. + Additional attributes may be needed depending on your + configuration. For instance, if you use the NVIDIA X driver, + then it also needs to contain an attribute + nvidia_x11. + ''; + }; + + boot.kernelPatches = + mkOption { + type = types.listOf types.attrs; + default = []; + example = literalExpression "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]"; + description = "A list of additional patches to apply to the kernel."; + }; + + boot.kernel.randstructSeed = + mkOption { + type = types.str; + default = ""; + example = "my secret seed"; + description = '' + Provides a custom seed for the RANDSTRUCT security + option of the Linux kernel. Note that RANDSTRUCT is + only enabled in NixOS hardened kernels. Using a custom seed requires + building the kernel and dependent packages locally, since this + customization happens at build time. + ''; + }; + + boot.kernelParams = + mkOption { + type = + types.listOf (types.strMatching ''([^"[:space:]]|"[^"]*")+'' + // { + name = "kernelParam"; + description = "string, with spaces inside double quotes"; + }); + default = []; + description = "Parameters added to the kernel command line."; + }; + + boot.consoleLogLevel = + mkOption { + type = types.int; + default = 4; + description = '' + The kernel console loglevel. All Kernel Messages with a log level smaller + than this setting will be printed to the console. + ''; + }; + + boot.vesa = + mkOption { + type = types.bool; + default = false; + description = '' + (Deprecated) This option, if set, activates the VESA 800x600 video + mode on boot and disables kernel modesetting. It is equivalent to + specifying [ "vga=0x317" "nomodeset" ] in the + option. This option is + deprecated as of 2020: Xorg now works better with modesetting, and + you might want a different VESA vga setting, anyway. + ''; + }; + + boot.extraModulePackages = + mkOption { + type = types.listOf types.package; + default = []; + example = literalExpression "[ config.boot.kernelPackages.nvidia_x11 ]"; + description = "A list of additional packages supplying kernel modules."; + }; + + boot.kernelModules = + mkOption { + type = types.listOf types.str; + default = []; + description = '' + The set of kernel modules to be loaded in the second stage of + the boot process. Note that modules that are needed to + mount the root file system should be added to + or + . + ''; + }; + + boot.initrd.availableKernelModules = + mkOption { + type = types.listOf types.str; + default = []; + example = ["sata_nv" "ext3"]; + description = '' + The set of kernel modules in the initial ramdisk used during the + boot process. This set must include all modules necessary for + mounting the root device. That is, it should include modules + for the physical device (e.g., SCSI drivers) and for the file + system (e.g., ext3). The set specified here is automatically + closed under the module dependency relation, i.e., all + dependencies of the modules list here are included + automatically. The modules listed here are available in the + initrd, but are only loaded on demand (e.g., the ext3 module is + loaded automatically when an ext3 filesystem is mounted, and + modules for PCI devices are loaded when they match the PCI ID + of a device in your system). To force a module to be loaded, + include it in . + ''; + }; + + boot.initrd.kernelModules = + mkOption { + type = types.listOf types.str; + default = []; + description = "List of modules that are always loaded by the initrd."; + }; + + boot.initrd.includeDefaultModules = + mkOption { + type = types.bool; + default = true; + description = '' + This option, if set, adds a collection of default kernel modules + to and + . + ''; + }; + + system.modulesTree = + mkOption { + type = types.listOf types.path; + internal = true; + default = []; + description = '' + Tree of kernel modules. This includes the kernel, plus modules + built outside of the kernel. Combine these into a single tree of + symlinks because modprobe only supports one directory. + ''; + # Convert the list of path to only one path. + apply = pkgs.aggregateModules; + }; + + system.requiredKernelConfig = + mkOption { + default = []; + example = + literalExpression '' + with config.lib.kernelConfig; [ + (isYes "MODULES") + (isEnabled "FB_CON_DECOR") + (isEnabled "BLK_DEV_INITRD") + ] + ''; + internal = true; + type = types.listOf types.attrs; + description = '' + This option allows modules to specify the kernel config options that + must be set (or unset) for the module to work. Please use the + lib.kernelConfig functions to build list elements. + ''; + }; + }; + + ###### implementation + + config = + mkMerge + [ + (mkIf config.boot.initrd.enable { + boot.initrd.availableKernelModules = + optionals config.boot.initrd.includeDefaultModules ([ + # Note: most of these (especially the SATA/PATA modules) + # shouldn't be included by default since nixos-generate-config + # detects them, but I'm keeping them for now for backwards + # compatibility. + + # Some SATA/PATA stuff. + "ahci" + "sata_nv" + "sata_via" + "sata_sis" + "sata_uli" + "ata_piix" + "pata_marvell" + + # Standard SCSI stuff. + "sd_mod" + "sr_mod" + + # SD cards and internal eMMC drives. + "mmc_block" + + # Support USB keyboards, in case the boot fails and we only have + # a USB keyboard, or for LUKS passphrase prompt. + "uhci_hcd" + "ehci_hcd" + "ehci_pci" + "ohci_hcd" + "ohci_pci" + "xhci_hcd" + "xhci_pci" + "usbhid" + "hid_generic" + "hid_lenovo" + "hid_apple" + "hid_roccat" + "hid_logitech_hidpp" + "hid_logitech_dj" + "hid_microsoft" + ] + ++ optionals pkgs.stdenv.hostPlatform.isx86 [ + # Misc. x86 keyboard stuff. + "pcips2" + "atkbd" + "i8042" + + # x86 RTC needed by the stage 2 init script. + "rtc_cmos" + ]); + + boot.initrd.kernelModules = + optionals config.boot.initrd.includeDefaultModules [ + # For LVM. + "dm_mod" + ]; + }) + + (mkIf (!config.boot.isContainer) { + system.build = {inherit kernel;}; + + system.modulesTree = [kernel] ++ config.boot.extraModulePackages; + + # Implement consoleLogLevel both in early boot and using sysctl + # (so you don't need to reboot to have changes take effect). + boot.kernelParams = + ["loglevel=${toString config.boot.consoleLogLevel}"] + ++ optionals config.boot.vesa ["vga=0x317" "nomodeset"]; + + boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel; + + boot.kernelModules = ["loop" "atkbd"]; + + # The Linux kernel >= 2.6.27 provides firmware. + hardware.firmware = [kernel]; + + # Create /etc/modules-load.d/nixos.conf, which is read by + # systemd-modules-load.service to load required kernel modules. + environment.etc = { + "modules-load.d/nixos.conf".source = kernelModulesConf; + }; + + systemd.services.systemd-modules-load = { + wantedBy = ["multi-user.target"]; + restartTriggers = [kernelModulesConf]; + serviceConfig = { + # Ignore failed module loads. Typically some of the + # modules in ‘boot.kernelModules’ are "nice to have but + # not required" (e.g. acpi-cpufreq), so we don't want to + # barf on those. + SuccessExitStatus = "0 1"; + }; + }; + + lib.kernelConfig = { + isYes = option: { + assertion = config: config.isYes option; + message = "CONFIG_${option} is not yes!"; + configLine = "CONFIG_${option}=y"; + }; + + isNo = option: { + assertion = config: config.isNo option; + message = "CONFIG_${option} is not no!"; + configLine = "CONFIG_${option}=n"; + }; + + isModule = option: { + assertion = config: config.isModule option; + message = "CONFIG_${option} is not built as a module!"; + configLine = "CONFIG_${option}=m"; + }; + + ### Usually you will just want to use these two + # True if yes or module + isEnabled = option: { + assertion = config: config.isEnabled option; + message = "CONFIG_${option} is not enabled!"; + configLine = "CONFIG_${option}=y"; + }; + + # True if no or omitted + isDisabled = option: { + assertion = config: config.isDisabled option; + message = "CONFIG_${option} is not disabled!"; + configLine = "CONFIG_${option}=n"; + }; + }; + + # The config options that all modules can depend upon + system.requiredKernelConfig = with config.lib.kernelConfig; + [ + # !!! Should this really be needed? + (isYes "MODULES") + (isYes "BINFMT_ELF") + ] + ++ (optional (randstructSeed != "") (isYes "GCC_PLUGIN_RANDSTRUCT")); + + # nixpkgs kernels are assumed to have all required features + assertions = + if config.boot.kernelPackages.kernel ? features + then [] + else let + cfg = config.boot.kernelPackages.kernel.config; + in + map ( + attrs: { + assertion = attrs.assertion cfg; + inherit (attrs) message; + } + ) + config.system.requiredKernelConfig; + }) + ]; +} diff --git a/src/alejandra/tests/cases/if_else/out-tabs.nix b/src/alejandra/tests/cases/if_else/out-tabs.nix new file mode 100644 index 00000000..d2375c16 --- /dev/null +++ b/src/alejandra/tests/cases/if_else/out-tabs.nix @@ -0,0 +1,286 @@ +[ + ( + if true + then { + version = "1.2.3"; + } + else { + version = "3.2.1"; + } + ) + ( + if true + then '' + some text + '' + else '' + other text + '' + ) + ( + if ./a + then b + else c + ) + ( + if + /**/ + a + /**/ + then + /**/ + b + /**/ + else + /**/ + c + ) + ( + if # test + a # test + then # test + b # test + else # test + c + ) + ( + if # test + /**/ + a # test + /**/ + then # test + b # test + /**/ + else # test + /**/ + c + ) + ( + if + if a + then b + else c + then b + else if a + then b + else if a + then b + else c + ) + ( + if + if a + then b + else c + then b + else if a + then b + else + /* + x + */ + if a + then b + else c + ) + ( + if + ( + if + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + then + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + else + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + ) + then + ( + if + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + then + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + else + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + ) + else + ( + if + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + then + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + else + ( + if + ( + if a + then b + else c + ) + then + ( + if a + then b + else c + ) + else + ( + if a + then b + else c + ) + ) + ) + ) +] diff --git a/src/alejandra/tests/cases/inherit/out-tabs.nix b/src/alejandra/tests/cases/inherit/out-tabs.nix new file mode 100644 index 00000000..86fd9444 --- /dev/null +++ b/src/alejandra/tests/cases/inherit/out-tabs.nix @@ -0,0 +1,103 @@ +[ + { + inherit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + } + { + inherit + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ; + } + {inherit b d;} + { + inherit + b + d + /* + e + */ + ; + } + { + inherit + b + /* + c + */ + d + ; + } + { + inherit + b + /* + c + */ + d + /* + e + */ + ; + } + { + inherit + /* + a + */ + b + d + ; + } + { + inherit + /* + a + */ + b + d + /* + e + */ + ; + } + { + inherit + /* + a + */ + b + /* + c + */ + d + ; + } + { + inherit + /* + a + */ + b + /* + c + */ + d + /* + e + */ + ; + } + { + inherit # test + a # test + + b # test + c # test + d # test + + e + f + g + h + ; + } +] diff --git a/src/alejandra/tests/cases/inherit_blank_trailing/out-tabs.nix b/src/alejandra/tests/cases/inherit_blank_trailing/out-tabs.nix new file mode 100644 index 00000000..d0a5e35e --- /dev/null +++ b/src/alejandra/tests/cases/inherit_blank_trailing/out-tabs.nix @@ -0,0 +1,31 @@ +[ + { + inherit # test + a # test + + b # test + c # test + d # test + + e + f + g + h + ; + } + { + inherit + a # mixed trivialities + + # comment 1 + # comment 2 + # comment 3 after blanks + b # multiple newlines + + c # multiple comments + # comment 1 + # comment 2 + # comment 3 + ; + } +] diff --git a/src/alejandra/tests/cases/inherit_comment/out-tabs.nix b/src/alejandra/tests/cases/inherit_comment/out-tabs.nix new file mode 100644 index 00000000..f6c7761b --- /dev/null +++ b/src/alejandra/tests/cases/inherit_comment/out-tabs.nix @@ -0,0 +1,7 @@ +{ + inherit # eeby deeby + a + # b + c + ; +} diff --git a/src/alejandra/tests/cases/inherit_from/out-tabs.nix b/src/alejandra/tests/cases/inherit_from/out-tabs.nix new file mode 100644 index 00000000..8da74422 --- /dev/null +++ b/src/alejandra/tests/cases/inherit_from/out-tabs.nix @@ -0,0 +1,1116 @@ +[ + {inherit (c) f h;} + { + inherit + (c) + f + h + /* + i + */ + ; + } + { + inherit + (c) + f + /* + g + */ + h + ; + } + { + inherit + (c) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + (c) + /* + e + */ + f + h + ; + } + { + inherit + (c) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + (c) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + (c) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + ( + c + /* + d + */ + ) + f + h + ; + } + { + inherit + ( + c + /* + d + */ + ) + f + h + /* + i + */ + ; + } + { + inherit + ( + c + /* + d + */ + ) + f + /* + g + */ + h + ; + } + { + inherit + ( + c + /* + d + */ + ) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + ( + c + /* + d + */ + ) + /* + e + */ + f + h + ; + } + { + inherit + ( + c + /* + d + */ + ) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + ( + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + ( + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + ) + f + h + ; + } + { + inherit + ( + /* + b + */ + c + ) + f + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + ) + f + /* + g + */ + h + ; + } + { + inherit + ( + /* + b + */ + c + ) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + ) + /* + e + */ + f + h + ; + } + { + inherit + ( + /* + b + */ + c + ) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + ) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + ( + /* + b + */ + c + ) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + f + h + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + f + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + f + /* + g + */ + h + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + h + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + (c) + f + h + ; + } + { + inherit + /* + a + */ + (c) + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + (c) + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + (c) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + (c) + /* + e + */ + f + h + ; + } + { + inherit + /* + a + */ + (c) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + (c) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + (c) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + f + h + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + /* + e + */ + f + h + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + ( + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + f + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + /* + e + */ + f + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + ) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + f + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + f + /* + g + */ + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + h + /* + i + */ + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + ; + } + { + inherit + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + f + /* + g + */ + h + /* + i + */ + ; + } +] diff --git a/src/alejandra/tests/cases/key_value/out-tabs.nix b/src/alejandra/tests/cases/key_value/out-tabs.nix new file mode 100644 index 00000000..1f652340 --- /dev/null +++ b/src/alejandra/tests/cases/key_value/out-tabs.nix @@ -0,0 +1,120 @@ +rec +/**/ +{ + a = 4; + a = a: b; + + a = {a = 1;}; + + b = { + a = + 1 + /* + d + */ + ; + }; + + c = { + a = + /* + c + */ + 1; + }; + d = { + a = + /* + c + */ + 1 + /* + d + */ + ; + }; + e = { + a + /* + b + */ + = + 1; + }; + f = { + a + /* + b + */ + = + 1 + /* + d + */ + ; + }; + h = { + a + /* + b + */ + = + /* + c + */ + 1; + }; + i = { + a + /* + b + */ + = + /* + c + */ + 1 + /* + d + */ + ; + }; + j = a: {b = 1;}; + k = a: { + b = 1; + c = 2; + }; + l = a: + /* + b + */ + {b = 1;}; + m = a: + /* + b + */ + { + b = 1; + c = 2; + }; + n = pkgs: {}; + o = {pkgs, ...}: {}; + + a + /* + b + */ + = + /* + c + */ + 1 + /* + d + */ + ; + + p = + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {} + a; +} diff --git a/src/alejandra/tests/cases/lambda/out-tabs.nix b/src/alejandra/tests/cases/lambda/out-tabs.nix new file mode 100644 index 00000000..83a05cdb --- /dev/null +++ b/src/alejandra/tests/cases/lambda/out-tabs.nix @@ -0,0 +1,71 @@ +[ + (a: b: + /* + c + */ + d) + ({}: b: + /* + c + */ + d) + (a: {}: + /* + c + */ + d) + (a: d) + (a: + /* + c + */ + d) + (a + /* + b + */ + : + d) + (a + /* + b + */ + : + /* + c + */ + d) + ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ) + ( + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ) + ({ + pkgs ? import ./.. {}, + locationsXml, + }: + null) + (a: b: c: {}: a: b: c: + a) + + ({pkgs, ...}: { + # Stuff + }) + + ({pkgs, ...}: let + in + pkgs) + + (a: {b, ...}: c: { + # Stuff + }) + + (a: { + b, + c, + ... + }: d: { + # Stuff + }) +] diff --git a/src/alejandra/tests/cases/let_in/out-tabs.nix b/src/alejandra/tests/cases/let_in/out-tabs.nix new file mode 100644 index 00000000..7ad1dcbb --- /dev/null +++ b/src/alejandra/tests/cases/let_in/out-tabs.nix @@ -0,0 +1,92 @@ +let + /**/ + a = let + b = 2; + c = 3; + in + d; + /**/ + a = let c = 1; in f; + + /**/ + a = let + c = 1; + in + /* + e + */ + f; + /**/ + a = let + c = 1; + /* + d + */ + in + f; + /**/ + + a = let + c = 1; + /* + d + */ + in + /* + e + */ + f; + /**/ + a = let + /* + b + */ + c = 1; + in + f; + /**/ + a = let + /* + b + */ + c = 1; + in + /* + e + */ + f; + /**/ + a = let + /* + b + */ + c = 1; + /* + d + */ + in + f; + /**/ + a = let + /* + b + */ + c = 1; + /* + d + */ + in + /* + e + */ + f; + /**/ + + a = let + in [ + 1 + 2 + ]; +in + /**/ + a diff --git a/src/alejandra/tests/cases/lists/out-tabs.nix b/src/alejandra/tests/cases/lists/out-tabs.nix new file mode 100644 index 00000000..5e299c1c --- /dev/null +++ b/src/alejandra/tests/cases/lists/out-tabs.nix @@ -0,0 +1,96 @@ +[ + [1] + + [ + 1 + ] + + [b d] + [ + b + d + /* + e + */ + ] + [ + b + /* + c + */ + d + ] + [ + b + /* + c + */ + d + /* + e + */ + ] + [ + /* + a + */ + b + d + ] + [ + /* + a + */ + b + d + /* + e + */ + ] + [ + /* + a + */ + b + /* + c + */ + d + ] + [ + /* + a + */ + b + /* + c + */ + d + /* + e + */ + ] + + [ + b + + d + ] + [ + /* + a + */ + + b + + /* + c + */ + + d + + /* + e + */ + ] +] diff --git a/src/alejandra/tests/cases/monsters_1/out-tabs.nix b/src/alejandra/tests/cases/monsters_1/out-tabs.nix new file mode 100644 index 00000000..4150c08e --- /dev/null +++ b/src/alejandra/tests/cases/monsters_1/out-tabs.nix @@ -0,0 +1,255 @@ +{ + # foo + stdenv, + # foo + # foo + lib, + # foo + # foo + fetchFromGitLab, + # foo + # foo + cairo, + # foo + # foo + desktop-file-utils, + # foo + # foo + gettext, + # foo + # foo + glib, + # foo + # foo + gtk4, + # foo + # foo + libadwaita, + # foo + # foo + meson, + # foo + # foo + ninja, + # foo + # foo + pango, + # foo + # foo + pkg-config, + # foo + # foo + python3, + # foo + # foo + rustPlatform, + # foo + # foo + wrapGAppsHook4, + # foo +}: +# foo +stdenv.mkDerivation +# foo +rec +# foo +{ + # foo + pname + # foo + = + # foo + "contrast"; + # foo + version + # foo + = + # foo + "0.0.5"; + # foo + src + # foo + = + # foo + fetchFromGitLab + # foo + { + # foo + domain + # foo + = + # foo + "gitlab.gnome.org"; + # foo + group + # foo + = + # foo + "World"; + # foo + owner + # foo + = + # foo + "design"; + # foo + repo + # foo + = + # foo + "contrast"; + # foo + rev + # foo + = + # foo + version; + # foo + sha256 + # foo + = + # foo + "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; + # foo + }; + # foo + cargoDeps + # foo + = + # foo + rustPlatform.fetchCargoTarball + # foo + { + # foo + inherit + # foo + src + ; + # foo + name + # foo + = + # foo + "${pname}-${version}"; + # foo + hash + # foo + = + # foo + "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; + # foo + }; + # foo + nativeBuildInputs + # foo + = + # foo + [ + # foo + desktop-file-utils + # foo + gettext + # foo + meson + # foo + ninja + # foo + pkg-config + # foo + python3 + # foo + rustPlatform.rust.cargo + # foo + rustPlatform.cargoSetupHook + # foo + rustPlatform.rust.rustc + # foo + wrapGAppsHook4 + # foo + glib + # foo + # for glib-compile-resources + + # foo + ]; + # foo + buildInputs + # foo + = + # foo + [ + # foo + cairo + # foo + glib + # foo + gtk4 + # foo + libadwaita + # foo + pango + # foo + ]; + # foo + postPatch + # foo + = + # foo + '' + patchShebangs build-aux/meson_post_install.py + # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 + substituteInPlace build-aux/meson_post_install.py \ + --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" + ''; + # foo + meta + # foo + = + # foo + with + # foo + lib; + # foo + { + # foo + description + # foo + = + # foo + "Checks whether the contrast between two colors meet the WCAG requirements"; + # foo + homepage + # foo + = + # foo + "https://gitlab.gnome.org/World/design/contrast"; + # foo + license + # foo + = + # foo + licenses.gpl3Plus; + # foo + maintainers + # foo + = + # foo + with + # foo + maintainers; + # foo + [ + # foo + jtojnar + # foo + ]; + # foo + platforms + # foo + = + # foo + platforms.unix; + # foo + }; + # foo +} diff --git a/src/alejandra/tests/cases/monsters_2/out-tabs.nix b/src/alejandra/tests/cases/monsters_2/out-tabs.nix new file mode 100644 index 00000000..295190a9 --- /dev/null +++ b/src/alejandra/tests/cases/monsters_2/out-tabs.nix @@ -0,0 +1,30 @@ +{ + lib = { + /* + Concatenate two lists + + Type: concat :: [a] -> [a] -> [a] + + Example: + concat [ 1 2 ] [ 3 4 ] + => [ 1 2 3 4 ] + */ + concat = x: y: x ++ y; + }; + + options = { + boot.kernel.features = + mkOption { + default = {}; + example = literalExpression "{ debug = true; }"; + internal = true; + description = '' + This option allows to enable or disable certain kernel features. + It's not API, because it's about kernel feature sets, that + make sense for specific use cases. Mostly along with programs, + which would have separate nixos options. + `grep features pkgs/os-specific/linux/kernel/common-config.nix` + ''; + }; + }; +} diff --git a/src/alejandra/tests/cases/monsters_3/out-tabs.nix b/src/alejandra/tests/cases/monsters_3/out-tabs.nix new file mode 100644 index 00000000..19143bd2 --- /dev/null +++ b/src/alejandra/tests/cases/monsters_3/out-tabs.nix @@ -0,0 +1,64 @@ +{ + stdenv, + lib, + fetchFromGitLab, + cairo, + desktop-file-utils, + gettext, + glib, + gtk4, + libadwaita, + meson, + ninja, + pango, + pkg-config, + python3, + rustPlatform, + wrapGAppsHook4, +}: +stdenv.mkDerivation rec { + pname = "contrast"; + version = "0.0.5"; + src = + fetchFromGitLab { + domain = "gitlab.gnome.org"; + group = "World"; + owner = "design"; + repo = "contrast"; + rev = version; + sha256 = "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; + }; + cargoDeps = + rustPlatform.fetchCargoTarball { + inherit src; + name = "${pname}-${version}"; + hash = "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; + }; + nativeBuildInputs = [ + desktop-file-utils + gettext + meson + ninja + pkg-config + python3 + rustPlatform.rust.cargo + rustPlatform.cargoSetupHook + rustPlatform.rust.rustc + wrapGAppsHook4 + glib # for glib-compile-resources + ]; + buildInputs = [cairo glib gtk4 libadwaita pango]; + postPatch = '' + patchShebangs build-aux/meson_post_install.py + # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 + substituteInPlace build-aux/meson_post_install.py \ + --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" + ''; + meta = with lib; { + description = "Checks whether the contrast between two colors meet the WCAG requirements"; + homepage = "https://gitlab.gnome.org/World/design/contrast"; + license = licenses.gpl3Plus; + maintainers = with maintainers; [jtojnar]; + platforms = platforms.unix; + }; +} diff --git a/src/alejandra/tests/cases/monsters_4/out-tabs.nix b/src/alejandra/tests/cases/monsters_4/out-tabs.nix new file mode 100644 index 00000000..a1cf495c --- /dev/null +++ b/src/alejandra/tests/cases/monsters_4/out-tabs.nix @@ -0,0 +1,516 @@ +{ + /* + Foo + */ + stdenv, + /* + Foo + */ + /* + Foo + */ + lib, + /* + Foo + */ + /* + Foo + */ + fetchFromGitLab, + /* + Foo + */ + /* + Foo + */ + cairo, + /* + Foo + */ + /* + Foo + */ + desktop-file-utils, + /* + Foo + */ + /* + Foo + */ + gettext, + /* + Foo + */ + /* + Foo + */ + glib, + /* + Foo + */ + /* + Foo + */ + gtk4, + /* + Foo + */ + /* + Foo + */ + libadwaita, + /* + Foo + */ + /* + Foo + */ + meson, + /* + Foo + */ + /* + Foo + */ + ninja, + /* + Foo + */ + /* + Foo + */ + pango, + /* + Foo + */ + /* + Foo + */ + pkg-config, + /* + Foo + */ + /* + Foo + */ + python3, + /* + Foo + */ + /* + Foo + */ + rustPlatform, + /* + Foo + */ + /* + Foo + */ + wrapGAppsHook4, + /* + Foo + */ +}: +/* +Foo +*/ +stdenv.mkDerivation +/* +Foo +*/ +rec +/* +Foo +*/ +{ + /* + Foo + */ + pname + /* + Foo + */ + = + /* + Foo + */ + "contrast"; + /* + Foo + */ + version + /* + Foo + */ + = + /* + Foo + */ + "0.0.5"; + /* + Foo + */ + src + /* + Foo + */ + = + /* + Foo + */ + fetchFromGitLab + /* + Foo + */ + { + /* + Foo + */ + domain + /* + Foo + */ + = + /* + Foo + */ + "gitlab.gnome.org"; + /* + Foo + */ + group + /* + Foo + */ + = + /* + Foo + */ + "World"; + /* + Foo + */ + owner + /* + Foo + */ + = + /* + Foo + */ + "design"; + /* + Foo + */ + repo + /* + Foo + */ + = + /* + Foo + */ + "contrast"; + /* + Foo + */ + rev + /* + Foo + */ + = + /* + Foo + */ + version; + /* + Foo + */ + sha256 + /* + Foo + */ + = + /* + Foo + */ + "cypSbqLwSmauOoWOuppWpF3hvrxiqmkLspxAWzvlUC0="; + /* + Foo + */ + }; + /* + Foo + */ + cargoDeps + /* + Foo + */ + = + /* + Foo + */ + rustPlatform.fetchCargoTarball + /* + Foo + */ + { + /* + Foo + */ + inherit + /* + Foo + */ + src + ; + /* + Foo + */ + name + /* + Foo + */ + = + /* + Foo + */ + "${pname}-${version}"; + /* + Foo + */ + hash + /* + Foo + */ + = + /* + Foo + */ + "sha256-W4FyqwJpimf0isQRCq9TegpTQPQfsumx40AFQCFG5VQ="; + /* + Foo + */ + }; + /* + Foo + */ + nativeBuildInputs + /* + Foo + */ + = + /* + Foo + */ + [ + /* + Foo + */ + desktop-file-utils + /* + Foo + */ + gettext + /* + Foo + */ + meson + /* + Foo + */ + ninja + /* + Foo + */ + pkg-config + /* + Foo + */ + python3 + /* + Foo + */ + rustPlatform.rust.cargo + /* + Foo + */ + rustPlatform.cargoSetupHook + /* + Foo + */ + rustPlatform.rust.rustc + /* + Foo + */ + wrapGAppsHook4 + /* + Foo + */ + glib + /* + Foo + */ + # for glib-compile-resources + /* + Foo + */ + ]; + /* + Foo + */ + buildInputs + /* + Foo + */ + = + /* + Foo + */ + [ + /* + Foo + */ + cairo + /* + Foo + */ + glib + /* + Foo + */ + gtk4 + /* + Foo + */ + libadwaita + /* + Foo + */ + pango + /* + Foo + */ + ]; + /* + Foo + */ + postPatch + /* + Foo + */ + = + /* + Foo + */ + '' + patchShebangs build-aux/meson_post_install.py + # https://gitlab.gnome.org/World/design/contrast/-/merge_requests/23 + substituteInPlace build-aux/meson_post_install.py \ + --replace "gtk-update-icon-cache" "gtk4-update-icon-cache" + ''; + /* + Foo + */ + meta + /* + Foo + */ + = + /* + Foo + */ + with + /* + Foo + */ + lib; + /* + Foo + */ + { + /* + Foo + */ + description + /* + Foo + */ + = + /* + Foo + */ + "Checks whether the contrast between two colors meet the WCAG requirements"; + /* + Foo + */ + homepage + /* + Foo + */ + = + /* + Foo + */ + "https://gitlab.gnome.org/World/design/contrast"; + /* + Foo + */ + license + /* + Foo + */ + = + /* + Foo + */ + licenses.gpl3Plus; + /* + Foo + */ + maintainers + /* + Foo + */ + = + /* + Foo + */ + with + /* + Foo + */ + maintainers; + /* + Foo + */ + [ + /* + Foo + */ + jtojnar + /* + Foo + */ + ]; + /* + Foo + */ + platforms + /* + Foo + */ + = + /* + Foo + */ + platforms.unix; + /* + Foo + */ + }; + /* + Foo + */ +} diff --git a/src/alejandra/tests/cases/monsters_5/out-tabs.nix b/src/alejandra/tests/cases/monsters_5/out-tabs.nix new file mode 100644 index 00000000..d77fbb2d --- /dev/null +++ b/src/alejandra/tests/cases/monsters_5/out-tabs.nix @@ -0,0 +1,130 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + inherit + (config.boot) + kernelPatches + ; + + inherit + (config.boot.kernel) + features + randstructSeed + ; + + inherit + (config.boot.kernelPackages) + kernel + ; + + kernelModulesConf = + pkgs.writeText + "nixos.conf" + '' + ${concatStringsSep "\n" config.boot.kernelModules} + ''; +in { + ###### interface + + options = { + boot.kernel.features = + mkOption + { + default = {}; + + example = + literalExpression + "{debug= true;}"; + + internal = + true; + + description = '' + This option allows to enable or disable certain kernel features. + It's not API, because it's about kernel feature sets, that + make sense for specific use cases. Mostly along with programs, + which would have separate nixos options. + `grep features pkgs/os-specific/linux/kernel/common-config.nix` + ''; + }; + + boot.kernelPackages = + mkOption + { + default = + pkgs.linuxPackages; + + type = + types.unspecified + // { + merge = + mergeEqualOption; + }; + + apply = kernelPackages: + kernelPackages.extend + (self: super: { + kernel = + super.kernel.override + (originalArgs: { + inherit + randstructSeed + ; + + kernelPatches = + (originalArgs.kernelPatches + or []) + ++ kernelPatches; + + features = + lib.recursiveUpdate + super.kernel.features + features; + }); + }); + + # We don't want to evaluate all of linuxPackages for the manual + # - some of it might not even evaluate correctly. + + defaultText = + literalExpression + "pkgs.linuxPackages"; + + example = + literalExpression + "pkgs.linuxKernel.packages.linux_5_10"; + + description = '' + This option allows you to override the Linux kernel used by + NixOS. Since things like external kernel module packages are + tied to the kernel you're using, it also overrides those. + This option is a function that takes Nixpkgs as an argument + (as a convenience), and returns an attribute set containing at + the very least an attribute kernel. + Additional attributes may be needed depending on your + configuration. For instance, if you use the NVIDIA X driver, + then it also needs to contain an attribute + nvidia_x11. + ''; + }; + + boot.kernelPatches = + mkOption + { + type = + types.listOf + types.attrs; + + default = []; + + example = + literalExpression + "[ pkgs.kernelPatches.ubuntu_fan_4_4 ]"; + description = "A list of additional patches to apply to the kernel."; + }; + }; +} diff --git a/src/alejandra/tests/cases/or_default/out-tabs.nix b/src/alejandra/tests/cases/or_default/out-tabs.nix new file mode 100644 index 00000000..8ecb7e6a --- /dev/null +++ b/src/alejandra/tests/cases/or_default/out-tabs.nix @@ -0,0 +1,48 @@ +[ + (a.b or c) + (a.b + or + /**/ + c) + (a.b + /**/ + or c) + (a.b + /**/ + or + /**/ + c) + (a.b + /**/ + or + /**/ + (a.b + /**/ + or + /**/ + (a.b + /**/ + or + /**/ + c))) + (a.b + /**/ + or + /**/ + (a.b + /**/ + or + /**/ + (a.b + /**/ + or + /**/ + c))) + (a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a) + (a.a + or a.a # test + or a.a # test + or # test + a.a + or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a or a.a) +] diff --git a/src/alejandra/tests/cases/paren/out-tabs.nix b/src/alejandra/tests/cases/paren/out-tabs.nix new file mode 100644 index 00000000..c013f04a --- /dev/null +++ b/src/alejandra/tests/cases/paren/out-tabs.nix @@ -0,0 +1,165 @@ +( + ( # test + a # test + ) + c + ( + c + /* + e + */ + ) + ( + c + /* + d + */ + ) + ( + ( + c + /* + d + */ + ) + /* + e + */ + ) + ( + /* + b + */ + c + ) + ( + ( + /* + b + */ + c + ) + /* + e + */ + ) + ( + /* + b + */ + c + /* + d + */ + ) + ( + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + ) + ( + /* + a + */ + c + ) + ( + /* + a + */ + c + /* + e + */ + ) + ( + /* + a + */ + ( + c + /* + d + */ + ) + ) + ( + /* + a + */ + ( + c + /* + d + */ + ) + /* + e + */ + ) + ( + /* + a + */ + ( + /* + b + */ + c + ) + ) + ( + /* + a + */ + ( + /* + b + */ + c + ) + /* + e + */ + ) + ( + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + ) + ( + /* + a + */ + ( + /* + b + */ + c + /* + d + */ + ) + /* + e + */ + ) +) diff --git a/src/alejandra/tests/cases/pat_bind/out-tabs.nix b/src/alejandra/tests/cases/pat_bind/out-tabs.nix new file mode 100644 index 00000000..d7b61cb3 --- /dev/null +++ b/src/alejandra/tests/cases/pat_bind/out-tabs.nix @@ -0,0 +1,33 @@ +[ + ({} @ a: _) + ({} @ + /**/ + a: + _) + ({} + /**/ + @ a: + _) + ({} + /**/ + @ + /**/ + a: + _) + + (a @ {}: _) + (a @ + /**/ + {}: + _) + (a + /**/ + @ {}: + _) + (a + /**/ + @ + /**/ + {}: + _) +] diff --git a/src/alejandra/tests/cases/pattern/out-tabs.nix b/src/alejandra/tests/cases/pattern/out-tabs.nix new file mode 100644 index 00000000..e758b12f --- /dev/null +++ b/src/alejandra/tests/cases/pattern/out-tabs.nix @@ -0,0 +1,1123 @@ +[ + ({ + foo, + bar, + # Some comment + baz, + }: {}) + ({ + foo, + bar, # Some comment + }: {}) + (a @ { + self, + gomod2nix, + mach-nix, + }: + _) + ({ + self, + gomod2nix, + mach-nix, + } @ inp: + _) + ({ + a ? [ + 1 + 2 + 3 + ], + b ? { + # ... + }, + }: + _) + ({}: _) + ({a}: _) + ({ + /**/ + }: + _) + ({...}: _) + ({ + ... + /**/ + }: + _) + ({ + /**/ + ... + }: + _) + ({ + /**/ + ... + /**/ + }: + _) + + ({ + b, + e, + ... + }: + _) + ({ + b, + e, + ... + /* + h + */ + }: + _) + ({ + b, + e, + /* + g + */ + ... + }: + _) + ({ + b, + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + b, + e, + /* + f + */ + ... + }: + _) + ({ + b, + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + b, + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + b, + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + d + */ + e, + ... + }: + _) + ({ + b, + /* + d + */ + e, + ... + /* + h + */ + }: + _) + ({ + b, + /* + d + */ + e, + /* + g + */ + ... + }: + _) + ({ + b, + /* + d + */ + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + d + */ + e, + /* + f + */ + ... + }: + _) + ({ + b, + /* + d + */ + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + b, + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + e, + ... + }: + _) + ({ + b, + /* + c + */ + e, + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + e, + /* + g + */ + ... + }: + _) + ({ + b, + /* + c + */ + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + e, + /* + f + */ + ... + }: + _) + ({ + b, + /* + c + */ + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + b, + /* + c + */ + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + ... + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + /* + g + */ + ... + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + ... + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + e, + ... + }: + _) + ({ + /* + a + */ + b, + e, + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + e, + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + e, + /* + f + */ + ... + }: + _) + ({ + /* + a + */ + b, + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + ... + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + /* + f + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + /* + f + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + /* + g + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + ... + /* + h + */ + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + }: + _) + ({ + /* + a + */ + b, + /* + c + */ + /* + d + */ + e, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + + ({a ? null}: _) + ({ + /* + a + */ + b + /* + a + */ + ? + /* + a + */ + null, + /* + c + */ + /* + d + */ + e + /* + a + */ + ? + /* + a + */ + null, + /* + f + */ + /* + g + */ + ... + /* + h + */ + }: + _) + + ( + { + /* + a + */ + # + b + /* + a + */ + # + ? + /* + a + */ + # + null, + /* + c + */ + # + /* + d + */ + # + e + /* + a + */ + # + ? + /* + a + */ + # + null, + /* + f + */ + # + /* + g + */ + # + ... + /* + h + */ + # + } + /* + i + */ + # + : + /* + j + */ + # + _ + ) +] diff --git a/src/alejandra/tests/cases/root/out-tabs.nix b/src/alejandra/tests/cases/root/out-tabs.nix new file mode 100644 index 00000000..181ed233 --- /dev/null +++ b/src/alejandra/tests/cases/root/out-tabs.nix @@ -0,0 +1,12 @@ +/* +Some functions f + name attribute. +*/ +/* + Add to or over +derivation. + +Example: + addMetaAttrs {des +*/ +1 diff --git a/src/alejandra/tests/cases/select/out-tabs.nix b/src/alejandra/tests/cases/select/out-tabs.nix new file mode 100644 index 00000000..a856a095 --- /dev/null +++ b/src/alejandra/tests/cases/select/out-tabs.nix @@ -0,0 +1,55 @@ +[ + (a.a) + (a + . + /**/ + a) + (a + /**/ + .a) + (a + /**/ + . + /**/ + a) + (a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a) + (a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a + .a) +] diff --git a/src/alejandra/tests/cases/string/out-tabs.nix b/src/alejandra/tests/cases/string/out-tabs.nix new file mode 100644 index 00000000..646b71e4 --- /dev/null +++ b/src/alejandra/tests/cases/string/out-tabs.nix @@ -0,0 +1,91 @@ +[ + '' + foo + bar + '' + "" + ### + " + " + ### + "a + ${x} + b + " + ### + '''' + ### + ''a'' + ### + ''${""}'' + ### + '' ${""} + + '' + ### + '' a + '' + ### + '' a + + '' + ### + '' a + '' + ### + + '' a + '' + ### + '' + a + ${""} + b + ${""} + c ${""} d + e + '' + ### + '' + '' + ### + '' + declare -a makefiles=(./*.mak) + sed -i -f ${makefile-sed} "''${makefiles[@]}" + ### assign Makefile variables eagerly & change backticks to `$(shell …)` + sed -i -e 's/ = `\([^`]\+\)`/ := $(shell \1)/' \ + -e 's/`\([^`]\+\)`/$(shell \1)/' \ + "''${makefiles[@]}" + '' + ### + '' + [${mkSectionName sectName}] + '' + ### + ''-couch_ini ${cfg.package}/etc/default.ini ${configFile} ${pkgs.writeText "couchdb-extra.ini" cfg.extraConfig} ${cfg.configFile}'' + ### + ''exec i3-input -F "mark %s" -l 1 -P 'Mark: ' '' + ### + ''exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Go to: ' '' + ### + ''"${pkgs.name or ""}";'' + ### + '' + ${pkgs.replace-secret}/bin/replace-secret '${placeholder}' '${secretFile}' '${targetFile}' '' + ### + '' + mkdir -p "$out/lib/modules/${kernel.modDirVersion}/kernel/net/wireless/" + '' + ### + '' + + + ${expr "" v} + '' + + '' + --${"test"} + '' + + "--${"test"}" +] diff --git a/src/alejandra/tests/cases/string_interpol/out-tabs.nix b/src/alejandra/tests/cases/string_interpol/out-tabs.nix new file mode 100644 index 00000000..ef7feda7 --- /dev/null +++ b/src/alejandra/tests/cases/string_interpol/out-tabs.nix @@ -0,0 +1,14 @@ +"${ + /* + a + */ + "${ + /* + b + */ + "${c}" + }" + /* + d + */ +}" diff --git a/src/alejandra/tests/cases/with/out-tabs.nix b/src/alejandra/tests/cases/with/out-tabs.nix new file mode 100644 index 00000000..9985cd4c --- /dev/null +++ b/src/alejandra/tests/cases/with/out-tabs.nix @@ -0,0 +1,69 @@ +[ + (with b; c) + (with b; + /* + b + */ + c) + (with + /* + a + */ + b; c) + (with + /* + a + */ + b; + /* + b + */ + c) + (with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) + (with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc) + {a = with b; 1;} + {a = with b; 1 + 1;} + {a = with b; {c = 1;};} + { + a = with b; { + c = 1; + d = 2; + e = 3; + }; + } + { + a = with b; + # comment + 1; + } + { + a = with b; 1; + # comment + } + (with a; with b; with c; {a = 1;}) + (with a; + with b; + with c; { + a = 1; + b = 2; + }) + (with a; + /* + comment + */ + with b; + with c; { + a = 1; + b = 2; + }) + { + a = with b; with b; with b; 1; + } + { + binPath = with pkgs; + makeBinPath [ + rsync + util-linux + ]; + } +] diff --git a/src/alejandra/tests/fmt.rs b/src/alejandra/tests/fmt.rs index dadaae52..266d9c6c 100644 --- a/src/alejandra/tests/fmt.rs +++ b/src/alejandra/tests/fmt.rs @@ -14,7 +14,13 @@ fn cases() { .map(|entry| entry.unwrap().file_name().into_string().unwrap()) .collect(); - let configs = HashMap::from([("", Config::default())]); + let configs = HashMap::from([ + ("", Config::default()), + ("-tabs", Config { + indentation: String::from("\t"), + ..Default::default() + }), + ]); for case in cases { let path_in = format!("tests/cases/{}/in.nix", case); diff --git a/src/alejandra_cli/src/config_options.rs b/src/alejandra_cli/src/config_options.rs index da283b70..f382ba51 100644 --- a/src/alejandra_cli/src/config_options.rs +++ b/src/alejandra_cli/src/config_options.rs @@ -2,11 +2,17 @@ use alejandra::config::Config; use serde::Deserialize; #[derive(Deserialize)] -pub(crate) struct ConfigOptions {} +pub(crate) struct ConfigOptions { + indentation: Option, +} impl From for Config { - fn from(_config_options: ConfigOptions) -> Config { - let config = Config::default(); + fn from(config_options: ConfigOptions) -> Config { + let mut config = Config::default(); + + if let Some(indentation) = config_options.indentation { + config.indentation = indentation; + } config }