-
Notifications
You must be signed in to change notification settings - Fork 51
feat(wrapperModules.difftastic): init #574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AlexLov
wants to merge
1
commit into
BirdeeHub:main
Choose a base branch
from
AlexLov:add-difftastic-module
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+347
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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") | ||
| ]; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 ]; | ||
| }; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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)