Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions wrapperModules/d/difftastic/check.nix

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x86_64-linux test run (success)
[jomarm@dell-inspiron7773:~/nix-wrapper-modules]$ nix-build --arg lib '(import <nixpkgs> {}).lib' --arg pkgs 'import <nixpkgs> {}' --arg self 'import ./. {}' --arg tlib '(import <nixpkgs> {}).callPackage ./ci/test-lib.nix { self = import ./. {}; }' wrapperModules/d/difftastic/check.nix 
these 6 derivations will be built:
  /nix/store/2q8zxnkrfjxwbxnb6pn4fpslrvvdkv8g-difftastic-0.69.0.drv
  /nix/store/5b18n6ymkyhvcazi6112gb6rsrrz3k78-difftastic-0.69.0.drv
  /nix/store/67q1294f4cg327s2q2dd6wxirhyyjg1a-difftastic-0.69.0.drv
  /nix/store/9wlffjdifnpw1qpk6vqvkm6zx3nfsv8c-difftastic-0.69.0.drv
  /nix/store/fjpl7m27a60w54maxnis1x9z0wzrjddp-difftastic-0.69.0.drv
  /nix/store/rwfxhg5vdfyfh81rylbzc18in5r9sph4-difftastic-test.drv
this path will be fetched (6.8 MiB download, 119.2 MiB unpacked):
  /nix/store/m80fwiwnsdnni2wncpyjw1pqpyzjdsss-difftastic-0.69.0
copying path '/nix/store/m80fwiwnsdnni2wncpyjw1pqpyzjdsss-difftastic-0.69.0' from 'https://cache.nixos.org'...
building '/nix/store/2q8zxnkrfjxwbxnb6pn4fpslrvvdkv8g-difftastic-0.69.0.drv'...
building '/nix/store/5b18n6ymkyhvcazi6112gb6rsrrz3k78-difftastic-0.69.0.drv'...
building '/nix/store/67q1294f4cg327s2q2dd6wxirhyyjg1a-difftastic-0.69.0.drv'...
building '/nix/store/9wlffjdifnpw1qpk6vqvkm6zx3nfsv8c-difftastic-0.69.0.drv'...
building '/nix/store/fjpl7m27a60w54maxnis1x9z0wzrjddp-difftastic-0.69.0.drv'...
/nix/store/m80fwiwnsdnni2wncpyjw1pqpyzjdsss-difftastic-0.69.0/bin:
difft: File exists
Patching self-references in specified files...
Running phase: updateAutotoolsGnuConfigScriptsPhase
/nix/store/m80fwiwnsdnni2wncpyjw1pqpyzjdsss-difftastic-0.69.0/bin:
difft: File exists
Patching self-references in specified files...
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: buildPhase
Running phase: installPhase
Running phase: buildPhase
/nix/store/m80fwiwnsdnni2wncpyjw1pqpyzjdsss-difftastic-0.69.0/bin:
difft: File exists
Patching self-references in specified files...
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: installPhase
Running phase: buildPhase
/nix/store/m80fwiwnsdnni2wncpyjw1pqpyzjdsss-difftastic-0.69.0/bin:
difft: File exists
Patching self-references in specified files...
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: installPhase
Running phase: buildPhase
Running phase: installPhase
/nix/store/m80fwiwnsdnni2wncpyjw1pqpyzjdsss-difftastic-0.69.0/bin:
difft: File exists
Patching self-references in specified files...
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: buildPhase
Running phase: installPhase
building '/nix/store/rwfxhg5vdfyfh81rylbzc18in5r9sph4-difftastic-test.drv'...
/nix/store/nslxzx8xyr2h2qkhb2za9m6k37ixn1ad-difftastic-test

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
lib,
pkgs,
self,
tlib,
...
}:

let
inherit (tlib)
fileContains
fileNotContains
test
;
wm = self.wrappers.difftastic;

in
test { wrapper = "difftastic"; } {
"wrapper should output correct version" =
let
wrapper = wm.wrap {
inherit pkgs;
};
in
''${wrapper}/bin/difft --version | grep -q "${wrapper.version}"'';

"If no config is provided then no DFT_ variables and no --override* flags in wrapper script" =
let
wrapper = wm.wrap {
inherit pkgs;
};
in
[
(fileNotContains "${wrapper}/bin/difft" "DFT_")
(fileNotContains "${wrapper}/bin/difft" "--override")
];

"If common settings set wrapper script should have DFT_ variable(s)" =
let
wrapper = wm.wrap {
inherit pkgs;
settings = {
check-only = true;
color = "never";
tab-width = 2;
};
};
in
[
(fileContains "${wrapper}/bin/difft" "DFT_CHECK_ONLY true$")
(fileContains "${wrapper}/bin/difft" "DFT_COLOR never$")
(fileContains "${wrapper}/bin/difft" "DFT_TAB_WIDTH 2$")
];

"If override setting set wrapper script should have correct --override flags and their order" =
let
wrapper = wm.wrap {
inherit pkgs;
settings = {
override = {
"*.c" = "c++";
"flake.lock" = lib.mkBefore "text";
"package.lock" = lib.mkAfter "json";
};
};
};
in
''grep -Fq -- "'--override=flake.lock:text' '--override=*.c:c++' '--override=package.lock:json'" ${wrapper}/bin/difft'';

"If override-binary setting set wrapper script should have correct --override-binary flags" =
let
wrapper = wm.wrap {
inherit pkgs;
settings = {
override-binary = [
"*.qcow2"
"file.iso"
];
};
};
in
''grep -Fq -- "'--override-binary=*.qcow2' '--override-binary=file.iso'" ${wrapper}/bin/difft'';

"If min-width setting set wrapper script should have a script to calculate and set width" =
let
wrapper = wm.wrap {
inherit pkgs;
settings = {
min-width = 120;
};
};
in
[
(fileContains "${wrapper}/bin/difft" "stty size")
(fileContains "${wrapper}/bin/difft" "wrapperSetEnvDefault DFT_WIDTH 120")
];
}
250 changes: 250 additions & 0 deletions wrapperModules/d/difftastic/module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
{ lib, wlib, pkgs, config, ... }:
let
mkEnvVarName = name: "DFT_${lib.replaceString "-" "_" (lib.toUpper name)}";

mkEnvVarValue =
value:
if builtins.isString value then
value
else if builtins.isInt value then
toString value
else if builtins.isBool value then
lib.boolToString value
else
throw "Unrecognized type ${builtins.typeOf value} in difftastic settings";

# converts single-attribute attrset to a string
mkOverrideValue = lib.attrsets.foldlAttrs (_: name: value: "${name}:${value}") "";

settingsToEnv = lib.pipe config.settings [
(lib.filterAttrs (_: value: value != null)) # settings with null values do not need to be handled
(lib.filterAttrs (name: _: ! lib.hasPrefix "override" name)) # override* settings need special handling
(lib.mapAttrs' (
name: value: lib.nameValuePair (mkEnvVarName name) (mkEnvVarValue value)
))
];
in
{
imports = [ wlib.modules.default ];
options.settings = {
background = lib.mkOption {
type = lib.types.nullOr (lib.types.enum [ "dark" "light" ]);
default = null;
description = ''
Set the background brightness.
Difftastic will prefer brighter colours on dark backgrounds.
'';
};
byte-limit = lib.mkOption {
type = lib.types.nullOr lib.types.ints.unsigned;
default = null;
description = ''
Use a line-oriented diff if either input file exceeds this size (in bytes).
'';
};
check-only = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = ''
Report whether there are any changes, but don't calculate them. Much faster.
'';
};
color = lib.mkOption {
type = lib.types.nullOr (lib.types.enum ["always" "auto" "never"]);
default = null;
description = ''
When to use color output: always, auto, never.
'';
};
context = lib.mkOption {
type = lib.types.nullOr lib.types.ints.unsigned;
default = null;
description = ''
The number of contextual lines to show around changed lines.
'';
};
display = lib.mkOption {
type = lib.types.nullOr (
lib.types.enum [
"side-by-side"
"side-by-side-show-both"
"inline"
"json"
]
);
default = null;
description = ''
Display mode for showing results.

side-by-side: Display the before file and the after file in two separate columns,
with line numbers aligned according to unchanged content.
If a change is exclusively additions or exclusively removals,
use a single column.

side-by-side-show-both: The same as side-by-side, but always uses two columns.

inline: A single column display, closer to traditional diff display.

json: Output the results as a machine-readable JSON array with an element per file."
'';
};
exit-code = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = ''
Set the exit code to 1 if there are syntactic changes in any files.
For files where there is no detected language (e.g. unsupported language or binary files),
sets the exit code if there are any byte changes.
'';
};
graph-limit = lib.mkOption {
type = lib.types.nullOr lib.types.ints.unsigned;
default = null;
description = ''
Use a line-oriented diff if the structural graph exceed this number of nodes in memory.
'';
};
ignore-comments = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = ''
Don't consider comments when diffing.
'';
};
override = lib.mkOption {
# Order for this option is important but uting just plaintext list doesn't look good nor
# efficient thus this type
type = lib.types.attrListOf lib.types.str;
default = [];
example = lib.literalExpression ''
lib.mkMerge [
{
"*.data" = lib.mkAfter "text";
"*.c" = lib.mkBefore "C++";
};
[
{ "*.js" = "javascript jsx" }
{ "CustomFile" = "json" };
]
]'';
description = ''
Associate this glob pattern with this language, overriding normal language detection.

See `difft --list-languages` for the list of language names. Language names are matched
case insensitively. Overrides may also specify the language "text" to treat a file
as plain text.

When multiple overrides are specified, the first matching override wins.

Value of this option can be either list of single-attribute attrSets,
or attribute set with values wrapped in lib.mkOrder (or lib.mkBefore/lib.mkAfter)
to control orediring.
Use lib.mkMerge or imports to use mixed formats at one place.
'';
};
override-binary = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [];
example = lib.literalExpression ''[
"*.gz"
"foo.pickle"
"*.data"
]'';
description = ''
Always treat file names matching this glob as binary files,
ignoring the default heuristics for binary detection.
'';
};
parse-error-limit = lib.mkOption {
type = lib.types.nullOr lib.types.ints.unsigned;
default = null;
description = ''
Use a line-oriented diff if the number of parse errors exceeds this value.
'';
};
skip-unchanged = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = ''
Don't display anything if a file is unchanged.
'';
};
sort-paths = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = ''
When diffing a directory, output the results sorted by path. This is slower.
'';
};
strip-cr = lib.mkOption {
type = lib.types.nullOr (lib.types.enum ["on" "off" ]);
default = null;
description = ''
Remove any carriage return characters before diffing.
This can be helpful when dealing with files on Windows that contain CRLF, i.e. `\r\n.`
'';
};
syntax-highlight = lib.mkOption {
type = lib.types.nullOr (lib.types.enum ["on" "off" ]);
default = null;
description = ''
Enable or disable syntax highlighting.
'';
};
tab-width = lib.mkOption {
type = lib.types.nullOr lib.types.ints.unsigned;
default = null;
description = ''
Treat a tab as this many spaces.
'';
};
width = lib.mkOption {
type = lib.types.nullOr lib.types.ints.unsigned;
default = null;
description = ''
Use this many columns when calculating line wrapping.
If not specified (default), difftastic will detect the terminal width.
'';
};
min-width = lib.mkOption {
type = lib.types.nullOr lib.types.ints.unsigned;
default = null;
description = ''
Custom option to prevent difftastic (in runtime) to set width lower then
the given number of columns.
Takes effect only when settings.width isn't set but still allow overriding
width by cli flag and/or env variable passed outside the wrapper settings.
'';
};
};

config = {
package = lib.mkDefault pkgs.difftastic;
envDefault = settingsToEnv;
flags."--override" = { ifs = null; sep = "="; data = map mkOverrideValue config.settings.override; };
flags."--override-binary" = { ifs = null; sep = "="; data = config.settings.override-binary; };

# min-width is need to be calculated in runtime
runShell =
lib.mkIf (config.settings.min-width != null && config.settings.width == null) [
/* bash */ ''
POSITIONAL=()
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--width=*) WIDTH="$(echo "$1" | cut -d'=' -f2)"; shift;;
-w|--width) WIDTH="$2"; shift; shift ;;
*) POSITIONAL+=("$1"); shift ;;
esac
done
set -- "''${POSITIONAL[@]}"
WIDTH="''${WIDTH:-"$(stty size | cut -d' ' -f2)"}"

[[ "$WIDTH" -lt "${toString config.settings.min-width}" ]] &&
wrapperSetEnvDefault DFT_WIDTH ${toString config.settings.min-width}
''
];

meta.maintainers = [ wlib.maintainers.alexlov ];
};
}
Loading