Support XDG base directory specification

https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
This commit is contained in:
Tim Byrne 2019-08-06 08:19:45 -05:00
parent f0ad40376d
commit 48fc6b0db7
No known key found for this signature in database
GPG Key ID: 14DB4FC2465A4B12
6 changed files with 178 additions and 25 deletions

View File

@ -7,7 +7,7 @@ _yadm(){
'config:Configure a setting'
'list:List tracked files'
'alt:Create links for alternates'
'bootstrap:Execute $HOME/.yadm/bootstrap'
'bootstrap:Execute $HOME/.config/yadm/bootstrap'
'encrypt:Encrypt files'
'decrypt:Decrypt files'
'perms:Fix perms for private files'

View File

@ -8,7 +8,7 @@ CONFIG = 'config'
ENCRYPT = 'encrypt'
HOME = '/testhome'
REPO = 'repo.git'
YDIR = '.yadm'
YDIR = '.config/yadm'
@pytest.mark.parametrize(
@ -70,6 +70,7 @@ def run_test(runner, paths, args, expected_matches, expected_code=0):
script = f"""
YADM_TEST=1 HOME="{HOME}" source {paths.pgm}
process_global_args {argstring}
HOME="{HOME}" set_yadm_dir
configure_paths
declare -p | grep -E '(YADM|GIT)_'
"""

View File

@ -0,0 +1,34 @@
"""Unit tests: issue_legacy_path_warning"""
import pytest
@pytest.mark.parametrize(
'legacy_path', [
None,
'repo.git',
'config',
'encrypt',
'files.gpg',
'bootstrap',
'hooks',
],
)
def test_legacy_warning(tmpdir, runner, yadm, legacy_path):
"""Use issue_legacy_path_warning"""
home = tmpdir.mkdir('home')
if legacy_path:
home.mkdir(f'.yadm').mkdir(legacy_path)
script = f"""
HOME={home}
YADM_TEST=1 source {yadm}
issue_legacy_path_warning
"""
run = runner(command=['bash'], inp=script)
assert run.success
assert run.err == ''
if legacy_path:
assert 'Legacy configuration paths have been detected' in run.out
else:
assert run.out.rstrip() == ''

View File

@ -0,0 +1,35 @@
"""Unit tests: set_yadm_dir"""
import pytest
@pytest.mark.parametrize(
'condition',
['basic', 'override', 'xdg_config_home', 'legacy'],
)
def test_set_yadm_dir(runner, yadm, condition):
"""Test set_yadm_dir"""
setup = ''
if condition == 'override':
setup = 'YADM_DIR=/override'
elif condition == 'xdg_config_home':
setup = 'XDG_CONFIG_HOME=/xdg'
elif condition == 'legacy':
setup = 'YADM_COMPATIBILITY=1'
script = f"""
HOME=/testhome
YADM_TEST=1 source {yadm}
{setup}
set_yadm_dir
echo "$YADM_DIR"
"""
run = runner(command=['bash'], inp=script)
assert run.success
assert run.err == ''
if condition == 'basic':
assert run.out.rstrip() == '/testhome/.config/yadm'
elif condition == 'override':
assert run.out.rstrip() == '/override'
elif condition == 'xdg_config_home':
assert run.out.rstrip() == '/xdg/yadm'
elif condition == 'legacy':
assert run.out.rstrip() == '/testhome/.yadm'

95
yadm
View File

@ -23,8 +23,10 @@ fi
VERSION=1.12.0
YADM_WORK="$HOME"
YADM_DIR="$HOME/.yadm"
YADM_DIR=
YADM_LEGACY_DIR="${HOME}/.yadm"
# these are the default paths relative to YADM_DIR
YADM_REPO="repo.git"
YADM_CONFIG="config"
YADM_ENCRYPT="encrypt"
@ -558,16 +560,16 @@ Commands:
yadm config <name> <value> - Configure a setting
yadm list [-a] - List tracked files
yadm alt - Create links for alternates
yadm bootstrap - Execute \$HOME/.yadm/bootstrap
yadm bootstrap - Execute \$HOME/.config/yadm/bootstrap
yadm encrypt - Encrypt files
yadm decrypt [-l] - Decrypt files
yadm perms - Fix perms for private files
Files:
\$HOME/.yadm/config - yadm's configuration file
\$HOME/.yadm/repo.git - yadm's Git repository
\$HOME/.yadm/encrypt - List of globs used for encrypt/decrypt
\$HOME/.yadm/files.gpg - Encrypted data stored here
\$HOME/.config/yadm/config - yadm's configuration file
\$HOME/.config/yadm/repo.git - yadm's Git repository
\$HOME/.config/yadm/encrypt - List of globs used for encrypt/decrypt
\$HOME/.config/yadm/files.gpg - Encrypted data stored here
Use "man yadm" for complete documentation.
EOF
@ -782,6 +784,86 @@ function process_global_args() {
}
function set_yadm_dir() {
# only resolve YADM_DIR if it hasn't been provided already
[ -n "$YADM_DIR" ] && return
# compatibility with major version 1 ignores XDG_CONFIG_HOME
if [ "$YADM_COMPATIBILITY" = "1" ]; then
YADM_DIR="$YADM_LEGACY_DIR"
return
fi
local base_yadm_dir
base_yadm_dir="$XDG_CONFIG_HOME"
if [[ ! "$base_yadm_dir" =~ ^/ ]] ; then
base_yadm_dir="${HOME}/.config"
fi
YADM_DIR="${base_yadm_dir}/yadm"
issue_legacy_path_warning
}
function issue_legacy_path_warning() {
# no warnings if YADM_DIR is resolved as the leacy path
[ "$YADM_DIR" = "$YADM_LEGACY_DIR" ] && return
# no warnings if the legacy directory doesn't exist
[ ! -d "$YADM_LEGACY_DIR" ] && return
# test for legacy paths
local legacy_found
legacy_found=()
# this is ordered by importance
for legacy_path in \
"$YADM_LEGACY_DIR/$YADM_REPO" \
"$YADM_LEGACY_DIR/$YADM_CONFIG" \
"$YADM_LEGACY_DIR/$YADM_ENCRYPT" \
"$YADM_LEGACY_DIR/$YADM_ARCHIVE" \
"$YADM_LEGACY_DIR/$YADM_BOOTSTRAP" \
"$YADM_LEGACY_DIR/$YADM_HOOKS" \
; \
do
[ -e "$legacy_path" ] && legacy_found+=("$legacy_path")
done
[ ${#legacy_found[@]} -eq 0 ] && return
local path_list
for legacy_path in "${legacy_found[@]}"; do
path_list="$path_list * $legacy_path"$'\n'
done
cat <<EOF
**WARNING**
Legacy configuration paths have been detected.
Beginning with version 2.0.0, yadm uses the XDG Base Directory Specification
to find its configurations. Read more about this change here:
https://yadm.io/docs/xdg_config_home
In your environment, the configuration directory has been resolved to:
$YADM_DIR
To remove this warning do one of the following:
* Move yadm configurations to the directory listed above. (RECOMMENDED)
* Specify your preferred yadm directory with -Y each execution.
* Define an environment variable "YADM_COMPATIBILITY=1" to run in version 1
compatibility mode. (DEPRECATED)
Legacy paths detected:
${path_list}
***********
EOF
}
function configure_paths() {
# change all paths to be relative to YADM_DIR
@ -1138,6 +1220,7 @@ function echo_e() {
if [ "$YADM_TEST" != 1 ] ; then
process_global_args "$@"
set_operating_system
set_yadm_dir
configure_paths
main "${MAIN_ARGS[@]}"
fi

34
yadm.1
View File

@ -105,7 +105,7 @@ to "false".
.TP
.B bootstrap
Execute
.I $HOME/.yadm/bootstrap
.I $HOME/.config/yadm/bootstrap
if it exists.
.TP
.BI clone " url
@ -140,7 +140,7 @@ yadm stash pop
.RE
The repository is stored in
.IR $HOME/.yadm/repo.git .
.IR $HOME/.config/yadm/repo.git .
By default,
.I $HOME
will be used as the
@ -169,7 +169,7 @@ See the CONFIGURATION section for more details.
.TP
.B decrypt
Decrypt all files stored in
.IR $HOME/.yadm/files.gpg .
.IR $HOME/.config/yadm/files.gpg .
Files decrypted will be relative to the configured
.IR work-tree " (usually
.IR $HOME ).
@ -179,7 +179,7 @@ option will list the files stored without extracting them.
.TP
.B encrypt
Encrypt all files matching the patterns found in
.IR $HOME/.yadm/encrypt .
.IR $HOME/.config/yadm/encrypt .
See the ENCRYPTION section for more details.
.TP
.B enter
@ -227,7 +227,7 @@ Print a summary of
.B init
Initialize a new, empty repository for tracking dotfiles.
The repository is stored in
.IR $HOME/.yadm/repo.git .
.IR $HOME/.config/yadm/repo.git .
By default,
.I $HOME
will be used as the
@ -320,7 +320,7 @@ bootstrap program.
.SH CONFIGURATION
.B yadm
uses a configuration file named
.IR $HOME/.yadm/config .
.IR $HOME/.config/yadm/config .
This file uses the same format as
.BR git-config (1).
Also, you can control the contents of the configuration file
@ -387,7 +387,7 @@ properly interpret Cygwin symlinks.
.RE
These last four "local" configurations are not stored in the
.IR $HOME/.yadm/config,
.IR $HOME/.config/yadm/config,
they are stored in the local repository.
.TP
@ -427,7 +427,7 @@ If there are any files managed by
.BR yadm \'s
repository,
or listed in
.IR $HOME/.yadm/encrypt ,
.IR $HOME/.config/yadm/encrypt ,
which match this naming convention,
symbolic links will be created for the most appropriate version.
This may best be demonstrated by example. Assume the following files are managed by
@ -575,7 +575,7 @@ This feature will only work if the
command is available.
To use this feature, a list of patterns must be created and saved as
.IR $HOME/.yadm/encrypt .
.IR $HOME/.config/yadm/encrypt .
This list of patterns should be relative to the configured
.IR work-tree " (usually
.IR $HOME ).
@ -595,7 +595,7 @@ The
.B yadm encrypt
command will find all files matching the patterns, and prompt for a password. Once a
password has confirmed, the matching files will be encrypted and saved as
.IR $HOME/.yadm/files.gpg .
.IR $HOME/.config/yadm/files.gpg .
The patterns and files.gpg should be added to the
.B yadm
repository so they are available across multiple systems.
@ -621,10 +621,10 @@ dependent upon the user's umask. Because of this,
will automatically update the permissions of some file paths. The "group" and
"others" permissions will be removed from the following files:
.RI - " $HOME/.yadm/files.gpg
.RI - " $HOME/.config/yadm/files.gpg
- All files matching patterns in
.I $HOME/.yadm/encrypt
.I $HOME/.config/yadm/encrypt
- The SSH directory and files,
.I .ssh/*
@ -670,7 +670,7 @@ are referred to as "hooks".
.B yadm
looks for
hooks in the directory
.IR $HOME/.yadm/hooks .
.IR $HOME/.config/yadm/hooks .
Each hook is named using a prefix of
.I pre_
or
@ -725,7 +725,7 @@ uses for its own data.
These paths can be altered using universal options.
See the OPTIONS section for details.
.TP
.I $HOME/.yadm
.I $HOME/.config/yadm
The
.B yadm
directory. By default, all data
@ -763,10 +763,10 @@ Add a remote origin to an existing repository
.B yadm push -u origin master
Initial push of master to origin
.TP
.B echo ".ssh/*.key" >> $HOME/.yadm/encrypt
.B echo ".ssh/*.key" >> $HOME/.config/yadm/encrypt
Add a new pattern to the list of encrypted files
.TP
.B yadm encrypt ; yadm add ~/.yadm/files.gpg ; yadm commit
.B yadm encrypt ; yadm add ~/.config/yadm/files.gpg ; yadm commit
Commit a new set of encrypted files
.SH REPORTING BUGS
Report issues or create pull requests at GitHub:
@ -779,4 +779,4 @@ Tim Byrne <sultan@locehilios.com>
.BR git (1),
.BR gpg (1)
https://thelocehiliosan.github.io/yadm/
https://yadm.io/