mirror of
https://github.com/nix-community/home-manager
synced 2024-11-26 21:19:45 +01:00
home-manager: rework news command
This new way of handling news should also work in Nix Flake setups.
This commit is contained in:
parent
729ab77f9e
commit
3db43afcb4
6 changed files with 158 additions and 130 deletions
54
home-manager/build-news.nix
Normal file
54
home-manager/build-news.nix
Normal file
|
@ -0,0 +1,54 @@
|
|||
# Used by the home-manager tool to present news to the user. The content of this
|
||||
# file is considered internal and the exported fields may change without
|
||||
# warning.
|
||||
|
||||
{ newsJsonFile, newsReadIdsFile ? null }:
|
||||
|
||||
let
|
||||
inherit (builtins)
|
||||
concatStringsSep filter hasAttr isString length optionalString readFile
|
||||
replaceStrings sort split;
|
||||
|
||||
newsJson = builtins.fromJSON (builtins.readFile newsJsonFile);
|
||||
|
||||
# Sorted and relevant entries.
|
||||
relevantEntries =
|
||||
sort (a: b: a.time > b.time) (filter (e: e.condition) newsJson.entries);
|
||||
|
||||
newsReadIds = if newsReadIdsFile == null then
|
||||
{ }
|
||||
else
|
||||
let ids = filter isString (split "\n" (readFile newsReadIdsFile));
|
||||
in builtins.listToAttrs (map (id: {
|
||||
name = id;
|
||||
value = null;
|
||||
}) ids);
|
||||
|
||||
newsIsRead = entry: hasAttr entry.id newsReadIds;
|
||||
|
||||
newsUnread = let pred = entry: entry.condition && !newsIsRead entry;
|
||||
in filter pred relevantEntries;
|
||||
|
||||
prettyTime = t: replaceStrings [ "T" "+00:00" ] [ " " "" ] t;
|
||||
|
||||
layoutNews = entries:
|
||||
let
|
||||
mkTextEntry = entry:
|
||||
let flag = if newsIsRead entry then "read" else "unread";
|
||||
in ''
|
||||
* ${prettyTime entry.time} [${flag}]
|
||||
|
||||
${replaceStrings [ "\n" ] [ "\n " ] entry.message}
|
||||
'';
|
||||
in concatStringsSep "\n\n" (map mkTextEntry entries);
|
||||
in {
|
||||
meta = {
|
||||
numUnread = length newsUnread;
|
||||
display = newsJson.display;
|
||||
ids = concatStringsSep "\n" (map (e: e.id) newsJson.entries);
|
||||
};
|
||||
news = {
|
||||
all = layoutNews relevantEntries;
|
||||
unread = layoutNews newsUnread;
|
||||
};
|
||||
}
|
|
@ -529,13 +529,16 @@ function doBuildFlake() {
|
|||
"${PASSTHROUGH_OPTS[@]}"
|
||||
}
|
||||
|
||||
# Presents news to the user. Takes as argument the path to a "news
|
||||
# info" file as generated by `buildNews`.
|
||||
# Presents news to the user as specified by the `news.display` option.
|
||||
function presentNews() {
|
||||
local infoFile="$1"
|
||||
local newsNixFile="$WORK_DIR/news.nix"
|
||||
buildNews "$newsNixFile"
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. "$infoFile"
|
||||
local newsDisplay
|
||||
newsDisplay="$(nix-instantiate --eval --expr "(import ${newsNixFile}).meta.display" | xargs)"
|
||||
|
||||
local newsNumUnread
|
||||
newsNumUnread="$(nix-instantiate --eval --expr "(import ${newsNixFile}).meta.numUnread" | xargs)"
|
||||
|
||||
# shellcheck disable=2154
|
||||
if [[ $newsNumUnread -eq 0 ]]; then
|
||||
|
@ -601,12 +604,9 @@ function doBuild() {
|
|||
${NO_OUT_LINK+--no-out-link} \
|
||||
--attr activationPackage \
|
||||
|| return
|
||||
|
||||
local newsInfo
|
||||
newsInfo=$(buildNews)
|
||||
|
||||
presentNews "$newsInfo"
|
||||
fi
|
||||
|
||||
presentNews
|
||||
}
|
||||
|
||||
function doSwitch() {
|
||||
|
@ -632,12 +632,9 @@ function doSwitch() {
|
|||
--out-link "$generation" \
|
||||
--attr activationPackage \
|
||||
&& "$generation/activate" || return
|
||||
|
||||
local newsInfo
|
||||
newsInfo=$(buildNews)
|
||||
|
||||
presentNews "$newsInfo"
|
||||
fi
|
||||
|
||||
presentNews
|
||||
}
|
||||
|
||||
function doListGens() {
|
||||
|
@ -718,62 +715,88 @@ function newsReadIdsFile() {
|
|||
echo "$path"
|
||||
}
|
||||
|
||||
# Builds news meta information to be sourced into this script.
|
||||
# Builds the Home Manager news data file.
|
||||
#
|
||||
# Note, we suppress build output to remove unnecessary verbosity. We
|
||||
# put the output in the work directory to avoid the risk of an
|
||||
# unfortunately timed GC removing it.
|
||||
function buildNews() {
|
||||
setFlakeAttribute
|
||||
local newsNixFile="$1"
|
||||
local newsJsonFile="$WORK_DIR/news.json"
|
||||
|
||||
if [[ -v FLAKE_CONFIG_URI ]]; then
|
||||
# translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
_iError "Sorry, this command is not yet supported in flake setup" >&2
|
||||
exit 1
|
||||
# TODO: Use check=false to make it more likely that the build succeeds.
|
||||
doBuildFlake \
|
||||
"$FLAKE_CONFIG_URI.config.news.json.output" \
|
||||
--quiet \
|
||||
--out-link "$newsJsonFile" \
|
||||
|| return
|
||||
else
|
||||
doBuildAttr \
|
||||
--out-link "$newsJsonFile" \
|
||||
--arg check false \
|
||||
--attr config.news.json.output \
|
||||
> /dev/null \
|
||||
|| return
|
||||
fi
|
||||
|
||||
local output
|
||||
output="$WORK_DIR/news-info.sh"
|
||||
local extraArgs=()
|
||||
|
||||
doBuildAttr \
|
||||
--out-link "$output" \
|
||||
--no-build-output \
|
||||
--quiet \
|
||||
--arg check false \
|
||||
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
|
||||
--attr newsInfo \
|
||||
> /dev/null
|
||||
for p in "${EXTRA_NIX_PATH[@]}"; do
|
||||
extraArgs=("${extraArgs[@]}" "-I" "$p")
|
||||
done
|
||||
|
||||
echo "$output"
|
||||
local readIdsFile
|
||||
readIdsFile=$(newsReadIdsFile)
|
||||
|
||||
nix-instantiate \
|
||||
--no-build-output --strict \
|
||||
--eval '<home-manager/home-manager/build-news.nix>' \
|
||||
--arg newsJsonFile "$newsJsonFile" \
|
||||
--arg newsReadIdsFile "$readIdsFile" \
|
||||
"${extraArgs[@]}" \
|
||||
> "$newsNixFile"
|
||||
}
|
||||
|
||||
function doShowNews() {
|
||||
setWorkDir
|
||||
setFlakeAttribute
|
||||
|
||||
local infoFile
|
||||
infoFile=$(buildNews) || return 1
|
||||
local newsNixFile="$WORK_DIR/news.nix"
|
||||
buildNews "$newsNixFile"
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
. "$infoFile"
|
||||
local readIdsFile
|
||||
readIdsFile=$(newsReadIdsFile)
|
||||
|
||||
# shellcheck disable=2154
|
||||
local news
|
||||
|
||||
# shellcheck disable=2154,2046
|
||||
case $1 in
|
||||
--all)
|
||||
${PAGER:-less} "$newsFileAll"
|
||||
news="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).news.all")"
|
||||
;;
|
||||
--unread)
|
||||
${PAGER:-less} "$newsFileUnread"
|
||||
news="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).news.unread")"
|
||||
;;
|
||||
*)
|
||||
_i 'Unknown argument %s' "$1"
|
||||
return 1
|
||||
esac
|
||||
|
||||
# shellcheck disable=2154
|
||||
if [[ -s "$newsUnreadIdsFile" ]]; then
|
||||
local newsReadIdsFile
|
||||
newsReadIdsFile="$(newsReadIdsFile)"
|
||||
cat "$newsUnreadIdsFile" >> "$newsReadIdsFile"
|
||||
fi
|
||||
# Prints the news without surrounding quotes.
|
||||
echo -e "${news:1:-1}" | ${PAGER:-less}
|
||||
|
||||
local allIds
|
||||
allIds="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).meta.ids")"
|
||||
allIds="${allIds:1:-1}" # Trim surrounding quotes.
|
||||
|
||||
local readIdsFileNew="$WORK_DIR/news-read-ids.new"
|
||||
{
|
||||
cat "$readIdsFile"
|
||||
echo -e "$allIds"
|
||||
} | sort | uniq > "$readIdsFileNew"
|
||||
|
||||
mv -f "$readIdsFileNew" "$readIdsFile"
|
||||
}
|
||||
|
||||
function doUninstall() {
|
||||
|
|
|
@ -15,60 +15,4 @@ let
|
|||
check = check;
|
||||
};
|
||||
|
||||
newsReadIds = if newsReadIdsFile == null then
|
||||
{ }
|
||||
else
|
||||
let ids = splitString "\n" (fileContents newsReadIdsFile);
|
||||
in builtins.listToAttrs (map (id: {
|
||||
name = id;
|
||||
value = null;
|
||||
}) ids);
|
||||
|
||||
newsIsRead = entry: builtins.hasAttr entry.id newsReadIds;
|
||||
|
||||
newsFiltered = let pred = entry: entry.condition && !newsIsRead entry;
|
||||
in filter pred env.newsEntries;
|
||||
|
||||
newsNumUnread = length newsFiltered;
|
||||
|
||||
newsFileUnread = pkgs.writeText "news-unread.txt" (concatMapStringsSep "\n\n"
|
||||
(entry:
|
||||
let
|
||||
time =
|
||||
replaceStrings [ "T" ] [ " " ] (removeSuffix "+00:00" entry.time);
|
||||
in ''
|
||||
* ${time}
|
||||
|
||||
${replaceStrings [ "\n" ] [ "\n " ] entry.message}
|
||||
'') newsFiltered);
|
||||
|
||||
newsFileAll = pkgs.writeText "news-all.txt" (concatMapStringsSep "\n\n"
|
||||
(entry:
|
||||
let
|
||||
flag = if newsIsRead entry then "read" else "unread";
|
||||
time =
|
||||
replaceStrings [ "T" ] [ " " ] (removeSuffix "+00:00" entry.time);
|
||||
in ''
|
||||
* ${time} [${flag}]
|
||||
|
||||
${replaceStrings [ "\n" ] [ "\n " ] entry.message}
|
||||
'') env.newsEntries);
|
||||
|
||||
# File where each line corresponds to an unread news entry
|
||||
# identifier. If non-empty then the file ends in "\n".
|
||||
newsUnreadIdsFile = pkgs.writeText "news-unread-ids"
|
||||
(let text = concatMapStringsSep "\n" (entry: entry.id) newsFiltered;
|
||||
in text + optionalString (text != "") "\n");
|
||||
|
||||
newsInfo = pkgs.writeText "news-info.sh" ''
|
||||
local newsNumUnread=${toString newsNumUnread}
|
||||
local newsDisplay="${env.newsDisplay}"
|
||||
local newsFileAll="${newsFileAll}"
|
||||
local newsFileUnread="${newsFileUnread}"
|
||||
local newsUnreadIdsFile="${newsUnreadIdsFile}"
|
||||
'';
|
||||
|
||||
in {
|
||||
inherit (env) activationPackage;
|
||||
inherit newsInfo;
|
||||
}
|
||||
in { inherit (env) activationPackage config; }
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Home Manager\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2023-07-16 10:09+0200\n"
|
||||
"POT-Creation-Date: 2023-07-30 09:08+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -78,11 +78,11 @@ msgid "Can't inspect options of a flake configuration"
|
|||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:281 home-manager/home-manager:304
|
||||
#: home-manager/home-manager:1000
|
||||
#: home-manager/home-manager:1023
|
||||
msgid "%s: unknown option '%s'"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:286 home-manager/home-manager:1001
|
||||
#: home-manager/home-manager:286 home-manager/home-manager:1024
|
||||
msgid "Run '%s --help' for usage help"
|
||||
msgstr ""
|
||||
|
||||
|
@ -124,7 +124,7 @@ msgstr ""
|
|||
msgid "Can't instantiate a flake configuration"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:549
|
||||
#: home-manager/home-manager:552
|
||||
msgid ""
|
||||
"There is %d unread and relevant news item.\n"
|
||||
"Read it by running the command \"%s news\"."
|
||||
|
@ -134,77 +134,72 @@ msgid_plural ""
|
|||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: home-manager/home-manager:563
|
||||
#: home-manager/home-manager:566
|
||||
msgid "Unknown \"news.display\" setting \"%s\"."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:570
|
||||
#: home-manager/home-manager:573
|
||||
#, sh-format
|
||||
msgid "Please set the $EDITOR environment variable"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:585
|
||||
#: home-manager/home-manager:588
|
||||
msgid "Cannot run build in read-only directory"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:669
|
||||
#: home-manager/home-manager:666
|
||||
msgid "No generation with ID %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:671
|
||||
#: home-manager/home-manager:668
|
||||
msgid "Cannot remove the current generation %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:673
|
||||
#: home-manager/home-manager:670
|
||||
msgid "Removing generation %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:692
|
||||
#: home-manager/home-manager:689
|
||||
msgid "No generations to expire"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:703
|
||||
#: home-manager/home-manager:700
|
||||
msgid "No home-manager packages seem to be installed."
|
||||
msgstr ""
|
||||
|
||||
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature.
|
||||
#: home-manager/home-manager:730
|
||||
msgid "Sorry, this command is not yet supported in flake setup"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:767
|
||||
#: home-manager/home-manager:781
|
||||
msgid "Unknown argument %s"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:783
|
||||
#: home-manager/home-manager:805
|
||||
msgid "This will remove Home Manager from your system."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:786
|
||||
#: home-manager/home-manager:808
|
||||
msgid "This is a dry run, nothing will actually be uninstalled."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:790
|
||||
#: home-manager/home-manager:812
|
||||
msgid "Really uninstall Home Manager?"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:796
|
||||
#: home-manager/home-manager:818
|
||||
msgid "Switching to empty Home Manager configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:823
|
||||
#: home-manager/home-manager:846
|
||||
msgid "Yay!"
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:828
|
||||
#: home-manager/home-manager:851
|
||||
msgid "Home Manager is uninstalled but your home.nix is left untouched."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1040
|
||||
#: home-manager/home-manager:1063
|
||||
msgid "expire-generations expects one argument, got %d."
|
||||
msgstr ""
|
||||
|
||||
#: home-manager/home-manager:1062
|
||||
#: home-manager/home-manager:1085
|
||||
msgid "Unknown command: %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -85,10 +85,22 @@ in
|
|||
default = [ ];
|
||||
description = "News entries.";
|
||||
};
|
||||
|
||||
json = {
|
||||
output = mkOption {
|
||||
internal = true;
|
||||
type = types.package;
|
||||
description = "The generated JSON file package.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
news.json.output = pkgs.writeText "hm-news.json" (builtins.toJSON {
|
||||
inherit (cfg) display entries;
|
||||
});
|
||||
|
||||
# Add news entries in chronological order (i.e., latest time
|
||||
# should be at the bottom of the list). The time should be
|
||||
# formatted as given in the output of
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Home Manager Modules\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
|
||||
"POT-Creation-Date: 2023-07-16 10:09+0200\n"
|
||||
"POT-Creation-Date: 2023-07-30 09:08+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -33,7 +33,7 @@ msgstr ""
|
|||
msgid "No change so reusing latest profile generation %s"
|
||||
msgstr ""
|
||||
|
||||
#: modules/home-environment.nix:634
|
||||
#: modules/home-environment.nix:626
|
||||
msgid ""
|
||||
"Oops, Nix failed to install your new Home Manager profile!\n"
|
||||
"\n"
|
||||
|
@ -49,7 +49,7 @@ msgid ""
|
|||
"Then try activating your Home Manager configuration again."
|
||||
msgstr ""
|
||||
|
||||
#: modules/home-environment.nix:667
|
||||
#: modules/home-environment.nix:659
|
||||
msgid "Activating %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
Loading…
Reference in a new issue