Restructure project:
The project has grown quite a bit without me remembering to make any commits... Here's a summary of what has happened: - Make the project friendly towards non-flake users - Add searchers to be created: `nur-package-search`, `nix-lib-search` - Add misc util scripts for formatting and testing code. - Split templates into their own directory, as they get quite large after a while. - Add colorized templates. - Replace some of the xml tags with optionally colorized output. - Add `--no-color` option - Add json2nix script, which will convert the json-converted nix code back into nix.
This commit is contained in:
parent
0aaa30346e
commit
f6217e4c54
|
@ -0,0 +1,24 @@
|
||||||
|
{ pkgs ? import <nixpkgs> { }, nixpkgs ? <nixpkgs>
|
||||||
|
, home-manager ? <home-manager>, ... }: rec {
|
||||||
|
# Applications
|
||||||
|
home-manager-search = pkgs.callPackage ./home-manager-search.nix {
|
||||||
|
inherit home-manager;
|
||||||
|
inherit (internals) json2nix;
|
||||||
|
};
|
||||||
|
|
||||||
|
nix-option-search =
|
||||||
|
pkgs.callPackage ./nix-option-search.nix { inherit nixpkgs; };
|
||||||
|
|
||||||
|
nix-package-search = pkgs.callPackage ./nix-package-search.nix { };
|
||||||
|
|
||||||
|
internals = {
|
||||||
|
# Data sources
|
||||||
|
home-manager-json = home-manager.packages.${system}.docs-json;
|
||||||
|
nix-options-json =
|
||||||
|
(import "${nixpkgs}/nixos/release.nix" { inherit nixpkgs; }).options;
|
||||||
|
nix-packages-json = pkgs.emptyFile;
|
||||||
|
|
||||||
|
# Internal Tools
|
||||||
|
json2nix = pkgs.callPackage ./internals/json2nix { };
|
||||||
|
};
|
||||||
|
}
|
42
flake.nix
42
flake.nix
|
@ -17,22 +17,50 @@
|
||||||
type = "app";
|
type = "app";
|
||||||
program = toString pkg;
|
program = toString pkg;
|
||||||
};
|
};
|
||||||
in builtins.mapAttrs toApp self.packages.${system};
|
in builtins.mapAttrs toApp {
|
||||||
|
inherit (self.packages.${system})
|
||||||
|
home-manager-search nix-option-search nix-package-search nix2json;
|
||||||
|
};
|
||||||
|
|
||||||
|
checks.${system} = let
|
||||||
|
|
||||||
|
in {
|
||||||
|
# hlint = pkgs.callPackage ./utils/hlint.nix {};
|
||||||
|
# format = pkgs.callPackage ./utils/format.nix {};
|
||||||
|
};
|
||||||
|
|
||||||
hydraJobs = with pkgs.lib;
|
hydraJobs = with pkgs.lib;
|
||||||
mapAttrs' (name: value: nameValuePair name { ${system} = value; })
|
mapAttrs' (name: value: nameValuePair name { ${system} = value; })
|
||||||
self.packages.${system};
|
self.packages.${system};
|
||||||
|
|
||||||
packages.${system} = {
|
packages.${system} = {
|
||||||
|
# Applications
|
||||||
home-manager-search =
|
home-manager-search =
|
||||||
pkgs.callPackage ./home-manager-search.nix { inherit home-manager; };
|
pkgs.callPackage ./searchers/home-manager-search.nix {
|
||||||
nix-option-search = pkgs.callPackage ./nix-option-search.nix { };
|
inherit home-manager;
|
||||||
nix-package-search = pkgs.callPackage ./nix-package-search.nix { };
|
inherit (self.packages.${system}) json2nix;
|
||||||
|
};
|
||||||
|
nix-option-search = pkgs.callPackage ./searchers/nix-option-search.nix {
|
||||||
|
inherit nixpkgs;
|
||||||
|
};
|
||||||
|
nix-package-search =
|
||||||
|
pkgs.callPackage ./searchers/nix-package-search.nix { };
|
||||||
|
nix-lib-search = pkgs.callPackage ./searchers/nix-lib-search.nix { };
|
||||||
|
nur-package-search =
|
||||||
|
pkgs.callPackage ./searchers/nur-package-search.nix { };
|
||||||
|
|
||||||
|
# Data sources
|
||||||
|
home-manager-json = home-manager.packages.${system}.docs-json;
|
||||||
|
nix-options-json =
|
||||||
|
(import "${nixpkgs}/nixos/release.nix" { inherit nixpkgs; }).options;
|
||||||
|
# nix-packages-json = pkgs.emptyFile;
|
||||||
|
|
||||||
|
# Internal Tools
|
||||||
|
json2nix = pkgs.callPackage ./internals/json2nix { };
|
||||||
};
|
};
|
||||||
|
|
||||||
overlays.default = final: prev: prev // self.packages.${system};
|
overlays.default = _: prev: prev // self.packages.${system};
|
||||||
|
|
||||||
devShells.${system}.default =
|
devShells.${system}.default = pkgs.callPackage ./shell.nix { };
|
||||||
pkgs.mkShell { packages = with pkgs; [ nixfmt ]; };
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
{ pkgs, lib, home-manager, system, ... }:
|
|
||||||
let
|
|
||||||
|
|
||||||
# TODO: Preprocess XML tags in description.
|
|
||||||
|
|
||||||
# TODO: Make non-literal examples have better syntax highlighting
|
|
||||||
|
|
||||||
# TODO: Colorize preview
|
|
||||||
|
|
||||||
usage = pkgs.writeText "home-manager-search-usage" ''
|
|
||||||
Usage:
|
|
||||||
home-manager-search [ -j | -n ] [-f=<flake-url> [-r=<git-reference>]]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-h | --help Display this message.
|
|
||||||
-j | --json Display raw data in json format.
|
|
||||||
-n | --no-preview Don't display a preview.
|
|
||||||
-f=* | --flake=* Use a flake url to an instance (e.g. a fork) of home-manager,
|
|
||||||
generate its options, and use those instead of the global ones.
|
|
||||||
-r=* | --ref=* If a flake url is specified, this option might be used to choose
|
|
||||||
a specific reference (branch, tag, commit, etc.) to use for
|
|
||||||
generating the docs.
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
home-manager-search
|
|
||||||
home-manager-search -j
|
|
||||||
home-manager-search --flake="github:nix-community/home-manager"
|
|
||||||
home-manager-search --flake="github:nix-community/home-manager" --ref="release-22.05"
|
|
||||||
'';
|
|
||||||
|
|
||||||
inherit (pkgs.callPackage ./shared.nix { })
|
|
||||||
jq fzf gomplate blinkred clear flatten;
|
|
||||||
|
|
||||||
template = pkgs.writeText "preview-home-manager-attrs-template" (flatten ''
|
|
||||||
{{ with (ds "opt")}}
|
|
||||||
{{- $title := join .loc "." }}
|
|
||||||
{{- $title }}
|
|
||||||
{{ strings.Repeat (strings.RuneCount $title) "=" }}
|
|
||||||
|
|
||||||
{{ if .readOnly }}
|
|
||||||
${blinkred}READONLY${clear}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
Type: {{ .type }}
|
|
||||||
|
|
||||||
{{ if has . "description" }}
|
|
||||||
DESCRIPTION
|
|
||||||
{{ strings.Repeat 20 "=" }}
|
|
||||||
{{ .description }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{- if has . "example" }}
|
|
||||||
EXAMPLE
|
|
||||||
{{ strings.Repeat 20 "=" }}
|
|
||||||
{{ if and (has .example "_type") }}
|
|
||||||
{{ else }}
|
|
||||||
{{ data.ToJSONPretty " " .example }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{- if has . "default" }}
|
|
||||||
DEFAULT
|
|
||||||
{{ strings.Repeat 20 "=" }}
|
|
||||||
{{ .default }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
CONFIGURED IN:
|
|
||||||
{{ strings.Repeat 20 "=" }}
|
|
||||||
{{ range .declarations }}
|
|
||||||
{{- .path }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ else }}
|
|
||||||
ERROR: Could not find datasource
|
|
||||||
{{ end }}
|
|
||||||
'');
|
|
||||||
|
|
||||||
previewJson = pkgs.writers.writeBash "preview-home-manager-attrs-json" ''
|
|
||||||
OPTION_KEY=$1
|
|
||||||
JSON_MANUAL_PATH=$2
|
|
||||||
|
|
||||||
${jq} -C ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH
|
|
||||||
'';
|
|
||||||
|
|
||||||
previewGomplate =
|
|
||||||
pkgs.writers.writeBash "preview-home-manager-attrs-gomplate" ''
|
|
||||||
OPTION_KEY=$1
|
|
||||||
JSON_MANUAL_PATH=$2
|
|
||||||
|
|
||||||
${jq} ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH | ${gomplate} --datasource opt=stdin:?type=application/json --file ${template}
|
|
||||||
'';
|
|
||||||
|
|
||||||
defaultManualPath = "${
|
|
||||||
home-manager.packages.${system}.docs-json
|
|
||||||
}/share/doc/home-manager/options.json";
|
|
||||||
|
|
||||||
in pkgs.writers.writeBash "search-home-manager-attrs" ''
|
|
||||||
JSON_MANUAL_PATH="${defaultManualPath}"
|
|
||||||
|
|
||||||
for i in "$@"; do
|
|
||||||
case $i in
|
|
||||||
-h|--help)
|
|
||||||
cat ${usage}
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
-j|--json)
|
|
||||||
PRINT_JSON=1
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-n|--no-preview)
|
|
||||||
NO_PREVIEW=1
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-f=*|--flake=*)
|
|
||||||
FLAKE="''${i#*=}"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-r=*|--ref=*)
|
|
||||||
REF="''${i#*=}"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*|-*|--*)
|
|
||||||
echo "Unknown option $i"
|
|
||||||
cat ${usage}
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -v PRINT_JSON ] && [ -v NO_PREVIEW ]; then
|
|
||||||
echo "Cannot preview as json with no-preview enabled"
|
|
||||||
cat ${usage}
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -v FLAKE ]; then
|
|
||||||
FLAKE_URL="''${FLAKE}"
|
|
||||||
|
|
||||||
if [ -v REF ]; then
|
|
||||||
FLAKE_URL="''${FLAKE_URL}?ref=$REF"
|
|
||||||
fi
|
|
||||||
|
|
||||||
FLAKE_URL="''${FLAKE_URL}#docs-json"
|
|
||||||
echo "Building docs from $FLAKE_URL"
|
|
||||||
|
|
||||||
OUT_PATH=$(${pkgs.nix}/bin/nix build "$FLAKE_URL" --no-link --print-out-paths --no-write-lock-file)
|
|
||||||
JSON_MANUAL_PATH="$OUT_PATH/share/doc/home-manager/options.json"
|
|
||||||
echo "Using docs located at $JSON_MANUAL_PATH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -v NO_PREVIEW ]; then
|
|
||||||
${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf}
|
|
||||||
elif [ -v PRINT_JSON ]; then
|
|
||||||
${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewJson} {} $JSON_MANUAL_PATH"
|
|
||||||
else
|
|
||||||
${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewGomplate} {} $JSON_MANUAL_PATH"
|
|
||||||
fi
|
|
||||||
''
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.writers.writeHaskellBin "json2nix" {
|
||||||
|
libraries = with pkgs.haskellPackages; [ aeson ];
|
||||||
|
} (builtins.readFile ./json2nix.hs)
|
|
@ -0,0 +1,35 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
import Data.Aeson (Value(..), decode)
|
||||||
|
import Data.Aeson.Key (Key, toString)
|
||||||
|
import Data.Aeson.KeyMap (foldMapWithKey)
|
||||||
|
import Data.Aeson.Parser (json')
|
||||||
|
import Data.Aeson.Types (parse)
|
||||||
|
import Data.String (fromString)
|
||||||
|
import Data.Text (Text(..), unpack, replace, isInfixOf)
|
||||||
|
import Data.Vector (Vector)
|
||||||
|
import Data.Maybe (fromMaybe)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = interact f
|
||||||
|
where
|
||||||
|
f input = case decode $ fromString input of
|
||||||
|
Nothing -> "json2nix error - could not parse input\n" ++ show input
|
||||||
|
Just jsonValue -> json2Nix jsonValue
|
||||||
|
|
||||||
|
keyValToString :: Key -> Value -> String
|
||||||
|
keyValToString key value = toString key ++ " = " ++ json2Nix value ++ ";"
|
||||||
|
|
||||||
|
-- escapeDollar :: Text -> Text
|
||||||
|
-- escapeDollar = replace "''${" "\\''${"
|
||||||
|
|
||||||
|
json2Nix :: Value -> String
|
||||||
|
json2Nix (Object object) = "{" ++ foldMapWithKey keyValToString object ++ "}"
|
||||||
|
json2Nix (Array array) = "[" ++ foldr (\x y -> x ++ " " ++ y) "" (fmap json2Nix array) ++ "]"
|
||||||
|
json2Nix (Number n) = show n
|
||||||
|
json2Nix (Bool False) = "false"
|
||||||
|
json2Nix (Bool True) = "true"
|
||||||
|
json2Nix Null = "null"
|
||||||
|
json2Nix (String text) = sep ++ unpack text ++ sep
|
||||||
|
where
|
||||||
|
sep = if "\"" `isInfixOf` text then "\'\'" else "\""
|
|
@ -0,0 +1,59 @@
|
||||||
|
{ pkgs, lib, ... }: {
|
||||||
|
# Executables
|
||||||
|
jq = "${pkgs.jq}/bin/jq";
|
||||||
|
fzf = "${pkgs.fzf}/bin/fzf";
|
||||||
|
gomplate = "${pkgs.gomplate}/bin/gomplate";
|
||||||
|
nixfmt = "${pkgs.nixfmt}/bin/nixfmt";
|
||||||
|
bat = "${pkgs.bat}/bin/bat";
|
||||||
|
perl = "${pkgs.perl}/bin/perl";
|
||||||
|
|
||||||
|
# ANSI Colors
|
||||||
|
bold = "\\x1b[1m";
|
||||||
|
blinkred = "\\x1b[31;5m";
|
||||||
|
red = "\\x1b[31m";
|
||||||
|
green = "\\x1b[32m";
|
||||||
|
yellow = "\\x1b[33m";
|
||||||
|
blue = "\\x1b[34m";
|
||||||
|
magenta = "\\x1b[35m";
|
||||||
|
clear = "\\x1b[0m";
|
||||||
|
|
||||||
|
# Misc functionality
|
||||||
|
|
||||||
|
# flatten takes a string that might be formatted like this:
|
||||||
|
#
|
||||||
|
# ''
|
||||||
|
# A string
|
||||||
|
# with some random indents
|
||||||
|
#
|
||||||
|
# and
|
||||||
|
#
|
||||||
|
# newlines
|
||||||
|
# ''
|
||||||
|
#
|
||||||
|
# And turns it into this:
|
||||||
|
#
|
||||||
|
# ''
|
||||||
|
# A string
|
||||||
|
# with some random indents
|
||||||
|
# and
|
||||||
|
# newlines
|
||||||
|
# ''
|
||||||
|
#
|
||||||
|
# Useful for keeping track of gomplates logic
|
||||||
|
# while keeping the template flat
|
||||||
|
#
|
||||||
|
# flatten :: String -> String
|
||||||
|
flatten = with lib;
|
||||||
|
let
|
||||||
|
stripPrefixSpace = s:
|
||||||
|
if hasPrefix " " s then
|
||||||
|
stripPrefixSpace ((substring 1 (stringLength s)) s)
|
||||||
|
else
|
||||||
|
s;
|
||||||
|
in (flip pipe) [
|
||||||
|
(splitString "\n")
|
||||||
|
(remove "")
|
||||||
|
(map stripPrefixSpace)
|
||||||
|
(concatStringsSep "\n")
|
||||||
|
];
|
||||||
|
}
|
|
@ -1 +0,0 @@
|
||||||
{ pkgs, ... }: pkgs.emptyFile
|
|
|
@ -1 +0,0 @@
|
||||||
{ pkgs, ... }: pkgs.emptyFile
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
{ pkgs, lib, home-manager, system, json2nix, ... }:
|
||||||
|
let
|
||||||
|
usage = pkgs.writeText "home-manager-search-usage" ''
|
||||||
|
Usage:
|
||||||
|
home-manager-search [ -j | -n ] [-f=<flake-url> [-r=<git-reference>]]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h | --help Display this message.
|
||||||
|
-j | --json Display raw data in json format.
|
||||||
|
-np | --no-preview Don't display a preview.
|
||||||
|
-nc | --no-color Turn off ANSI colors.
|
||||||
|
-f=* | --flake=* Use a flake url to an instance (e.g. a fork) of home-manager,
|
||||||
|
generate its options, and use those instead of the global ones.
|
||||||
|
-r=* | --ref=* If a flake url is specified, this option might be used to choose
|
||||||
|
a specific reference (branch, tag, commit, etc.) to use for
|
||||||
|
generating the docs.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
home-manager-search
|
||||||
|
home-manager-search -j
|
||||||
|
home-manager-search --flake="github:nix-community/home-manager"
|
||||||
|
home-manager-search --flake="github:nix-community/home-manager" --ref="release-22.05"
|
||||||
|
'';
|
||||||
|
|
||||||
|
inherit (pkgs.callPackage ../internals/lib.nix { })
|
||||||
|
jq fzf gomplate nixfmt bat perl blinkred bold red green yellow blue magenta
|
||||||
|
clear flatten;
|
||||||
|
|
||||||
|
# TODO: Preprocess all XML tags in description.
|
||||||
|
substitutionsColor = let s = "\\s*";
|
||||||
|
in {
|
||||||
|
"<code>([^>]*)</code>" = "${bold}`$1`${clear}";
|
||||||
|
"<command>([^>]*)</command>" = "${bold}`$1`${clear}";
|
||||||
|
"<filename>([^>]*)</filename>" = "${yellow}$1${clear}";
|
||||||
|
"<emphasis>([^>]*)</emphasis>" = "${bold}$1${clear}";
|
||||||
|
"<literal>([^>]*)</literal>" = "${red}$1${clear}";
|
||||||
|
"<varname>([^>]*)</varname>" = "${red}$1${clear}";
|
||||||
|
"</para><para>" = "\\n";
|
||||||
|
"<link${s}xlink:href=\"([^>]*)\"${s}/>" = "${blue}$1${clear}";
|
||||||
|
"<link${s}xlink:href=\"([^>]*)\"${s}>([^<]*)</link>" = "${bold}$2 ${clear}(${blue}$1${clear})";
|
||||||
|
"<xref${s}linkend=\"opt-([^>]*)\"${s}/>" = "${blue}$1${clear}";
|
||||||
|
};
|
||||||
|
|
||||||
|
substitutions = let s = "\\s*";
|
||||||
|
in {
|
||||||
|
"<code>([^>]*)</code>" = "`$1`";
|
||||||
|
"<command>([^>]*)</command>" = "`$1`";
|
||||||
|
"<filename>([^>]*)</filename>" = "`$1`";
|
||||||
|
"<emphasis>([^>]*)</emphasis>" = "`$1`";
|
||||||
|
"<literal>([^>]*)</literal>" = "`$1`";
|
||||||
|
"<varname>([^>]*)</varname>" = "`$1`";
|
||||||
|
"</para><para>" = "\\n";
|
||||||
|
"<link${s}xlink:href=\"([^>]*)\"${s}/>" = "`$1`";
|
||||||
|
"<link${s}xlink:href=\"([^>]*)\"${s}>([^<]*)</link>" = "`$2 ($1)`";
|
||||||
|
"<xref${s}linkend=\"opt-([^>]*)\"${s}/>" = "`$1`";
|
||||||
|
};
|
||||||
|
|
||||||
|
perlArgsColor = with lib;
|
||||||
|
pipe substitutionsColor [
|
||||||
|
(mapAttrsToList (name: value: "s|${name}|${value}|gm"))
|
||||||
|
(concatStringsSep ";")
|
||||||
|
(x: "-pe '${x}'")
|
||||||
|
];
|
||||||
|
|
||||||
|
perlArgs = with lib;
|
||||||
|
pipe substitutions [
|
||||||
|
(mapAttrsToList (name: value: "s|${name}|${value}|gm"))
|
||||||
|
(concatStringsSep ";")
|
||||||
|
(x: "-pe '${x}'")
|
||||||
|
];
|
||||||
|
|
||||||
|
optionTemplateColor =
|
||||||
|
pkgs.callPackage ../templates/option-preview-template-color.nix { };
|
||||||
|
|
||||||
|
optionTemplate =
|
||||||
|
pkgs.callPackage ../templates/option-preview-template.nix { };
|
||||||
|
|
||||||
|
# TODO: This preview does not respect the color option...
|
||||||
|
previewJson = pkgs.writers.writeBash "preview-home-manager-attrs-json" ''
|
||||||
|
OPTION_KEY=$1
|
||||||
|
JSON_MANUAL_PATH=$2
|
||||||
|
|
||||||
|
${jq} -C ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH
|
||||||
|
'';
|
||||||
|
|
||||||
|
previewGomplate = isColorized: let
|
||||||
|
# TODO: Color management here needs a refactoring badly...
|
||||||
|
pArgs = if isColorized then perlArgsColor else perlArgs;
|
||||||
|
colorSuffix = if isColorized then "-color" else "";
|
||||||
|
batColorArg = if isColorized then "--color=always " else "";
|
||||||
|
template = if isColorized then optionTemplateColor else optionTemplate;
|
||||||
|
in pkgs.writers.writeBash "preview-home-manager-attrs-gomplate${colorSuffix}" ''
|
||||||
|
OPTION_KEY=$1
|
||||||
|
JSON_MANUAL_PATH=$2
|
||||||
|
|
||||||
|
JSON_DATA=$(${jq} ".\"$OPTION_KEY\"" $JSON_MANUAL_PATH)
|
||||||
|
export DESCRIPTION=$(echo $JSON_DATA | ${jq} -r ".description" | ${perl} ${pArgs})
|
||||||
|
export EXAMPLE=$(echo $JSON_DATA | ${jq} -r ".example | try(.text) // ." | ${bat} ${batColorArg}--style=numbers)
|
||||||
|
export DEFAULT=$(echo $JSON_DATA | ${jq} -r ".default" | ${json2nix}/bin/json2nix | ${nixfmt} | ${bat} ${batColorArg}--style=numbers)
|
||||||
|
echo $JSON_DATA | ${gomplate} --datasource opt=stdin:?type=application/json --file ${template}
|
||||||
|
'';
|
||||||
|
|
||||||
|
defaultManualPath = "${
|
||||||
|
home-manager.packages.${system}.docs-json
|
||||||
|
}/share/doc/home-manager/options.json";
|
||||||
|
|
||||||
|
in pkgs.writers.writeBash "search-home-manager-attrs" ''
|
||||||
|
JSON_MANUAL_PATH="${defaultManualPath}"
|
||||||
|
|
||||||
|
for i in "$@"; do
|
||||||
|
case $i in
|
||||||
|
-h|--help)
|
||||||
|
cat ${usage}
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-j|--json)
|
||||||
|
PRINT_JSON=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-np|--no-preview)
|
||||||
|
NO_PREVIEW=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-nc|--no-color)
|
||||||
|
NO_COLOR=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-f=*|--flake=*)
|
||||||
|
FLAKE="''${i#*=}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-r=*|--ref=*)
|
||||||
|
REF="''${i#*=}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*|-*|--*)
|
||||||
|
echo "Unknown option $i"
|
||||||
|
cat ${usage}
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -v PRINT_JSON ] && [ -v NO_PREVIEW ]; then
|
||||||
|
echo "Cannot preview as json with no-preview enabled"
|
||||||
|
cat ${usage}
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -v FLAKE ]; then
|
||||||
|
FLAKE_URL="''${FLAKE}"
|
||||||
|
|
||||||
|
if [ -v REF ]; then
|
||||||
|
FLAKE_URL="''${FLAKE_URL}?ref=$REF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
FLAKE_URL="''${FLAKE_URL}#docs-json"
|
||||||
|
echo "Building docs from $FLAKE_URL"
|
||||||
|
|
||||||
|
OUT_PATH=$(${pkgs.nix}/bin/nix build "$FLAKE_URL" --no-link --print-out-paths --no-write-lock-file)
|
||||||
|
JSON_MANUAL_PATH="$OUT_PATH/share/doc/home-manager/options.json"
|
||||||
|
echo "Using docs located at $JSON_MANUAL_PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -v NO_PREVIEW ]; then
|
||||||
|
${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf}
|
||||||
|
elif [ -v PRINT_JSON ]; then
|
||||||
|
${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewJson} {} $JSON_MANUAL_PATH"
|
||||||
|
elif [ -v NO_COLOR ]; then
|
||||||
|
${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewGomplate false} {} $JSON_MANUAL_PATH"
|
||||||
|
else
|
||||||
|
${jq} -r 'keys | .[] | .' $JSON_MANUAL_PATH | ${fzf} --preview "${previewGomplate true} {} $JSON_MANUAL_PATH"
|
||||||
|
fi
|
||||||
|
''
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# TODO:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.emptyFile
|
|
@ -0,0 +1,2 @@
|
||||||
|
# TODO:
|
||||||
|
{ pkgs, ... }: pkgs.emptyFile
|
|
@ -0,0 +1,3 @@
|
||||||
|
# TODO:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.emptyFile
|
|
@ -0,0 +1,3 @@
|
||||||
|
# TODO:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.emptyFile
|
28
shared.nix
28
shared.nix
|
@ -1,28 +0,0 @@
|
||||||
{ pkgs, lib, ... }: {
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
jq = "${pkgs.jq}/bin/jq";
|
|
||||||
fzf = "${pkgs.fzf}/bin/fzf";
|
|
||||||
gomplate = "${pkgs.gomplate}/bin/gomplate";
|
|
||||||
|
|
||||||
# ANSI Colors
|
|
||||||
blinkred = "\\033[31;5m";
|
|
||||||
clear = "\\033[0m";
|
|
||||||
|
|
||||||
# Misc functionality
|
|
||||||
|
|
||||||
# All empty lines, and all prefixed whitespace is removed.
|
|
||||||
flatten = with lib;
|
|
||||||
let
|
|
||||||
stripPrefixSpace = s:
|
|
||||||
if hasPrefix " " s then
|
|
||||||
stripPrefixSpace ((substring 1 (stringLength s)) s)
|
|
||||||
else
|
|
||||||
s;
|
|
||||||
in (flip pipe) [
|
|
||||||
(splitString "\n")
|
|
||||||
(remove "")
|
|
||||||
(map stripPrefixSpace)
|
|
||||||
(concatStringsSep "\n")
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ pkgs }:
|
||||||
|
pkgs.mkShell {
|
||||||
|
packages = with pkgs; [ nixfmt hlint jq bat gomplate ];
|
||||||
|
|
||||||
|
shellHook = let
|
||||||
|
format = pkgs.callPackage ./utils/format.nix { };
|
||||||
|
hlint = pkgs.callPackage ./utils/hlint.nix { };
|
||||||
|
in ''
|
||||||
|
alias nasf=${format}/bin/nix-attrs-search-format
|
||||||
|
alias nashl=${hlint}/bin/nix-attrs-search-hlint
|
||||||
|
'';
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
{ pkgs }:
|
||||||
|
let
|
||||||
|
inherit (pkgs.callPackage ../internals/lib.nix { })
|
||||||
|
flatten red bold blinkred green yellow magenta blue clear;
|
||||||
|
in pkgs.writeText "nix-attrs-search-internal-option-template" (flatten ''
|
||||||
|
{{ define "colorize" -}}
|
||||||
|
{{ strings.ShellQuote . | strings.Trim "'" }}
|
||||||
|
{{- end -}}
|
||||||
|
{{ with (ds "opt")}}
|
||||||
|
{{- $origTitle := join .loc "." }}
|
||||||
|
{{- $title := join .loc "." | regexp.Replace "(<name>)" "${red}$1${clear}${bold}" }}
|
||||||
|
{{- template "colorize" "${bold}" -}}
|
||||||
|
{{- template "colorize" $title }}
|
||||||
|
{{ strings.Repeat (strings.RuneCount $origTitle) "=" }}
|
||||||
|
{{- template "colorize" "${clear}" }}
|
||||||
|
|
||||||
|
{{ if .readOnly }}
|
||||||
|
{{ template "colorize" "${blinkred}READONLY${clear}" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ template "colorize" "${green}" -}}
|
||||||
|
Type: {{ .type }}
|
||||||
|
{{- template "colorize" "${clear}" }}
|
||||||
|
|
||||||
|
{{ if has . "description" }}
|
||||||
|
{{ template "colorize" "${yellow}" -}}
|
||||||
|
DESCRIPTION
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{- template "colorize" "${clear}" }}
|
||||||
|
{{ getenv "DESCRIPTION" "Gomplate error: could not fetch description" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "example" }}
|
||||||
|
{{ template "colorize" "${magenta}" -}}
|
||||||
|
EXAMPLE
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{- template "colorize" "${clear}" }}
|
||||||
|
{{ getenv "EXAMPLE" "Gomplate error: could not fetch example" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "default" }}
|
||||||
|
{{ template "colorize" "${blue}" -}}
|
||||||
|
DEFAULT
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{- template "colorize" "${clear}" }}
|
||||||
|
{{ getenv "DEFAULT" "Gomplate error: could not fetch default value" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "declarations" }}
|
||||||
|
{{ template "colorize" "${red}" -}}
|
||||||
|
CONFIGURED IN
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{- template "colorize" "${clear}" }}
|
||||||
|
{{ range .declarations }}
|
||||||
|
{{- .path }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "relatedPackages" }}
|
||||||
|
RELATED PACKAGES:
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{ range .relatedPackages }}
|
||||||
|
{{- .attrName }}
|
||||||
|
{{- .description }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ else }}
|
||||||
|
ERROR: Could not find datasource
|
||||||
|
{{ end }}
|
||||||
|
'')
|
|
@ -0,0 +1,54 @@
|
||||||
|
{ pkgs }:
|
||||||
|
let inherit (pkgs.callPackage ../internals/lib.nix { }) flatten;
|
||||||
|
in pkgs.writeText "nix-attrs-search-internal-option-template" (flatten ''
|
||||||
|
{{ with (ds "opt")}}
|
||||||
|
{{- $origTitle := join .loc "." }}
|
||||||
|
{{- $title := join .loc "." }}
|
||||||
|
{{- $title }}
|
||||||
|
{{ strings.Repeat (strings.RuneCount $origTitle) "=" }}
|
||||||
|
|
||||||
|
{{ if .readOnly }}
|
||||||
|
READONLY
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
Type: {{ .type }}
|
||||||
|
|
||||||
|
{{ if has . "description" }}
|
||||||
|
DESCRIPTION
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{ getenv "DESCRIPTION" "Gomplate error: could not fetch description" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "example" }}
|
||||||
|
EXAMPLE
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{ getenv "EXAMPLE" "Gomplate error: could not fetch example" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "default" }}
|
||||||
|
DEFAULT
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{ getenv "DEFAULT" "Gomplate error: could not fetch default value" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "declarations" }}
|
||||||
|
CONFIGURED IN
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{ range .declarations }}
|
||||||
|
{{- .path }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{- if has . "relatedPackages" }}
|
||||||
|
RELATED PACKAGES:
|
||||||
|
{{ strings.Repeat 20 "=" }}
|
||||||
|
{{ range .relatedPackages }}
|
||||||
|
{{- .attrName }}
|
||||||
|
{{- .description }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ else }}
|
||||||
|
ERROR: Could not find datasource
|
||||||
|
{{ end }}
|
||||||
|
'')
|
|
@ -0,0 +1,3 @@
|
||||||
|
# TODO:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.emptyFile
|
|
@ -0,0 +1,3 @@
|
||||||
|
# TODO:
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.emptyFile
|
|
@ -0,0 +1,4 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.writeScriptBin "nix-attrs-search-format" ''
|
||||||
|
find -name '*.nix' -exec '${pkgs.nixfmt}/bin/nixfmt' {} \;
|
||||||
|
''
|
|
@ -0,0 +1,4 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.writeScriptBin "nix-attrs-search-hlint" ''
|
||||||
|
find -name '*.hs' -exec '${pkgs.hlint}/bin/hlint' {} \;
|
||||||
|
''
|
|
@ -0,0 +1,17 @@
|
||||||
|
{ pkgs, home-manager-options, json2nix }:
|
||||||
|
pkgs.writers.writeBash "nix-attrs-search-test-json2nix" ''
|
||||||
|
ELEMENT_COUNT=$(${jq} 'keys | length' ${home-manager-options}/share/doc/home-manager/options.json)
|
||||||
|
echo "Trying $(($ELEMENT_COUNT - 1)) elements"
|
||||||
|
for i in $(seq 0 $(($ELEMENT_COUNT - 1))); do
|
||||||
|
if ! (($i % 100)); then
|
||||||
|
echo "$i..."
|
||||||
|
fi
|
||||||
|
DEFAULT_VAL=$(${jq} "[.[]][$i].default" ${home-manager-options}/share/doc/home-manager/options.json)
|
||||||
|
ERROR_MESSAGE=$( { echo $DEFAULT_VAL | ${json2nix} | ${nixfmt} } 2>&1 )
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
echo "[$i] ERROR:"
|
||||||
|
echo $DEFAULT_VAL
|
||||||
|
echo $ERROR_MESSAGE
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
''
|
Loading…
Reference in New Issue