summaryrefslogtreecommitdiff
path: root/tw/services
diff options
context:
space:
mode:
Diffstat (limited to 'tw/services')
-rw-r--r--tw/services/git.scm108
-rw-r--r--tw/services/gnupg.scm94
2 files changed, 202 insertions, 0 deletions
diff --git a/tw/services/git.scm b/tw/services/git.scm
new file mode 100644
index 00000000..69dae1e8
--- /dev/null
+++ b/tw/services/git.scm
@@ -0,0 +1,108 @@
+(define-module (tw services git)
+ #:use-module (gnu)
+ #:use-module (gnu home services)
+ #:use-module (gnu packages terminals)
+ #:use-module (gnu packages version-control)
+ #:use-module (gnu services configuration)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module ((guix records) #:select (match-record))
+ #:use-module (srfi srfi-1)
+ #:export (home-git-identity
+ home-git-configuration
+ home-git-service-type))
+
+(define-configuration/no-serialization home-git-identity
+ (name string "Short slug identifying this identity. Only used to name config files.")
+ (root-directory string "Directory under which this identity should apply.")
+ (email string "Author commits as this email for this identity.")
+ (signing-key string "Sign commits using this key for this identity."))
+
+(define (list-of-identities? thing)
+ (and (list? thing) (every home-git-identity? thing)))
+
+(define-configuration/no-serialization home-git-configuration
+ (default-email string "Author git commits as this email.")
+ (default-signing-key string "Sign git commits using this email.")
+ (identities (list-of-identities '()) "Override default configuration values
+under specific directories, e.g. to use a work identity in a directory
+containing work projects."))
+
+(define (gitconfig-includes identities)
+ (if (null? identities) '()
+ (cons (match-record (car identities) <home-git-identity>
+ (name root-directory)
+ ;; A relative path is relative to the gitconfig file.
+ (format #f "[includeIf \"gitdir:~a/**\"]\n\tpath = ~aconfig"
+ (string-trim-right root-directory #\/) name))
+ (gitconfig-includes (cdr identities)))))
+
+(define (gitconfig-otherfiles identities)
+ (if (null? identities) '()
+ (cons (match-record (car identities) <home-git-identity>
+ (name email signing-key)
+ (list
+ (string-append "git/" name "config")
+ (plain-file (string-append "git" name "config")
+ (string-append
+ "[user]\n"
+ (if email (string-append "\temail = " email "\n") "")
+ (if signing-key (string-append "\tsigningkey = " signing-key "\n") "")))))
+ (gitconfig-otherfiles (cdr identities)))))
+
+(define (gitconfig config)
+ (match-record config <home-git-configuration>
+ (default-email default-signing-key identities)
+ `(,@(gitconfig-otherfiles identities)
+ ("git/config" ,(mixed-text-file "gitconfig" "\
+# This is Git's per-user configuration file.
+[user]
+ name = Timo Wilken
+ email = " default-email "
+ signingkey = " default-signing-key
+ (string-join (gitconfig-includes identities) "\n" 'prefix) "
+[commit]
+ gpgsign = true
+[url \"ssh://git@gitlab.cern.ch:7999/\"]
+ insteadOf = https://gitlab.cern.ch/
+[url \"ssh://git@ssh.github.com/\"]
+ insteadOf = gh:
+[gui]
+ fontui = -family \\\"Fira Sans\\\" -size 10 -weight normal -slant roman -underline 0 -overstrike 0
+ fontdiff = -family \\\"Hermit\\\" -size 10 -weight normal -slant roman -underline 0 -overstrike 0
+ tabsize = 4
+[merge]
+ summary = true
+ conflictstyle = diff3
+[color]
+ ui = auto
+[pull]
+ rebase = false
+ ff = only
+[alias]
+ glog = log --decorate --graph --oneline
+ plog = log --decorate --graph --oneline --pretty=tformat:\\\"%C(yellow)%h %Cgreen%as %Cblue%<(10,trunc)%an%Cred%d%Creset %s\\\"
+[init]
+ defaultBranch = master
+[advice]
+ detachedHead = false
+ addEmptyPathspec = false
+# https://sw.kovidgoyal.net/kitty/kittens/diff/
+[diff]
+ tool = kitty
+ guitool = kitty.gui
+[difftool]
+ prompt = false
+ trustExitCode = true
+[difftool \"kitty\"]
+ cmd = " kitty "/bin/kitty +kitten diff $LOCAL $REMOTE
+[difftool \"kitty.gui\"]
+ cmd = " kitty "/bin/kitty " kitty "/bin/kitty +kitten diff $LOCAL $REMOTE
+")))))
+
+(define home-git-service-type
+ (service-type
+ (name 'git)
+ (extensions
+ (list (service-extension home-xdg-configuration-files-service-type gitconfig)))
+ (description "Configure Git.")))
diff --git a/tw/services/gnupg.scm b/tw/services/gnupg.scm
new file mode 100644
index 00000000..9b358ea4
--- /dev/null
+++ b/tw/services/gnupg.scm
@@ -0,0 +1,94 @@
+(define-module (tw services gnupg)
+ #:use-module (gnu)
+ #:use-module (gnu home services)
+ #:use-module (gnu home services shepherd)
+ #:use-module (gnu packages gnupg)
+ #:use-module ((gnu packages image-viewers)
+ #:select (imv))
+ #:use-module (gnu services configuration)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module ((guix records) #:select (match-record))
+ #:export (home-gnupg-configuration
+ home-gnupg-service-type))
+
+(define-configuration/no-serialization home-gnupg-configuration
+ (default-key string "The user's own key. Always encrypt to this key, and
+use it by default.")
+ (gui-pinentry? boolean "Use pinentry-rofi if true, else pinentry-tty.")
+ (keyserver (string "hkps://keys.openpgp.org") "The default keyserver to use.")
+ (gnupg (package gnupg) "The GnuPG package to use.")
+ (image-viewer (file-like (file-append imv "/bin/imv")) "A gexp returning a
+string, specifying the command to call in order to view images.")
+ (gnupghome (string "$XDG_DATA_HOME/gnupg") "The value of $GNUPGHOME in the
+environment."))
+
+(define (gnupg-xdg config)
+ `(("GNUPGHOME" . ,(home-gnupg-configuration-gnupghome config))))
+
+(define (gnupg-files config)
+ (match-record config <home-gnupg-configuration>
+ (default-key gui-pinentry? keyserver image-viewer)
+ `(;; GnuPG config files must be in ~/.local/share/gnupg, not ~/.config,
+ ;; so we can't use `home-xdg-configuration-files-service-type'.
+ (".local/share/gnupg/dirmngr.conf"
+ ,(mixed-text-file "dirmngr.conf"
+ "keyserver " keyserver "\n"))
+ (".local/share/gnupg/gpg.conf"
+ ,(mixed-text-file "gpg.conf" "\
+# This options file can contain any long options to GnuPG.
+# See the gpg man page for a list of options.
+# Comments can only be at the start of a line, not after options.
+
+default-key " default-key "
+default-recipient-self
+use-agent
+# Get rid of the copyright notice.
+no-greeting
+# Always encrypt to my key as well, in addition to any recipient.
+encrypt-to " default-key "
+auto-key-import
+auto-key-retrieve
+photo-viewer \"" image-viewer " %i\"
+
+# Because some mailers change lines starting with 'From ' to '>From '
+# it is good to handle such lines in a special way when creating
+# cleartext signatures; all other PGP versions do it this way too.
+# To enable full OpenPGP compliance you may want to use this option.
+#no-escape-from-lines
+"))
+ (".local/share/gnupg/gpg-agent.conf"
+ ,(mixed-text-file "gpg-agent.conf" "\
+pinentry-program " (if gui-pinentry?
+ (file-append pinentry-rofi "/bin/pinentry-rofi")
+ (file-append pinentry-tty "/bin/pinentry-tty")) "
+# Keep passphrase cached for longer, so that mcron jobs (e.g. restic,
+# vdirsyncer) can access the password store. Vdirsyncer should run every half
+# hour to extend the default-cache-ttl.
+default-cache-ttl 2100 # 35 min
+max-cache-ttl 43200 # 12 h
+# Needed if spawning lots of parallel gpg --decrypt processes. https://dev.gnupg.org/T3530
+auto-expand-secmem
+")))))
+
+(define (gnupg-shepherd config)
+ (match-record config <home-gnupg-configuration> (gnupg)
+ (list (shepherd-service
+ (documentation "GPG agent; caches key passwords.")
+ (provision '(gpg-agent))
+ (start #~(lambda _
+ (invoke #$(file-append gnupg "/bin/gpg-agent")
+ "--daemon" "--no-detach")))
+ (stop #~(lambda _
+ (invoke #$(file-append gnupg "/bin/gpg-connect-agent")
+ "killagent" "/bye")))))))
+
+(define home-gnupg-service-type
+ (service-type
+ (name 'gnupg)
+ (extensions
+ (list (service-extension home-shepherd-service-type gnupg-shepherd)
+ (service-extension home-files-service-type gnupg-files)
+ (service-extension home-environment-variables-service-type gnupg-xdg)))
+ (description
+ "Install GnuPG configuration files and run the agent.")))