Compare commits

...

39 commits

Author SHA1 Message Date
Robert Helgesson 4ccd4b9ccc
readme: add 'console' syntax highlighting
(cherry picked from commit e1bceb2adb)
2017-09-27 18:26:00 +02:00
Linus Heckemann c9d0e3ee29
Add overlay and instructions for using it
(cherry picked from commit 34428fc709)
2017-09-27 18:25:54 +02:00
Robert Helgesson 3c6453b32d
home-environment: fail if a home.file is outside $HOME
(cherry picked from commit 6ecf9e091c)
2017-09-21 15:55:56 +02:00
Nikita Uvarov c2ab3bc95c
readme: add man page info
(cherry picked from commit 82c5aa82d2)
2017-09-21 15:50:47 +02:00
Robert Helgesson d31a1ba6e2
lib: make dag.nix take lib as argument
(cherry picked from commit 742d1889c5)
2017-09-21 15:50:47 +02:00
Robert Helgesson 21a4dedd6f
lib: use generators from Nixpkgs
(cherry picked from commit 61042c7606)
2017-09-21 15:50:47 +02:00
Silvan Mosberger 4b09df1809
ssh: allow attrset matchBlock
(cherry picked from commit fc1d4f5362)
2017-09-12 08:58:13 +02:00
Nikita Uvarov 7ad849f033
home-manager: remove escaping
The Nix code that was extracted to its own file erroneously included
escaping of "${".

(cherry picked from commit 5eff7f38df)
2017-08-29 13:05:52 +02:00
Robert Helgesson a3395bc3a4
home-manager: move Nix code to own file
(cherry picked from commit e9ca4305a6)
2017-08-29 13:05:52 +02:00
Robert Helgesson edb46f4aa2
home-manager: add explanatory comment
(cherry picked from commit 125deafc84)
2017-08-29 13:05:51 +02:00
Robert Helgesson 83866e7fc4
home-manager: temporarily re-add attribute
(cherry picked from commit 1445673e18)
2017-08-29 13:05:51 +02:00
Robert Helgesson 01a030a974
home-manager: remove unused attribute
(cherry picked from commit 4a17d8ef97)
2017-08-29 13:05:51 +02:00
Robert Helgesson 0357f71d71
home-manager: minor attribute rename
The "activation-script" attribute doesn't actually point directly at
the activation script. Renamed the attribute to be more descriptive.

(cherry picked from commit b4fff6b9b7)
2017-08-29 13:05:51 +02:00
Robert Helgesson 331eb9b809
home-manager: simplify use of nix-build output
There is no need to specify an out link when switching to a new
generation since nix-build prints the store path on standard output.
Similarly, when just building a generation we specify no out link
since nix-build will use "result" by default.

(cherry picked from commit 2245b0ac94)
2017-08-29 13:05:51 +02:00
Robert Helgesson 6b55d5373c
home-environment: include home path in generation directory
Technically not necessary but it was a bit silly to leave out this
important directory from the generation directory. This also makes it
more convenient to browse the installed packages after a
`home-manager build`.

(cherry picked from commit e561beab44)
2017-08-27 00:22:08 +02:00
Robert Helgesson f6a05b15a6
info: use XDG_CACHE_HOME if defined
(cherry picked from commit a30751464a)
2017-08-26 12:55:21 +02:00
Robert Helgesson b25037d68b
git: simplify submodule slightly
(cherry picked from commit fed112e497)
2017-08-24 01:03:34 +02:00
Richard Yang 95327eb5cd
home-environment: use relative latest profile link
Using a relative path prevents the latest version from being garbage
collected.

(cherry picked from commit 42f5d4404d)
2017-08-22 09:46:39 +02:00
Cornelius Mika d38ef895e5
lib-bash: always print message announcing a dry run
(cherry picked from commit 5c098dc7ad)
2017-08-21 18:53:26 +02:00
Cornelius Mika 4e7a26e710
home-environment: replace superfluous spaces in debug messages
(cherry picked from commit 3dba6fc95c)
2017-08-21 18:53:26 +02:00
Cornelius Mika b18d5e02ef
home-environment: only notify about path deletion on verbose output
(cherry picked from commit 1eee82272a)
2017-08-21 18:53:26 +02:00
Cornelius Mika 9865e3ce29
home-environment: fix error when deleting empty directories
With --ignore-fail-on-non-empty, non-emptiness is the only failure
that gets ignored by rmdir. In the case that rmdir reaches $HOME and
considers deleting it, it will detect insufficient permissions and
subsequently exit with an error, even if $HOME is not empty.

Prevent this by calling rmdir with a relative path that excludes
$HOME.

(cherry picked from commit da5b7bea78)
2017-08-21 18:46:07 +02:00
Cornelius Mika 758d2ef9c1
home-manager: show full script path on activation error
Run the activation script in its original nix-store location so that
Bash error messages show the real script location instead of 'wrkdir',
which gets deleted right after the script exits.

(cherry picked from commit 02a501705a)
2017-08-21 18:46:07 +02:00
Cornelius Mika 463d6db90b
home-manager: exit with an error on build failure
Because 'set -e' has no effect on commands that run in an if condition,
the script was always exiting with no error when 'doBuild' failed.

As a bonus, $wrkdir is now always removed after building.

(cherry picked from commit a9d9fb5d75)
2017-08-21 18:46:07 +02:00
Cornelius Mika 5f2a6d90bd
home-manager: add config file attribute
(cherry picked from commit ffbc7e723d)
2017-08-21 18:46:07 +02:00
Silvan Mosberger 85d12028ad
htop: use types.coercedTo
(cherry picked from commit 1d24e96074)
2017-08-02 22:33:53 +02:00
Robert Helgesson bea9daabeb
ssh: add control persist option
(cherry picked from commit be432c8654)
2017-07-29 17:54:50 +02:00
Silvan Mosberger 31655a1621
htop: add module
(cherry picked from commit 3778a69fbe)
2017-07-24 13:23:48 +02:00
Robert Helgesson ee28f76369
home-environment: fix cleanup of user replaced directories
We must only follow the symbolic link once (i.e., not use the `-e`
option) since otherwise the pattern will not match when
`home.file.xyz.source` is a directory.

(cherry picked from commit d807a5c314)
2017-07-22 14:26:31 +02:00
Robert Helgesson 7f2eacfe49
home-environment: avoid harmless but scary error message
(cherry picked from commit 5862a05fb1)
2017-07-22 14:26:23 +02:00
Robert Helgesson 0ef0be8ffb
home-manager: remove manually installed home-manager
If the `home-manager` module is enabled then check if the
`home-manager` package is installed using `nix-env -i` and if so then
it is automatically uninstalled before the new package environment,
which includes home-manager, is installed.

(cherry picked from commit 2e257f40e6)
2017-07-20 09:14:23 +02:00
Robert Helgesson e9cc225cbb
syncthing: expand service description
This models the user service on the upstream systemd file.

(cherry picked from commit cdb2bec909)
2017-07-20 09:14:23 +02:00
Utku Demir 68f0ed58c1
Add syncthing service
(cherry picked from commit dd5061d73b)
2017-07-20 09:14:23 +02:00
Robert Helgesson 4bc6e454d7
home-manager: add module
This module is a module to install and configure the home-manager
tool. By managing the home-manager tool through the Home Manager
module system it will be installed/updated on configuration
activation.

(cherry picked from commit 7a18a0fb34)
2017-07-13 00:40:20 +02:00
Robert Helgesson 401975f500
home-manager: allow a user-defined third module path
The user-defined path will be used if present, otherwise the two
"fallback" defaults (in `.nixpkgs` and `.config/nixpkgs`) will be
used.

(cherry picked from commit 28d3f74614)
2017-07-13 00:40:20 +02:00
Robert Helgesson 1bcfec1e87
home-manager: remove unnecessary variable setting
The `NIX_PATH` variable is set by the `setHomeManagerModulesPath`
function so it is unnecessary to set it again.

(cherry picked from commit 98c7b23178)
2017-07-13 00:40:20 +02:00
Robin Stumm 540e90d3fa
home-environment: fix home.activation.checkLinkTargets
Problem
-------

We resolve symlinks from inside `/nix/store/HASH-home-manager-files`
into the nix store as `/nix/store/HASH-DRVNAME` which does not match
the pattern.

This happened to me because I pull in some repos in via `home.file`.
The `home-manager-files` derivation links to the repo's derivation in
the nix store. For example:

    let nanorcs = fetchFromGitHub {
      owner = "scopatz";
      repo = "nanorc";
      …
    }; in [
      {
        target = ".nano";
        source = nanorcs;
      }
      {
        target = ".nanorc";
        source = "${nanorcs}/nanorc";
      }
    ]

Solution
--------

Call `readlink` without `-e` to obtain only the first redirection from
`~` to `/nix/store/HASH-home-manager-files`.

(cherry picked from commit 89dc8c2004)
2017-07-08 00:40:58 +02:00
Robert Helgesson 3c3f68bf61
Merge commit '196db18' into release-17.03 2017-06-30 22:46:58 +02:00
Robert Helgesson 46f0338092
README: add instructions for release-17.03 branch 2017-06-15 18:13:56 +02:00
19 changed files with 598 additions and 214 deletions

View file

@ -19,9 +19,9 @@ will write to your dconf store and cannot tell whether a configuration
that it is about to be overwrite was from a previous Home Manager
generation or from manual configuration.
Home Manager targets [NixOS][] version 17.03 (the current stable
version), it may or may not work on other Linux distributions and
NixOS versions.
Home Manager targets [NixOS][] unstable and NixOS version 17.03 (the
current stable version), it may or may not work on other Linux
distributions and NixOS versions.
Also, the `home-manager` tool does not explicitly support rollbacks at
the moment so if your home directory gets messed up you'll have to fix
@ -39,7 +39,7 @@ Currently the easiest way to install Home Manager is as follows:
1. Make sure you have a working Nix installation. If you are not
using NixOS then you may here have to run
```
```console
$ mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
```
@ -49,25 +49,29 @@ Currently the easiest way to install Home Manager is as follows:
2. Clone the Home Manager repository into the `~/.config/nixpkgs`
directory:
```
$ git clone https://github.com/rycee/home-manager ~/.config/nixpkgs/home-manager
```console
$ git clone -b master https://github.com/rycee/home-manager ~/.config/nixpkgs/home-manager
```
3. Add Home Manager to your user's Nixpkgs, for example by adding it
to the `packageOverrides` section in your
`~/.config/nixpkgs/config.nix` file:
or
```nix
{
packageOverrides = pkgs: rec {
home-manager = import ./home-manager { inherit pkgs; };
};
}
```console
$ git clone -b release-17.03 https://github.com/rycee/home-manager ~/.config/nixpkgs/home-manager
```
depending on whether you are tracking Nixpkgs unstable or version
17.03.
3. Add Home Manager to your user's Nixpkgs, for example by symlinking the
overlay to `~/.config/nixpkgs/overlays`:
```console
$ ln -s ~/.config/nixpkgs/home-manager/overlay.nix ~/.config/nixpkgs/overlays/home-manager.nix
```
4. Install the `home-manager` package:
```
```console
$ nix-env -f '<nixpkgs>' -iA home-manager
installing home-manager
```
@ -119,19 +123,26 @@ First create a file `~/.config/nixpkgs/home.nix` containing
To activate this configuration you can then run
```
```console
$ home-manager switch
```
or if you are not feeling so lucky,
```
```console
$ home-manager build
```
which will create a `result` link to a directory containing an
activation script and the generated home directory files.
To see available configuration options with descriptions
and usage examples run
```console
$ man home-configuration.nix
```
Keeping your ~ safe from harm
-----------------------------
@ -162,7 +173,7 @@ For example, suppose you have a wonderful, painstakingly created
to your configuration. Attempting to switch to the generation will
then result in
```
```console
$ home-manager switch
Activating checkLinkTargets

View file

@ -1,20 +1,14 @@
{ pkgs, modulesPath ? "$HOME/.config/nixpkgs/home-manager/modules" }:
{ pkgs
# Extra path to the Home Manager modules. If set then this path will
# be tried before `$HOME/.config/nixpkgs/home-manager/modules` and
# `$HOME/.nixpkgs/home-manager/modules`.
, modulesPath ? null
}:
let
homeManagerExpr = pkgs.writeText "home-manager.nix" ''
{ pkgs ? import <nixpkgs> {}, confPath }:
let
env = import <home-manager> {
configuration = import confPath;
pkgs = pkgs;
};
in
{
inherit (env) activation-script;
}
'';
modulesPathStr = if modulesPath == null then "" else modulesPath;
in
@ -29,8 +23,8 @@ pkgs.stdenv.mkDerivation {
substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${pkgs.bash}" \
--subst-var-by coreutils "${pkgs.coreutils}" \
--subst-var-by MODULES_PATH '${modulesPath}' \
--subst-var-by HOME_MANAGER_EXPR_PATH "${homeManagerExpr}"
--subst-var-by MODULES_PATH '${modulesPathStr}' \
--subst-var-by HOME_MANAGER_EXPR_PATH "${./home-manager.nix}"
'';
meta = with pkgs.stdenv.lib; {

View file

@ -39,6 +39,7 @@ function setConfigFile() {
function setHomeManagerModulesPath() {
local modulesPath
for modulesPath in "@MODULES_PATH@" \
"$HOME/.config/nixpkgs/home-manager/modules" \
"$HOME/.nixpkgs/home-manager/modules" ; do
if [[ -e "$modulesPath" ]] ; then
export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=$modulesPath"
@ -48,29 +49,11 @@ function setHomeManagerModulesPath() {
}
function doBuild() {
if [[ -z "$1" ]]; then
echo "Need to provide generation output path."
exit 1
fi
if [[ -e "$1" ]]; then
echo "The output path $1 already exists."
exit 1
fi
setConfigFile
setHomeManagerModulesPath
output="$(realpath "$1")"
if [[ $? -ne 0 ]]; then
exit 1
fi
export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=@MODULES_PATH@"
local extraArgs
extraArgs=""
extraArgs="$1"
for p in "${EXTRA_NIX_PATH[@]}"; do
extraArgs="$extraArgs -I $p"
@ -83,19 +66,17 @@ function doBuild() {
nix-build $extraArgs \
"@HOME_MANAGER_EXPR_PATH@" \
--argstr confPath "$HOME_MANAGER_CONFIG" \
-A activation-script \
-o "$output"
--argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE" \
-A activationPackage
}
function doSwitch() {
local wrkdir
wrkdir="$(mktemp -d)"
local generation
local exitCode=0
if doBuild "$wrkdir/generation" ; then
"$wrkdir/generation/activate"
fi
generation=$(doBuild "--no-out-link") && $generation/activate || exitCode=1
rm -r "$wrkdir"
return $exitCode
}
function doListGens() {
@ -122,6 +103,8 @@ function doHelp() {
echo
echo " -f FILE The home configuration file."
echo " Default is '~/.config/nixpkgs/home.nix'."
echo " -A ATTRIBUTE Optional attribute that selects a configuration"
echo " expression in the configuration file."
echo " -I PATH Add a path to the Nix expression search path."
echo " -v Verbose output"
echo " -n Do a dry run, only prints what actions would be taken"
@ -136,8 +119,9 @@ function doHelp() {
}
EXTRA_NIX_PATH=()
HOME_MANAGER_CONFIG_ATTRIBUTE=""
while getopts f:I:vnh opt; do
while getopts f:I:A:vnh opt; do
case $opt in
f)
HOME_MANAGER_CONFIG="$OPTARG"
@ -145,6 +129,9 @@ while getopts f:I:vnh opt; do
I)
EXTRA_NIX_PATH+=("$OPTARG")
;;
A)
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
;;
v)
export VERBOSE=1
;;
@ -170,7 +157,7 @@ cmd="$*"
case "$cmd" in
build)
doBuild "result"
doBuild ""
;;
switch)
doSwitch

View file

@ -0,0 +1,15 @@
{ pkgs ? import <nixpkgs> {}, confPath, confAttr }:
let
env = import <home-manager> {
configuration =
let
conf = import confPath;
in
if confAttr == "" then conf else conf.${confAttr};
pkgs = pkgs;
};
in
{
inherit (env) activationPackage;
}

View file

@ -19,6 +19,8 @@ let
./programs/firefox.nix
./programs/git.nix
./programs/gnome-terminal.nix
./programs/home-manager.nix
./programs/htop.nix
./programs/info.nix
./programs/lesspipe.nix
./programs/ssh.nix
@ -30,6 +32,7 @@ let
./services/network-manager-applet.nix
./services/random-background.nix
./services/redshift.nix
./services/syncthing.nix
./services/taffybar.nix
./services/tahoe-lafs.nix
./services/udiskie.nix
@ -75,6 +78,8 @@ in
{
inherit (module) options config;
activationPackage = module.config.home.activationPackage;
# For backwards compatibility. Please use activationPackage instead.
activation-script = module.config.home.activationPackage;
home-path = module.config.home.path;
}

View file

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
with import ./lib/dag.nix;
with import ./lib/dag.nix { inherit lib; };
let
@ -260,7 +260,7 @@ in
relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" \
&& ! "$(readlink -e "$targetPath")" =~ "${pattern}" ]] ; then
&& ! "$(readlink "$targetPath")" =~ "${pattern}" ]] ; then
errorEcho "Existing file '$targetPath' is in the way"
collision=1
fi
@ -309,14 +309,27 @@ in
relativePath="''${sourcePath#$oldGenFiles/}"
targetPath="$HOME/$relativePath"
if [[ -e "$newGenFiles/$relativePath" ]] ; then
$VERBOSE_ECHO "Checking $targetPath exists"
elif [[ ! "$(readlink -e "$targetPath")" =~ "${pattern}" ]] ; then
$VERBOSE_ECHO "Checking $targetPath: exists"
elif [[ ! "$(readlink "$targetPath")" =~ "${pattern}" ]] ; then
warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
else
echo "Checking $targetPath gone (deleting)"
$VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
$DRY_RUN_CMD rm $VERBOSE_ARG "$targetPath"
$DRY_RUN_CMD rmdir --ignore-fail-on-non-empty \
$VERBOSE_ARG -p "$(dirname "$targetPath")"
# Recursively delete empty parent directories.
targetDir="$(dirname "$relativePath")"
if [[ "$targetDir" != "." ]] ; then
pushd "$HOME" > /dev/null
# Call rmdir with a relative path excluding $HOME.
# Otherwise, it might try to delete $HOME and exit
# with a permission error.
$DRY_RUN_CMD rmdir $VERBOSE_ARG \
-p --ignore-fail-on-non-empty \
"$targetDir"
popd > /dev/null
fi
fi
done
'';
@ -346,7 +359,7 @@ in
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
echo "Creating profile generation $newGenNum"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenProfilePath" "$genProfilePath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG $(basename "$newGenProfilePath") "$genProfilePath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
else
echo "No change so reusing latest profile generation $oldGenNum"
@ -403,11 +416,19 @@ in
concatStringsSep "\n" (
mapAttrsToList (n: v:
''
target="$(realpath -m "$out/${v.target}")"
# Target file must be within $HOME.
if [[ ! "$target" =~ "$out" ]] ; then
echo "Error installing file '${v.target}' outside \$HOME" >&2
exit 1
fi
if [ -d "${v.source}" ]; then
mkdir -pv "$(dirname "$out/${v.target}")"
ln -sv "${v.source}" "$out/${v.target}"
ln -sv "${v.source}" "$target"
else
install -D -m${v.mode} "${v.source}" "$out/${v.target}"
install -D -m${v.mode} "${v.source}" "$target"
fi
''
) cfg.file
@ -426,6 +447,7 @@ in
--subst-var-by GENERATION_DIR $out
ln -s ${home-files} $out/home-files
ln -s ${cfg.path} $out/home-path
'';
};

View file

@ -39,7 +39,7 @@ else
fi
if [[ -v DRY_RUN ]] ; then
$VERBOSE_ECHO "This is a dry run"
echo "This is a dry run"
export DRY_RUN_CMD=echo
else
$VERBOSE_ECHO "This is a live run"

View file

@ -7,9 +7,9 @@
# - the addition of the function `dagEntryBefore` indicating a
# "wanted by" relationship.
with import <nixpkgs/lib/strings.nix>;
with import <nixpkgs/lib/attrsets.nix>;
with import <nixpkgs/lib/lists.nix>;
{ lib }:
with lib;
rec {

View file

@ -1,93 +0,0 @@
/* Functions that generate widespread file
* formats from nix data structures.
*
* They all follow a similar interface:
* generator { config-attrs } data
*
* Tests can be found in ./tests.nix
* Documentation in the manual, #sec-generators
*/
with import <nixpkgs/lib/trivial.nix>;
let
libStr = import <nixpkgs/lib/strings.nix>;
libAttr = import <nixpkgs/lib/attrsets.nix>;
flipMapAttrs = flip libAttr.mapAttrs;
in
rec {
/* Generate a line of key k and value v, separated by
* character sep. If sep appears in k, it is escaped.
* Helper for synaxes with different separators.
*
* mkKeyValueDefault ":" "f:oo" "bar"
* > "f\:oo:bar"
*/
mkKeyValueDefault = sep: k: v:
"${libStr.escape [sep] k}${sep}${toString v}";
/* Generate a key-value-style config file from an attrset.
*
* mkKeyValue is the same as in toINI.
*/
toKeyValue = {
mkKeyValue ? mkKeyValueDefault "="
}: attrs:
let mkLine = k: v: mkKeyValue k v + "\n";
in libStr.concatStrings (libAttr.mapAttrsToList mkLine attrs);
/* Generate an INI-style config file from an
* attrset of sections to an attrset of key-value pairs.
*
* generators.toINI {} {
* foo = { hi = "${pkgs.hello}"; ciao = "bar"; };
* baz = { "also, integers" = 42; };
* }
*
*> [baz]
*> also, integers=42
*>
*> [foo]
*> ciao=bar
*> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
*
* The mk* configuration attributes can generically change
* the way sections and key-value strings are generated.
*
* For more examples see the test cases in ./tests.nix.
*/
toINI = {
# apply transformations (e.g. escapes) to section names
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
# format a setting line from key and value
mkKeyValue ? mkKeyValueDefault "="
}: attrsOfAttrs:
let
# map function to string for each key val
mapAttrsToStringsSep = sep: mapFn: attrs:
libStr.concatStringsSep sep
(libAttr.mapAttrsToList mapFn attrs);
mkSection = sectName: sectValues: ''
[${mkSectionName sectName}]
'' + toKeyValue { inherit mkKeyValue; } sectValues;
in
# map input to ini sections
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
/* Generates JSON from an arbitrary (non-function) value.
* For more information see the documentation of the builtin.
*/
toJSON = {}: builtins.toJSON;
/* YAML has been a strict superset of JSON since 1.2, so we
* use toJSON. Before it only had a few differences referring
* to implicit typing rules, so it should work with older
* parsers as well.
*/
toYAML = {}@args: toJSON args;
}

View file

@ -8,7 +8,7 @@ let
cfg2 = config.gtk.gtk2;
cfg3 = config.gtk.gtk3;
toGtk3Ini = (import ../lib/generators.nix).toINI {
toGtk3Ini = generators.toINI {
mkKeyValue = key: value:
let
value' =

View file

@ -6,10 +6,7 @@ let
cfg = config.programs.git;
toINI = (import ../lib/generators.nix).toINI {};
signModule = types.submodule (
{ ... }: {
signModule = types.submodule {
options = {
key = mkOption {
type = types.str;
@ -29,8 +26,7 @@ let
description = "Path to GnuPG binary to use.";
};
};
}
);
};
in
@ -95,7 +91,8 @@ in
{
home.packages = [ cfg.package ];
home.file.".gitconfig".text = toINI ini + "\n" + cfg.extraConfig;
home.file.".gitconfig".text =
generators.toINI {} ini + "\n" + cfg.extraConfig;
}
);
}

View file

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
with import ../lib/dag.nix;
with import ../lib/dag.nix { inherit lib; };
let
@ -90,7 +90,7 @@ let
}
);
toINI = (import ../lib/generators.nix).toINI { mkKeyValue = mkIniKeyValue; };
toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
mkIniKeyValue = key: value:
let
@ -181,14 +181,15 @@ in
# The dconf service needs to be installed and prepared.
home.activation.gnomeTerminal = dagEntryAfter ["installPackages"] (
let
sf = pkgs.writeText "gnome-terminal.ini" (toINI (buildIniSet cfg));
iniText = toDconfIni (buildIniSet cfg);
iniFile = pkgs.writeText "gnome-terminal.ini" iniText;
dconfPath = "/org/gnome/terminal/legacy/";
in
''
if [[ -v DRY_RUN ]]; then
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${sf}
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${iniFile}
else
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${sf}
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${iniFile}
fi
''
);

View file

@ -0,0 +1,52 @@
{ config, lib, pkgs, ... }:
with lib;
with import ../lib/dag.nix { inherit lib; };
let
cfg = config.programs.home-manager;
in
{
options = {
programs.home-manager = {
enable = mkEnableOption "Home Manager";
modulesPath = mkOption {
type = types.nullOr types.str;
default = null;
example = "$HOME/devel/home-manager/modules";
description = ''
The default path to use for Home Manager modules. If this
path does not exist then
<filename>$HOME/.config/nixpkgs/home-manager/modules</filename>
and <filename>$HOME/.nixpkgs/home-manager/modules</filename>
will be attempted.
'';
};
};
};
config = mkIf cfg.enable {
home.packages = [
(import ../../home-manager {
inherit pkgs;
inherit (cfg) modulesPath;
})
];
# Uninstall manually installed home-manager, if such exists.
# Without this a file collision error will be printed.
home.activation.uninstallHomeManager =
dagEntryBetween [ "installPackages" ] [ "writeBoundary" ] ''
if nix-env -q | grep -q '^home-manager$' ; then
$DRY_RUN_CMD nix-env -e home-manager
echo "You can now remove the 'home-manager' packageOverride"
echo "or overlay in '~/.config/nixpkgs/', if you want."
fi
'';
};
}

327
modules/programs/htop.nix Normal file
View file

@ -0,0 +1,327 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.programs.htop;
list = xs: concatMapStrings (x: "${toString x} ") xs;
bool = b: if b then "1" else "0";
fields = {
PID = 0;
COMM = 1;
STATE = 2;
PPID = 3;
PGRP = 4;
SESSION = 5;
TTY_NR = 6;
TPGID = 7;
MINFLT = 9;
MAJFLT = 11;
PRIORITY = 17;
NICE = 18;
STARTTIME = 20;
PROCESSOR = 37;
M_SIZE = 38;
M_RESIDENT = 39;
ST_UID = 45;
PERCENT_CPU = 46;
PERCENT_MEM = 47;
USER = 48;
TIME = 49;
NLWP = 50;
TGID = 51;
CMINFLT = 10;
CMAJFLT = 12;
UTIME = 13;
STIME = 14;
CUTIME = 15;
CSTIME = 16;
M_SHARE = 40;
M_TRS = 41;
M_DRS = 42;
M_LRS = 43;
M_DT = 44;
CTID = 99;
VPID = 100;
VXID = 102;
RCHAR = 102;
WCHAR = 103;
SYSCR = 104;
SYSCW = 105;
RBYTES = 106;
WBYTES = 107;
CNCLWB = 108;
IO_READ_RATE = 109;
IO_WRITE_RATE = 110;
IO_RATE = 111;
CGROUP = 112;
OOM = 113;
IO_PRIORITY = 114;
};
# Mapping from names to defaults
meters = {
Clock = 2;
LoadAverage = 2;
Load = 2;
Memory = 1;
Swap = 1;
Tasks = 2;
Uptime = 2;
Battery = 2;
Hostname = 2;
AllCPUs = 1;
AllCPUs2 = 1;
LeftCPUs = 1;
RightCPUs = 1;
LeftCPUs2 = 1;
RightCPUs2 = 1;
Blank = 2;
CPU = 1;
"CPU(1)"= 1;
"CPU(2)" = 1;
"CPU(3)" = 1;
"CPU(4)" = 1;
};
singleMeterType = types.coercedTo
(types.enum (attrNames meters))
(m: { kind = m; mode = meters.${m}; })
(types.submodule {
options = {
kind = mkOption {
type = types.enum (attrNames meters);
example = "AllCPUs";
description = "What kind of meter.";
};
mode = mkOption {
type = types.enum [ 1 2 3 4 ];
example = 2;
description = "Which mode the meter should use, one of 1(Bar) 2(Text) 3(Graph) 4(LED).";
};
};
});
meterType = types.submodule {
options = {
left = mkOption {
description = "Meters shown in the left header.";
default = [ "AllCPUs" "Memory" "Swap" ];
example = [
"Memory"
"LeftCPUs2"
"RightCPUs2"
{ kind = "CPU"; mode = 3; }
];
type = types.listOf singleMeterType;
};
right = mkOption {
description = "Meters shown in the right header.";
default = [ "Tasks" "LoadAverage" "Uptime" ];
example = [
{ kind = "Clock"; mode = 4; }
"Uptime"
"Tasks"
];
type = types.listOf singleMeterType;
};
};
};
in
{
options.programs.htop = {
enable = mkEnableOption "htop";
fields = mkOption {
type = types.listOf (types.enum (attrNames fields));
default = [ "PID" "USER" "PRIORITY" "NICE" "M_SIZE" "M_RESIDENT" "M_SHARE" "STATE" "PERCENT_CPU" "PERCENT_MEM" "TIME" "COMM" ];
example = [ "PID" "USER" "PRIORITY" "PERCENT_CPU" "M_RESIDENT" "PERCENT_MEM" "TIME" "COMM" ];
description = "Active fields shown in the table.";
};
sortKey = mkOption {
type = types.enum (attrNames fields);
default = "PERCENT_CPU";
example = "TIME";
description = "Which field to use for sorting.";
};
sortDescending = mkOption {
type = types.bool;
default = true;
description = "Whether to sort descending or not.";
};
hideThreads = mkOption {
type = types.bool;
default = false;
description = "Hide threads.";
};
hideKernelThreads = mkOption {
type = types.bool;
default = true;
description = "Hide kernel threads.";
};
hideUserlandThreads = mkOption {
type = types.bool;
default = false;
description = "Hide userland process threads.";
};
shadowOtherUsers = mkOption {
type = types.bool;
default = false;
description = "Shadow other users' processes.";
};
showThreadNames = mkOption {
type = types.bool;
default = false;
description = "Show custom thread names.";
};
showProgramPath = mkOption {
type = types.bool;
default = true;
description = "Show program path.";
};
highlightBaseName = mkOption {
type = types.bool;
default = false;
description = "Highlight program <quote>basename</quote>.";
};
highlightMegabytes = mkOption {
type = types.bool;
default = true;
description = "Highlight large numbers in memory counters.";
};
highlightThreads = mkOption {
type = types.bool;
default = true;
description = "Display threads in a different color.";
};
treeView = mkOption {
type = types.bool;
default = false;
description = "Tree view.";
};
headerMargin = mkOption {
type = types.bool;
default = true;
description = "Leave a margin around header.";
};
detailedCpuTime = mkOption {
type = types.bool;
default = false;
description = "Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest).";
};
cpuCountFromZero = mkOption {
type = types.bool;
default = false;
description = "Count CPUs from 0 instead of 1.";
};
updateProcessNames = mkOption {
type = types.bool;
default = false;
description = "Update process names on every refresh.";
};
accountGuestInCpuMeter = mkOption {
type = types.bool;
default = false;
description = "Add guest time in CPU meter percentage.";
};
colorScheme = mkOption {
type = types.enum [ 0 1 2 3 4 5 6 ];
default = 0;
example = 6;
description = "Which color scheme to use.";
};
delay = mkOption {
type = types.int;
default = 15;
example = 2;
description = "Set the delay between updates, in tenths of seconds.";
};
meters = mkOption {
description = "Meters shown in the header.";
default = {
left = [ "AllCPUs" "Memory" "Swap" ];
right = [ "Tasks" "LoadAverage" "Uptime" ];
};
example = {
left = [
"Memory"
"CPU"
"LeftCPUs2"
"RightCPUs2"
{ kind = "CPU"; mode = 3; }
];
right = [
{ kind = "Clock"; mode = 4; }
"Uptime"
"Tasks"
"LoadAverage"
{ kind = "Battery"; mode = 1; }
];
};
type = meterType;
};
};
config = mkIf cfg.enable {
home.packages = [ pkgs.htop ];
home.file.".config/htop/htoprc".text = let
leftMeters = map (m: m.kind) cfg.meters.left;
leftModes = map (m: m.mode) cfg.meters.left;
rightMeters = map (m: m.kind) cfg.meters.right;
rightModes = map (m: m.mode) cfg.meters.right;
in ''
# This file is regenerated by home-manager
# when options are changed in the config
fields=${list (map (n: fields.${n}) cfg.fields)}
sort_key=${toString (fields.${cfg.sortKey})}
sort_direction=${bool cfg.sortDescending}
hide_threads=${bool cfg.hideThreads}
hide_kernel_threads=${bool cfg.hideKernelThreads}
hide_userland_threads=${bool cfg.hideUserlandThreads}
shadow_other_users=${bool cfg.shadowOtherUsers}
show_thread_names=${bool cfg.showThreadNames}
show_program_path=${bool cfg.showProgramPath}
highlight_base_name=${bool cfg.highlightBaseName}
highlight_megabytes=${bool cfg.highlightMegabytes}
highlight_threads=${bool cfg.highlightThreads}
tree_view=${bool cfg.treeView}
header_margin=${bool cfg.headerMargin}
detailed_cpu_time=${bool cfg.detailedCpuTime}
cpu_count_from_zero=${bool cfg.cpuCountFromZero}
update_process_names=${bool cfg.updateProcessNames}
account_guest_in_cpu_meter=${bool cfg.accountGuestInCpuMeter}
color_scheme=${toString cfg.colorScheme}
delay=${toString cfg.delay}
left_meters=${list leftMeters}
left_meter_modes=${list leftModes}
right_meters=${list rightMeters}
right_meter_modes=${list rightModes}
'';
};
}

View file

@ -21,7 +21,7 @@
{ config, lib, pkgs, ... }:
with lib;
with import ../lib/dag.nix;
with import ../lib/dag.nix { inherit lib; };
let
cfg = config.programs.info;
@ -42,7 +42,7 @@ in
enable = mkEnableOption "GNU Info";
homeInfoDirLocation = mkOption {
default = "$HOME/.cache/info";
default = "\${XDG_CACHE_HOME:-$HOME/.cache}/info";
description = ''
Directory in which to store the info <filename>dir</filename>
file within your home.

View file

@ -8,7 +8,7 @@ let
yn = flag: if flag then "yes" else "no";
matchBlockModule = types.submodule {
matchBlockModule = types.submodule ({ name, ... }: {
options = {
host = mkOption {
type = types.str;
@ -96,7 +96,9 @@ let
description = "The command to use to connect to the server.";
};
};
};
config.host = mkDefault name;
});
matchBlockStr = cf: concatStringsSep "\n" (
["Host ${cf.host}"]
@ -144,11 +146,37 @@ in
'';
};
matchBlocks = mkOption {
type = types.listOf matchBlockModule;
default = [];
controlPersist = mkOption {
type = types.str;
default = "no";
example = "10m";
description = ''
Specify per-host settings.
Whether control socket should remain open in the background.
'';
};
matchBlocks = mkOption {
type = types.loaOf matchBlockModule;
default = [];
example = literalExample ''
{
"john.example.com" = {
hostname = "example.com";
user = "john";
};
foo = {
hostname = "example.com";
identityFile = "/home/john/.ssh/foo_rsa";
};
};
'';
description = ''
Specify per-host settings. Note, if the order of rules matter
then this must be a list. See
<citerefentry>
<refentrytitle>ssh_config</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>.
'';
};
};
@ -158,8 +186,11 @@ in
ForwardAgent ${yn cfg.forwardAgent}
ControlMaster ${cfg.controlMaster}
ControlPath ${cfg.controlPath}
ControlPersist ${cfg.controlPersist}
${concatStringsSep "\n\n" (map matchBlockStr cfg.matchBlocks)}
${concatStringsSep "\n\n" (
map matchBlockStr (
builtins.attrValues cfg.matchBlocks))}
'';
};
}

View file

@ -0,0 +1,32 @@
{ config, lib, pkgs, ... }:
with lib;
{
options = {
services.syncthing = {
enable = mkEnableOption "Syncthing continuous file synchronization";
};
};
config = mkIf config.services.syncthing.enable {
systemd.user.services.syncthing = {
Unit = {
Description = "Syncthing - Open Source Continuous File Synchronization";
Documentation = "man:syncthing(1)";
After = [ "network.target" ];
};
Service = {
ExecStart = "${pkgs.syncthing}/bin/syncthing -no-browser -no-restart -logflags=0";
Restart = "on-failure";
SuccessExitStatus = [ 3 4 ];
RestartForceExitStatus = [ 3 4 ];
};
Install = {
WantedBy = [ "default.target" ];
};
};
};
}

View file

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
with import ./lib/dag.nix;
with import ./lib/dag.nix { inherit lib; };
let
@ -12,7 +12,7 @@ let
|| cfg.targets != {}
|| cfg.timers != {};
toSystemdIni = (import lib/generators.nix).toINI {
toSystemdIni = generators.toINI {
mkKeyValue = key: value:
let
value' =

3
overlay.nix Normal file
View file

@ -0,0 +1,3 @@
self: super: {
home-manager = import ./home-manager { pkgs = super; };
}