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 that it is about to be overwrite was from a previous Home Manager
generation or from manual configuration. generation or from manual configuration.
Home Manager targets [NixOS][] version 17.03 (the current stable Home Manager targets [NixOS][] unstable and NixOS version 17.03 (the
version), it may or may not work on other Linux distributions and current stable version), it may or may not work on other Linux
NixOS versions. distributions and NixOS versions.
Also, the `home-manager` tool does not explicitly support rollbacks at 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 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 1. Make sure you have a working Nix installation. If you are not
using NixOS then you may here have to run using NixOS then you may here have to run
``` ```console
$ mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER $ 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` 2. Clone the Home Manager repository into the `~/.config/nixpkgs`
directory: directory:
``` ```console
$ git clone https://github.com/rycee/home-manager ~/.config/nixpkgs/home-manager $ 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 or
to the `packageOverrides` section in your
`~/.config/nixpkgs/config.nix` file:
```nix ```console
{ $ git clone -b release-17.03 https://github.com/rycee/home-manager ~/.config/nixpkgs/home-manager
packageOverrides = pkgs: rec { ```
home-manager = import ./home-manager { inherit pkgs; };
}; 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: 4. Install the `home-manager` package:
``` ```console
$ nix-env -f '<nixpkgs>' -iA home-manager $ nix-env -f '<nixpkgs>' -iA home-manager
installing 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 To activate this configuration you can then run
``` ```console
$ home-manager switch $ home-manager switch
``` ```
or if you are not feeling so lucky, or if you are not feeling so lucky,
``` ```console
$ home-manager build $ home-manager build
``` ```
which will create a `result` link to a directory containing an which will create a `result` link to a directory containing an
activation script and the generated home directory files. 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 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 to your configuration. Attempting to switch to the generation will
then result in then result in
``` ```console
$ home-manager switch $ home-manager switch
Activating checkLinkTargets 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 let
homeManagerExpr = pkgs.writeText "home-manager.nix" '' modulesPathStr = if modulesPath == null then "" else modulesPath;
{ pkgs ? import <nixpkgs> {}, confPath }:
let
env = import <home-manager> {
configuration = import confPath;
pkgs = pkgs;
};
in
{
inherit (env) activation-script;
}
'';
in in
@ -29,8 +23,8 @@ pkgs.stdenv.mkDerivation {
substituteInPlace $out/bin/home-manager \ substituteInPlace $out/bin/home-manager \
--subst-var-by bash "${pkgs.bash}" \ --subst-var-by bash "${pkgs.bash}" \
--subst-var-by coreutils "${pkgs.coreutils}" \ --subst-var-by coreutils "${pkgs.coreutils}" \
--subst-var-by MODULES_PATH '${modulesPath}' \ --subst-var-by MODULES_PATH '${modulesPathStr}' \
--subst-var-by HOME_MANAGER_EXPR_PATH "${homeManagerExpr}" --subst-var-by HOME_MANAGER_EXPR_PATH "${./home-manager.nix}"
''; '';
meta = with pkgs.stdenv.lib; { meta = with pkgs.stdenv.lib; {

View file

@ -39,6 +39,7 @@ function setConfigFile() {
function setHomeManagerModulesPath() { function setHomeManagerModulesPath() {
local modulesPath local modulesPath
for modulesPath in "@MODULES_PATH@" \ for modulesPath in "@MODULES_PATH@" \
"$HOME/.config/nixpkgs/home-manager/modules" \
"$HOME/.nixpkgs/home-manager/modules" ; do "$HOME/.nixpkgs/home-manager/modules" ; do
if [[ -e "$modulesPath" ]] ; then if [[ -e "$modulesPath" ]] ; then
export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=$modulesPath" export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=$modulesPath"
@ -48,29 +49,11 @@ function setHomeManagerModulesPath() {
} }
function doBuild() { 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 setConfigFile
setHomeManagerModulesPath setHomeManagerModulesPath
output="$(realpath "$1")"
if [[ $? -ne 0 ]]; then
exit 1
fi
export NIX_PATH="$NIX_PATH${NIX_PATH:+:}home-manager=@MODULES_PATH@"
local extraArgs local extraArgs
extraArgs="" extraArgs="$1"
for p in "${EXTRA_NIX_PATH[@]}"; do for p in "${EXTRA_NIX_PATH[@]}"; do
extraArgs="$extraArgs -I $p" extraArgs="$extraArgs -I $p"
@ -83,19 +66,17 @@ function doBuild() {
nix-build $extraArgs \ nix-build $extraArgs \
"@HOME_MANAGER_EXPR_PATH@" \ "@HOME_MANAGER_EXPR_PATH@" \
--argstr confPath "$HOME_MANAGER_CONFIG" \ --argstr confPath "$HOME_MANAGER_CONFIG" \
-A activation-script \ --argstr confAttr "$HOME_MANAGER_CONFIG_ATTRIBUTE" \
-o "$output" -A activationPackage
} }
function doSwitch() { function doSwitch() {
local wrkdir local generation
wrkdir="$(mktemp -d)" local exitCode=0
if doBuild "$wrkdir/generation" ; then generation=$(doBuild "--no-out-link") && $generation/activate || exitCode=1
"$wrkdir/generation/activate"
fi
rm -r "$wrkdir" return $exitCode
} }
function doListGens() { function doListGens() {
@ -122,6 +103,8 @@ function doHelp() {
echo echo
echo " -f FILE The home configuration file." echo " -f FILE The home configuration file."
echo " Default is '~/.config/nixpkgs/home.nix'." 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 " -I PATH Add a path to the Nix expression search path."
echo " -v Verbose output" echo " -v Verbose output"
echo " -n Do a dry run, only prints what actions would be taken" echo " -n Do a dry run, only prints what actions would be taken"
@ -136,8 +119,9 @@ function doHelp() {
} }
EXTRA_NIX_PATH=() 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 case $opt in
f) f)
HOME_MANAGER_CONFIG="$OPTARG" HOME_MANAGER_CONFIG="$OPTARG"
@ -145,6 +129,9 @@ while getopts f:I:vnh opt; do
I) I)
EXTRA_NIX_PATH+=("$OPTARG") EXTRA_NIX_PATH+=("$OPTARG")
;; ;;
A)
HOME_MANAGER_CONFIG_ATTRIBUTE="$OPTARG"
;;
v) v)
export VERBOSE=1 export VERBOSE=1
;; ;;
@ -170,7 +157,7 @@ cmd="$*"
case "$cmd" in case "$cmd" in
build) build)
doBuild "result" doBuild ""
;; ;;
switch) switch)
doSwitch 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/firefox.nix
./programs/git.nix ./programs/git.nix
./programs/gnome-terminal.nix ./programs/gnome-terminal.nix
./programs/home-manager.nix
./programs/htop.nix
./programs/info.nix ./programs/info.nix
./programs/lesspipe.nix ./programs/lesspipe.nix
./programs/ssh.nix ./programs/ssh.nix
@ -30,6 +32,7 @@ let
./services/network-manager-applet.nix ./services/network-manager-applet.nix
./services/random-background.nix ./services/random-background.nix
./services/redshift.nix ./services/redshift.nix
./services/syncthing.nix
./services/taffybar.nix ./services/taffybar.nix
./services/tahoe-lafs.nix ./services/tahoe-lafs.nix
./services/udiskie.nix ./services/udiskie.nix
@ -75,6 +78,8 @@ in
{ {
inherit (module) options config; inherit (module) options config;
activationPackage = module.config.home.activationPackage;
# For backwards compatibility. Please use activationPackage instead.
activation-script = module.config.home.activationPackage; activation-script = module.config.home.activationPackage;
home-path = module.config.home.path;
} }

View file

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
with import ./lib/dag.nix; with import ./lib/dag.nix { inherit lib; };
let let
@ -260,7 +260,7 @@ in
relativePath="''${sourcePath#$newGenFiles/}" relativePath="''${sourcePath#$newGenFiles/}"
targetPath="$HOME/$relativePath" targetPath="$HOME/$relativePath"
if [[ -e "$targetPath" \ if [[ -e "$targetPath" \
&& ! "$(readlink -e "$targetPath")" =~ "${pattern}" ]] ; then && ! "$(readlink "$targetPath")" =~ "${pattern}" ]] ; then
errorEcho "Existing file '$targetPath' is in the way" errorEcho "Existing file '$targetPath' is in the way"
collision=1 collision=1
fi fi
@ -309,14 +309,27 @@ in
relativePath="''${sourcePath#$oldGenFiles/}" relativePath="''${sourcePath#$oldGenFiles/}"
targetPath="$HOME/$relativePath" targetPath="$HOME/$relativePath"
if [[ -e "$newGenFiles/$relativePath" ]] ; then if [[ -e "$newGenFiles/$relativePath" ]] ; then
$VERBOSE_ECHO "Checking $targetPath exists" $VERBOSE_ECHO "Checking $targetPath: exists"
elif [[ ! "$(readlink -e "$targetPath")" =~ "${pattern}" ]] ; then elif [[ ! "$(readlink "$targetPath")" =~ "${pattern}" ]] ; then
warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete." warnEcho "Path '$targetPath' not link into Home Manager generation. Skipping delete."
else else
echo "Checking $targetPath gone (deleting)" $VERBOSE_ECHO "Checking $targetPath: gone (deleting)"
$DRY_RUN_CMD rm $VERBOSE_ARG "$targetPath" $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 fi
done done
''; '';
@ -346,7 +359,7 @@ in
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
echo "Creating profile generation $newGenNum" echo "Creating profile generation $newGenNum"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath" $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" $DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
else else
echo "No change so reusing latest profile generation $oldGenNum" echo "No change so reusing latest profile generation $oldGenNum"
@ -403,11 +416,19 @@ in
concatStringsSep "\n" ( concatStringsSep "\n" (
mapAttrsToList (n: v: 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 if [ -d "${v.source}" ]; then
mkdir -pv "$(dirname "$out/${v.target}")" mkdir -pv "$(dirname "$out/${v.target}")"
ln -sv "${v.source}" "$out/${v.target}" ln -sv "${v.source}" "$target"
else else
install -D -m${v.mode} "${v.source}" "$out/${v.target}" install -D -m${v.mode} "${v.source}" "$target"
fi fi
'' ''
) cfg.file ) cfg.file
@ -426,6 +447,7 @@ in
--subst-var-by GENERATION_DIR $out --subst-var-by GENERATION_DIR $out
ln -s ${home-files} $out/home-files ln -s ${home-files} $out/home-files
ln -s ${cfg.path} $out/home-path
''; '';
}; };

View file

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

View file

@ -7,9 +7,9 @@
# - the addition of the function `dagEntryBefore` indicating a # - the addition of the function `dagEntryBefore` indicating a
# "wanted by" relationship. # "wanted by" relationship.
with import <nixpkgs/lib/strings.nix>; { lib }:
with import <nixpkgs/lib/attrsets.nix>;
with import <nixpkgs/lib/lists.nix>; with lib;
rec { 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; cfg2 = config.gtk.gtk2;
cfg3 = config.gtk.gtk3; cfg3 = config.gtk.gtk3;
toGtk3Ini = (import ../lib/generators.nix).toINI { toGtk3Ini = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
value' = value' =

View file

@ -6,31 +6,27 @@ let
cfg = config.programs.git; cfg = config.programs.git;
toINI = (import ../lib/generators.nix).toINI {}; signModule = types.submodule {
options = {
signModule = types.submodule ( key = mkOption {
{ ... }: { type = types.str;
options = { description = "The default GPG signing key fingerprint.";
key = mkOption {
type = types.str;
description = "The default GPG signing key fingerprint.";
};
signByDefault = mkOption {
type = types.bool;
default = false;
description = "Whether commits should be signed by default.";
};
gpgPath = mkOption {
type = types.str;
default = "${pkgs.gnupg}/bin/gpg2";
defaultText = "\${pkgs.gnupg}/bin/gpg2";
description = "Path to GnuPG binary to use.";
};
}; };
}
); signByDefault = mkOption {
type = types.bool;
default = false;
description = "Whether commits should be signed by default.";
};
gpgPath = mkOption {
type = types.str;
default = "${pkgs.gnupg}/bin/gpg2";
defaultText = "\${pkgs.gnupg}/bin/gpg2";
description = "Path to GnuPG binary to use.";
};
};
};
in in
@ -95,7 +91,8 @@ in
{ {
home.packages = [ cfg.package ]; 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, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
with import ../lib/dag.nix; with import ../lib/dag.nix { inherit lib; };
let let
@ -90,7 +90,7 @@ let
} }
); );
toINI = (import ../lib/generators.nix).toINI { mkKeyValue = mkIniKeyValue; }; toDconfIni = generators.toINI { mkKeyValue = mkIniKeyValue; };
mkIniKeyValue = key: value: mkIniKeyValue = key: value:
let let
@ -181,14 +181,15 @@ in
# The dconf service needs to be installed and prepared. # The dconf service needs to be installed and prepared.
home.activation.gnomeTerminal = dagEntryAfter ["installPackages"] ( home.activation.gnomeTerminal = dagEntryAfter ["installPackages"] (
let 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/"; dconfPath = "/org/gnome/terminal/legacy/";
in in
'' ''
if [[ -v DRY_RUN ]]; then if [[ -v DRY_RUN ]]; then
echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${sf} echo ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} "<" ${iniFile}
else else
${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${sf} ${pkgs.gnome3.dconf}/bin/dconf load ${dconfPath} < ${iniFile}
fi 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, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
with import ../lib/dag.nix; with import ../lib/dag.nix { inherit lib; };
let let
cfg = config.programs.info; cfg = config.programs.info;
@ -42,7 +42,7 @@ in
enable = mkEnableOption "GNU Info"; enable = mkEnableOption "GNU Info";
homeInfoDirLocation = mkOption { homeInfoDirLocation = mkOption {
default = "$HOME/.cache/info"; default = "\${XDG_CACHE_HOME:-$HOME/.cache}/info";
description = '' description = ''
Directory in which to store the info <filename>dir</filename> Directory in which to store the info <filename>dir</filename>
file within your home. file within your home.

View file

@ -8,7 +8,7 @@ let
yn = flag: if flag then "yes" else "no"; yn = flag: if flag then "yes" else "no";
matchBlockModule = types.submodule { matchBlockModule = types.submodule ({ name, ... }: {
options = { options = {
host = mkOption { host = mkOption {
type = types.str; type = types.str;
@ -96,7 +96,9 @@ let
description = "The command to use to connect to the server."; description = "The command to use to connect to the server.";
}; };
}; };
};
config.host = mkDefault name;
});
matchBlockStr = cf: concatStringsSep "\n" ( matchBlockStr = cf: concatStringsSep "\n" (
["Host ${cf.host}"] ["Host ${cf.host}"]
@ -144,11 +146,37 @@ in
''; '';
}; };
matchBlocks = mkOption { controlPersist = mkOption {
type = types.listOf matchBlockModule; type = types.str;
default = []; default = "no";
example = "10m";
description = '' 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} ForwardAgent ${yn cfg.forwardAgent}
ControlMaster ${cfg.controlMaster} ControlMaster ${cfg.controlMaster}
ControlPath ${cfg.controlPath} 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, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
with import ./lib/dag.nix; with import ./lib/dag.nix { inherit lib; };
let let
@ -12,7 +12,7 @@ let
|| cfg.targets != {} || cfg.targets != {}
|| cfg.timers != {}; || cfg.timers != {};
toSystemdIni = (import lib/generators.nix).toINI { toSystemdIni = generators.toINI {
mkKeyValue = key: value: mkKeyValue = key: value:
let let
value' = value' =

3
overlay.nix Normal file
View file

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