1
0
Fork 0
mirror of https://github.com/nix-community/home-manager synced 2024-11-27 05:29:46 +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:
Robert Helgesson 2023-07-29 19:56:00 +02:00
parent 729ab77f9e
commit 3db43afcb4
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
6 changed files with 158 additions and 130 deletions

View 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;
};
}

View file

@ -529,13 +529,16 @@ function doBuildFlake() {
"${PASSTHROUGH_OPTS[@]}" "${PASSTHROUGH_OPTS[@]}"
} }
# Presents news to the user. Takes as argument the path to a "news # Presents news to the user as specified by the `news.display` option.
# info" file as generated by `buildNews`.
function presentNews() { function presentNews() {
local infoFile="$1" local newsNixFile="$WORK_DIR/news.nix"
buildNews "$newsNixFile"
# shellcheck source=/dev/null local newsDisplay
. "$infoFile" 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 # shellcheck disable=2154
if [[ $newsNumUnread -eq 0 ]]; then if [[ $newsNumUnread -eq 0 ]]; then
@ -601,12 +604,9 @@ function doBuild() {
${NO_OUT_LINK+--no-out-link} \ ${NO_OUT_LINK+--no-out-link} \
--attr activationPackage \ --attr activationPackage \
|| return || return
local newsInfo
newsInfo=$(buildNews)
presentNews "$newsInfo"
fi fi
presentNews
} }
function doSwitch() { function doSwitch() {
@ -632,12 +632,9 @@ function doSwitch() {
--out-link "$generation" \ --out-link "$generation" \
--attr activationPackage \ --attr activationPackage \
&& "$generation/activate" || return && "$generation/activate" || return
local newsInfo
newsInfo=$(buildNews)
presentNews "$newsInfo"
fi fi
presentNews
} }
function doListGens() { function doListGens() {
@ -718,62 +715,88 @@ function newsReadIdsFile() {
echo "$path" 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 # Note, we suppress build output to remove unnecessary verbosity. We
# put the output in the work directory to avoid the risk of an # put the output in the work directory to avoid the risk of an
# unfortunately timed GC removing it. # unfortunately timed GC removing it.
function buildNews() { function buildNews() {
setFlakeAttribute local newsNixFile="$1"
local newsJsonFile="$WORK_DIR/news.json"
if [[ -v FLAKE_CONFIG_URI ]]; then if [[ -v FLAKE_CONFIG_URI ]]; then
# translators: Here "flake" is a noun that refers to the Nix Flakes feature. # TODO: Use check=false to make it more likely that the build succeeds.
_iError "Sorry, this command is not yet supported in flake setup" >&2 doBuildFlake \
exit 1 "$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 fi
local output local extraArgs=()
output="$WORK_DIR/news-info.sh"
doBuildAttr \ for p in "${EXTRA_NIX_PATH[@]}"; do
--out-link "$output" \ extraArgs=("${extraArgs[@]}" "-I" "$p")
--no-build-output \ done
--quiet \
--arg check false \
--argstr newsReadIdsFile "$(newsReadIdsFile)" \
--attr newsInfo \
> /dev/null
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() { function doShowNews() {
setWorkDir setWorkDir
setFlakeAttribute
local infoFile local newsNixFile="$WORK_DIR/news.nix"
infoFile=$(buildNews) || return 1 buildNews "$newsNixFile"
# shellcheck source=/dev/null local readIdsFile
. "$infoFile" readIdsFile=$(newsReadIdsFile)
# shellcheck disable=2154 local news
# shellcheck disable=2154,2046
case $1 in case $1 in
--all) --all)
${PAGER:-less} "$newsFileAll" news="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).news.all")"
;; ;;
--unread) --unread)
${PAGER:-less} "$newsFileUnread" news="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).news.unread")"
;; ;;
*) *)
_i 'Unknown argument %s' "$1" _i 'Unknown argument %s' "$1"
return 1 return 1
esac esac
# shellcheck disable=2154 # Prints the news without surrounding quotes.
if [[ -s "$newsUnreadIdsFile" ]]; then echo -e "${news:1:-1}" | ${PAGER:-less}
local newsReadIdsFile
newsReadIdsFile="$(newsReadIdsFile)" local allIds
cat "$newsUnreadIdsFile" >> "$newsReadIdsFile" allIds="$(nix-instantiate --quiet --eval --expr "(import ${newsNixFile}).meta.ids")"
fi 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() { function doUninstall() {

View file

@ -15,60 +15,4 @@ let
check = check; check = check;
}; };
newsReadIds = if newsReadIdsFile == null then in { inherit (env) activationPackage config; }
{ }
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;
}

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Home Manager\n" "Project-Id-Version: Home Manager\n"
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -78,11 +78,11 @@ msgid "Can't inspect options of a flake configuration"
msgstr "" msgstr ""
#: home-manager/home-manager:281 home-manager/home-manager:304 #: 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'" msgid "%s: unknown option '%s'"
msgstr "" 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" msgid "Run '%s --help' for usage help"
msgstr "" msgstr ""
@ -124,7 +124,7 @@ msgstr ""
msgid "Can't instantiate a flake configuration" msgid "Can't instantiate a flake configuration"
msgstr "" msgstr ""
#: home-manager/home-manager:549 #: home-manager/home-manager:552
msgid "" msgid ""
"There is %d unread and relevant news item.\n" "There is %d unread and relevant news item.\n"
"Read it by running the command \"%s news\"." "Read it by running the command \"%s news\"."
@ -134,77 +134,72 @@ msgid_plural ""
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: home-manager/home-manager:563 #: home-manager/home-manager:566
msgid "Unknown \"news.display\" setting \"%s\"." msgid "Unknown \"news.display\" setting \"%s\"."
msgstr "" msgstr ""
#: home-manager/home-manager:570 #: home-manager/home-manager:573
#, sh-format #, sh-format
msgid "Please set the $EDITOR environment variable" msgid "Please set the $EDITOR environment variable"
msgstr "" msgstr ""
#: home-manager/home-manager:585 #: home-manager/home-manager:588
msgid "Cannot run build in read-only directory" msgid "Cannot run build in read-only directory"
msgstr "" msgstr ""
#: home-manager/home-manager:669 #: home-manager/home-manager:666
msgid "No generation with ID %s" msgid "No generation with ID %s"
msgstr "" msgstr ""
#: home-manager/home-manager:671 #: home-manager/home-manager:668
msgid "Cannot remove the current generation %s" msgid "Cannot remove the current generation %s"
msgstr "" msgstr ""
#: home-manager/home-manager:673 #: home-manager/home-manager:670
msgid "Removing generation %s" msgid "Removing generation %s"
msgstr "" msgstr ""
#: home-manager/home-manager:692 #: home-manager/home-manager:689
msgid "No generations to expire" msgid "No generations to expire"
msgstr "" msgstr ""
#: home-manager/home-manager:703 #: home-manager/home-manager:700
msgid "No home-manager packages seem to be installed." msgid "No home-manager packages seem to be installed."
msgstr "" msgstr ""
#. translators: Here "flake" is a noun that refers to the Nix Flakes feature. #: home-manager/home-manager:781
#: home-manager/home-manager:730
msgid "Sorry, this command is not yet supported in flake setup"
msgstr ""
#: home-manager/home-manager:767
msgid "Unknown argument %s" msgid "Unknown argument %s"
msgstr "" msgstr ""
#: home-manager/home-manager:783 #: home-manager/home-manager:805
msgid "This will remove Home Manager from your system." msgid "This will remove Home Manager from your system."
msgstr "" msgstr ""
#: home-manager/home-manager:786 #: home-manager/home-manager:808
msgid "This is a dry run, nothing will actually be uninstalled." msgid "This is a dry run, nothing will actually be uninstalled."
msgstr "" msgstr ""
#: home-manager/home-manager:790 #: home-manager/home-manager:812
msgid "Really uninstall Home Manager?" msgid "Really uninstall Home Manager?"
msgstr "" msgstr ""
#: home-manager/home-manager:796 #: home-manager/home-manager:818
msgid "Switching to empty Home Manager configuration..." msgid "Switching to empty Home Manager configuration..."
msgstr "" msgstr ""
#: home-manager/home-manager:823 #: home-manager/home-manager:846
msgid "Yay!" msgid "Yay!"
msgstr "" msgstr ""
#: home-manager/home-manager:828 #: home-manager/home-manager:851
msgid "Home Manager is uninstalled but your home.nix is left untouched." msgid "Home Manager is uninstalled but your home.nix is left untouched."
msgstr "" msgstr ""
#: home-manager/home-manager:1040 #: home-manager/home-manager:1063
msgid "expire-generations expects one argument, got %d." msgid "expire-generations expects one argument, got %d."
msgstr "" msgstr ""
#: home-manager/home-manager:1062 #: home-manager/home-manager:1085
msgid "Unknown command: %s" msgid "Unknown command: %s"
msgstr "" msgstr ""

View file

@ -85,10 +85,22 @@ in
default = [ ]; default = [ ];
description = "News entries."; description = "News entries.";
}; };
json = {
output = mkOption {
internal = true;
type = types.package;
description = "The generated JSON file package.";
};
};
}; };
}; };
config = { 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 # Add news entries in chronological order (i.e., latest time
# should be at the bottom of the list). The time should be # should be at the bottom of the list). The time should be
# formatted as given in the output of # formatted as given in the output of

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Home Manager Modules\n" "Project-Id-Version: Home Manager Modules\n"
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -33,7 +33,7 @@ msgstr ""
msgid "No change so reusing latest profile generation %s" msgid "No change so reusing latest profile generation %s"
msgstr "" msgstr ""
#: modules/home-environment.nix:634 #: modules/home-environment.nix:626
msgid "" msgid ""
"Oops, Nix failed to install your new Home Manager profile!\n" "Oops, Nix failed to install your new Home Manager profile!\n"
"\n" "\n"
@ -49,7 +49,7 @@ msgid ""
"Then try activating your Home Manager configuration again." "Then try activating your Home Manager configuration again."
msgstr "" msgstr ""
#: modules/home-environment.nix:667 #: modules/home-environment.nix:659
msgid "Activating %s" msgid "Activating %s"
msgstr "" msgstr ""