[services] Make git-sync script more universal

Can now sync any folder, passed in on the command line.
This commit is contained in:
Marty Oehme 2020-06-17 21:00:41 +02:00
parent c93cf0fc27
commit a6096c25ef
No known key found for this signature in database
GPG key ID: 0CCB0526EFB9611A
3 changed files with 89 additions and 27 deletions

View file

@ -1,12 +1,13 @@
[Unit] [Unit]
Description=Automatically commit notes in directory Description=Automatically commit notes in directory
After=graphical.target After=default.target
[Service] [Service]
Type=simple Type=simple
Environment=TIME_TO_COMMIT=120 UNCHANGED_RUNS_TO_PUSH=30 Environment=GS_TIME_TO_COMMIT=120 GS_UNCHANGED_RUNS_TO_PUSH=30
ExecStart=/bin/bash -c '%h/.local/share/services/git-sync' # workaround to allow relative executable invocation (i.e. current users' home dir)
Restart=on-failure ExecStart=/bin/bash -c '%h/.local/share/services/git-sync %h/documents/notes/uni'
# Restart=on-failure
[Install] [Install]
WantedBy=multi-user.target WantedBy=default.target

View file

@ -1,17 +1,23 @@
#!/usr/bin/env sh #!/usr/bin/env sh
#
# Keeps a git directory synced by automatically committing every x seconds.
# After y number of runs without changes automatically pushes the directory to a remote.
# time in seconds to check for changes to commit # time in seconds to check for changes to commit
TIME_TO_COMMIT=${GS_TIME_TO_COMMIT:-120} TIME_TO_COMMIT=${GS_TIME_TO_COMMIT:-120}
# amount of times to check for changes *without changes occurring* to push to origin # amount of times to check for changes *without changes occurring* to push to origin
UNCHANGED_RUNS_TO_PUSH=${GS_UNCHANGED_RUNS_TO_PUSH:-30} UNCHANGED_RUNS_TO_PUSH=${GS_UNCHANGED_RUNS_TO_PUSH:-30}
NOTEDIR=${WIKIROOT:-"$HOME/documents/notes"}/uni # logging verbosity level -- 0=error, 1=info, 2=debug
[ -z "$NOTEDIR" ] && [ -z "$1" ] && { VERBOSITY=${GS_LOG_VERBOSITY:-1}
msg "ERROR: Please supply a directory to sync."
exit 1
}
DIR="${NOTEDIR:-$1}" set_target() {
[ -z "$GS_TARGETDIR" ] && [ -z "$1" ] && {
msg "ERROR: git-sync requires a target directory to keep in sync to be passed in." 0
exit 1
}
DIR="${GS_TARGETDIR:-$1}"
}
commit() { commit() {
run_git pull --ff-only --ff run_git pull --ff-only --ff
@ -28,8 +34,8 @@ push() {
} }
should_commit() { should_commit() {
if [ "$(run_git status --porcelain | wc -l)" -eq 0 ]; then if [ "$(run_git diff-files --name-only | wc -l)" -eq 0 ]; then
msg "No changes to commit in $DIR" msg "No changes to commit in $DIR" 2
false false
else else
msg "Found changes to commit in $DIR" msg "Found changes to commit in $DIR"
@ -49,12 +55,18 @@ run_git() {
git -C "$DIR" "$@" git -C "$DIR" "$@"
} }
# echos its first argument
# verbosity level optionally set through second argument
msg() { msg() {
lvl=${2:-1}
[ "$lvl" -gt "$VERBOSITY" ] && return 0
echo "$1" echo "$1"
} }
no_change_cycle=0 watch_changes() {
while true; do no_change_cycle=0
while true; do
if should_commit; then if should_commit; then
commit commit
no_change_cycle=0 no_change_cycle=0
@ -65,8 +77,17 @@ while true; do
no_change_cycle=-9999 no_change_cycle=-9999
fi fi
msg "No changes for $((no_change_cycle * TIME_TO_COMMIT)) of $((UNCHANGED_RUNS_TO_PUSH * TIME_TO_COMMIT)) seconds, going back to sleep for $((TIME_TO_COMMIT)) seconds." msg "No changes for $((no_change_cycle * TIME_TO_COMMIT)) of $((UNCHANGED_RUNS_TO_PUSH * TIME_TO_COMMIT)) seconds, going back to sleep for $((TIME_TO_COMMIT)) seconds." 2
no_change_cycle=$((no_change_cycle + 1)) no_change_cycle=$((no_change_cycle + 1))
sleep "$TIME_TO_COMMIT" sleep "$TIME_TO_COMMIT"
done done
}
main() {
set_target "$1"
watch_changes
}
main "$1"

40
services/README.md Normal file
View file

@ -0,0 +1,40 @@
# User services
This module uses `systemd` to provide various services for the user running the dotfiles.
The services will get moved into the correct `.config` directory for `systemd` to pick them up as user services.
They will, for now, *not* be automatically enabled when installing the dotfiles. This is pending changes.
They can be enabled as needed by invoking `systemctl --user enable [service]`. Be aware that
## Why systemd
There are two reasons for the service module making use of `systemd` to manage its services:
The machine(s) these dotfiles are currently targeting are both archlinux-based.
That means, pragmatically, I will adhere to using `systemd` since it is what arch uses as init manager.
I *am* eye-ing alternatives like [Artix Linux](https://artixlinux.org/) but adopting it is, if it happens at all, still a way out due to my current time constraints.
Secondly, I am using this opportunity to learn more about `systemd`.
There are various arcane-seeming invocations in `systemd` which are beginning to make more sense to me as time goes on
(looking at you, `journalctl`).
I do not want to dismiss a program without having given it a fair shake (especially if it enjoys *such* widespread adoption).
Additionally, process watching and automatic maintenance, as well as the entire `.timer` system that it can provide for services are pretty fantastic, even if their syntax takes some getting used to for me.
That said, there are also many moments where I am envious of the simplicity and straightforward nature of something like [runit](http://smarden.org/runit/).
So what that essentially means: this service module uses `systemd` *for now*.
It might change to something else in the future.
It might also not be written very well, since I am using it to adopt a mental mapping of `systemd` at the same time.
## Commit Notes service
This service keeps my university note directory in sync with a remote origin.
The script behind it (`git-sync`) can be used more generally to keep any git directory in sync.
The idea behind the services is: commit asap, push when finished.
It basically runs on two different timers, every x seconds (120 by default, can be changed with `GS_TIME_TO_COMMIT` env var) it will commit whatever changes took place in the directory.
After x runs of the commit timer *without changes* (30 by default, can be changed with `GS_UNCHANGED_RUNS_TO_PUSH`) it will push the git index to its default remote.
In effect this means, using the default values, the service will commit any changes made every two minutes and when *no* changes were made for an hour (±2minutes), it will push it to remote.
The two cycles can be changed independently from each other via the environment variables mentioned above so that, for example, the repository can be pushed every single time a commit takes place, or commits can be checked for on faster or shorter intervals.
As another example, if you want to check for changes every 30 seconds but still push every hour, you would do `GS_TIME_TO_COMMIT=30` and `GS_UNCHANGED_RUNS_TO_PUSH=120`.