diff --git a/src/tup/option.c b/src/tup/option.c index f1ac6021b..e65d48a0c 100644 --- a/src/tup/option.c +++ b/src/tup/option.c @@ -47,6 +47,7 @@ #define OPT_MAX 256 +static char xdg_config_home_loc[PATH_MAX]; static char home_loc[PATH_MAX]; static struct { @@ -58,6 +59,7 @@ static struct { { .file = TUP_OPTIONS_FILE }, { .file = home_loc }, #ifndef _WIN32 + { .file = xdg_config_home_loc }, { .file = "/etc/tup/options" }, #endif }; @@ -67,6 +69,9 @@ static int parse_option_file(int x); static const char *cpu_number(void); static const char *stdout_isatty(void); static const char *get_console_width(void); +#ifndef _WIN32 +static int init_xdg_config_home_loc(void); +#endif static int init_home_loc(void); static struct option { @@ -283,6 +288,11 @@ int tup_option_init(int argc, char **argv) options[x].default_value = options[x].generator(); } +#ifndef _WIN32 + if (init_xdg_config_home_loc() < 0) + return -1; +#endif + if(init_home_loc() < 0) return -1; @@ -535,6 +545,28 @@ static const char *stdout_isatty(void) return buf; } +#ifndef _WIN32 +static int init_xdg_config_home_loc(void) { + const char *base_dir; + const char *fmt_string; + + if ((base_dir = getenv("XDG_CONFIG_HOME")) && *base_dir != '\0') + fmt_string = "%s/tup/options"; + else if ((base_dir = getenv("HOME"))) + fmt_string = "%s/.config/tup/options"; + else + return 0; + + if (snprintf(xdg_config_home_loc, sizeof(xdg_config_home_loc), fmt_string, base_dir) + >= (signed)sizeof(xdg_config_home_loc)) { + fprintf(stderr, "tup internal error: user-level options file string is too small.\n"); + return -1; + } + + return 0; +} +#endif + static int init_home_loc(void) { #if defined(_WIN32) diff --git a/test/t1007-tupoptions.sh b/test/t1007-tupoptions.sh index e581b0744..6a0348f44 100755 --- a/test/t1007-tupoptions.sh +++ b/test/t1007-tupoptions.sh @@ -30,10 +30,34 @@ check() . ./tup.sh check_no_windows HOME environment variable -# Override HOME so we can control ~/.tupoptions +# Override HOME and XDG_CONFIG_HOME so we can control +# the location of the options files. + +# Test ${XDG_CONFIG_HOME:-$HOME/.config}/tup/options export HOME=`pwd` +export XDG_CONFIG_HOME= check keep_going 0 +mkdir -p "$HOME/.config/tup" +cat > .config/tup/options << HERE +[updater] +num_jobs = 4 +keep_going = 1 +HERE +check num_jobs 4 +check keep_going 1 + +export XDG_CONFIG_HOME="$HOME/.alt_config" +check keep_going 0 + +mkdir -p "$XDG_CONFIG_HOME/tup" +cat > "$XDG_CONFIG_HOME/tup/options" << HERE +[updater] +num_jobs = 5 +HERE +check num_jobs 5 + +# Test ~/.tupoptions, which overrides the previous file. cat > .tupoptions << HERE [updater] num_jobs = 2 diff --git a/tup.1 b/tup.1 index 51fde0852..4c942571a 100644 --- a/tup.1 +++ b/tup.1 @@ -243,6 +243,7 @@ The options are read in the following precedence order: .nf command-line overrides (eg: -j flag passed to 'tup') \&.tup/options file + ${XDG_CONFIG_HOME:-$HOME/.config}/tup/options ~/.tupoptions file /etc/tup/options file tup's compiled in defaults