[services] Make git-sync script more universal
Can now sync any folder, passed in on the command line.
This commit is contained in:
parent
c93cf0fc27
commit
a6096c25ef
3 changed files with 89 additions and 27 deletions
|
@ -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
|
||||||
|
|
|
@ -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."
|
|
||||||
|
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
|
exit 1
|
||||||
}
|
}
|
||||||
|
DIR="${GS_TARGETDIR:-$1}"
|
||||||
DIR="${NOTEDIR:-$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,10 +55,16 @@ 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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch_changes() {
|
||||||
no_change_cycle=0
|
no_change_cycle=0
|
||||||
while true; do
|
while true; do
|
||||||
if should_commit; then
|
if should_commit; then
|
||||||
|
@ -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
40
services/README.md
Normal 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`.
|
Loading…
Reference in a new issue