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' 'config:Configure a setting'
'list:List tracked files' 'list:List tracked files'
'alt:Create links for alternates' 'alt:Create links for alternates'
'bootstrap:Execute $HOME/.yadm/bootstrap' 'bootstrap:Execute $HOME/.config/yadm/bootstrap'
'encrypt:Encrypt files' 'encrypt:Encrypt files'
'decrypt:Decrypt files' 'decrypt:Decrypt files'
'perms:Fix perms for private files' 'perms:Fix perms for private files'

View File

@ -8,7 +8,7 @@ CONFIG = 'config'
ENCRYPT = 'encrypt' ENCRYPT = 'encrypt'
HOME = '/testhome' HOME = '/testhome'
REPO = 'repo.git' REPO = 'repo.git'
YDIR = '.yadm' YDIR = '.config/yadm'
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -70,6 +70,7 @@ def run_test(runner, paths, args, expected_matches, expected_code=0):
script = f""" script = f"""
YADM_TEST=1 HOME="{HOME}" source {paths.pgm} YADM_TEST=1 HOME="{HOME}" source {paths.pgm}
process_global_args {argstring} process_global_args {argstring}
HOME="{HOME}" set_yadm_dir
configure_paths configure_paths
declare -p | grep -E '(YADM|GIT)_' 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 VERSION=1.12.0
YADM_WORK="$HOME" 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_REPO="repo.git"
YADM_CONFIG="config" YADM_CONFIG="config"
YADM_ENCRYPT="encrypt" YADM_ENCRYPT="encrypt"
@ -558,16 +560,16 @@ Commands:
yadm config <name> <value> - Configure a setting yadm config <name> <value> - Configure a setting
yadm list [-a] - List tracked files yadm list [-a] - List tracked files
yadm alt - Create links for alternates yadm alt - Create links for alternates
yadm bootstrap - Execute \$HOME/.yadm/bootstrap yadm bootstrap - Execute \$HOME/.config/yadm/bootstrap
yadm encrypt - Encrypt files yadm encrypt - Encrypt files
yadm decrypt [-l] - Decrypt files yadm decrypt [-l] - Decrypt files
yadm perms - Fix perms for private files yadm perms - Fix perms for private files
Files: Files:
\$HOME/.yadm/config - yadm's configuration file \$HOME/.config/yadm/config - yadm's configuration file
\$HOME/.yadm/repo.git - yadm's Git repository \$HOME/.config/yadm/repo.git - yadm's Git repository
\$HOME/.yadm/encrypt - List of globs used for encrypt/decrypt \$HOME/.config/yadm/encrypt - List of globs used for encrypt/decrypt
\$HOME/.yadm/files.gpg - Encrypted data stored here \$HOME/.config/yadm/files.gpg - Encrypted data stored here
Use "man yadm" for complete documentation. Use "man yadm" for complete documentation.
EOF 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() { function configure_paths() {
# change all paths to be relative to YADM_DIR # change all paths to be relative to YADM_DIR
@ -1138,6 +1220,7 @@ function echo_e() {
if [ "$YADM_TEST" != 1 ] ; then if [ "$YADM_TEST" != 1 ] ; then
process_global_args "$@" process_global_args "$@"
set_operating_system set_operating_system
set_yadm_dir
configure_paths configure_paths
main "${MAIN_ARGS[@]}" main "${MAIN_ARGS[@]}"
fi fi

34
yadm.1
View File

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