Skip to content

Commit c3f87dd

Browse files
committed
Use XDG directories by default
Fallback to the old directory and log a deprecation warning.
1 parent 708bd9e commit c3f87dd

48 files changed

Lines changed: 239 additions & 185 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,17 @@ or
144144
sheldon init --shell zsh
145145
```
146146

147-
This will create `plugins.toml` under `~/.sheldon` or, if defined,
148-
`$XDG_CONFIG_HOME/sheldon`. You can either edit this file directly or use the
149-
provided command line interface to add or remove plugins.
147+
This will create `plugins.toml` under `$XDG_CONFIG_HOME/sheldon`, on most
148+
systems this will be `~/.config/sheldon/plugins.toml`. You can either edit this
149+
file directly or use the provided command line interface to add or remove
150+
plugins.
150151

151152
### Adding a plugin
152153

153154
To add your first plugin append the following to the Sheldon config file.
154155

155156
```toml
156-
# ~/.sheldon/plugins.toml
157+
# ~/.config/sheldon/plugins.toml
157158

158159
[plugins.base16]
159160
github = "chriskempson/base16-shell"
@@ -217,10 +218,10 @@ sheldon init --shell zsh
217218

218219
### `lock`
219220

220-
The `lock` command installs the plugins sources and generates the lock file
221-
(`~/.sheldon/plugins.lock`). Rerunning this command without any extra options
222-
will not reinstall plugin sources, just verify that they are correctly
223-
installed. It will always regenerate the lock file.
221+
The `lock` command installs the plugins sources and generates the lock file.
222+
Rerunning this command without any extra options will not reinstall plugin
223+
sources, just verify that they are correctly installed. It will always
224+
regenerate the lock file.
224225

225226
```sh
226227
sheldon lock
@@ -324,20 +325,15 @@ be required if you are using an obscure operating system.
324325

325326
*Environment variable:* `SHELDON_CONFIG_DIR`
326327

327-
Set the config directory where config will store the configuration file. If
328-
Sheldon detects an XDG directory structure ([as described
329-
below](#xdg-directory-structure)) then this will default to
330-
`XDG_CONFIG_HOME/sheldon` otherwise it will default to `<home>/.sheldon` where
331-
`<home>` is the users home directory.
328+
Set the config directory where the configuration file will be stored. This
329+
defaults to `$XDG_CONFIG_HOME/sheldon` or `~/.config/sheldon`.
332330

333331
##### `--data-dir <path>`
334332

335333
*Environment variable:* `SHELDON_DATA_DIR`
336334

337-
Set the data directory where plugins will be downloaded to. If Sheldon detects
338-
an XDG directory structure ([as described below](#xdg-directory-structure)) then
339-
this will default to `XDG_DATA_HOME/sheldon` otherwise it will default to
340-
`<home>/.sheldon` where `<home>` is the users home directory.
335+
Set the data directory where plugins will be downloaded to. This defaults to
336+
`$XDG_DATA_HOME/sheldon` or `~/.local/share/sheldon`.
341337

342338
##### `--config-file <path>`
343339

@@ -400,7 +396,7 @@ location of the source. There are three types of sources, each kind is described
400396
in this section. A plugin may only specify *one* source type.
401397

402398
```toml
403-
# ~/.sheldon/plugins.toml
399+
# ~/.config/sheldon/plugins.toml
404400

405401
# ┌─ Unique name for the plugin
406402
# ┌──┴─┐
@@ -588,11 +584,10 @@ plugins.
588584

589585
#### `profiles`
590586

591-
A list of profiles this plugin should be used in. If this field is not given
592-
the plugin will be used regardless of the profile. Otherwise, the plugin is
593-
only used if the specified
594-
[profile](https://sheldon.cli.rs/Command-line-interface.html#--profile-profile) is included in the
595-
configured list of profiles.
587+
A list of profiles this plugin should be used in. If this field is not given the
588+
plugin will be used regardless of the profile. Otherwise, the plugin is only
589+
used if the specified [profile](https://sheldon.cli.rs/Command-line-interface.html#--profile-profile) is
590+
included in the configured list of profiles.
596591

597592
### Inline plugins
598593

@@ -643,10 +638,6 @@ github = "owner/repo"
643638
apply = ["PATH", "fpath"]
644639
```
645640

646-
The `each` value, as used in the `source` template above, specifies that the
647-
template should be applied to each matched file for the plugin. This defaults to
648-
`false`.
649-
650641
#### Custom templates
651642

652643
It is possible to create your own custom templates, and you can even override
@@ -664,10 +655,8 @@ Plugins all have the following information that can be used in templates.
664655

665656
* **One or more files.** These are the matched files in the plugin directory
666657
either discovered using the the global `match` field or specified as a plugin
667-
option with `use`. These can be used in templates using `{{ file }}`. This
668-
information only makes sense in templates with `each` set to `true`.
669-
670-
* **The Sheldon data directory.** This directory can be used as `{{ data_dir }}`.
658+
option with `use`. These can be used in templates by iterating over the files.
659+
For example: `{% for file in files %} ... {{ file }} ... {% endfor %}`.
671660

672661
To add or update a template add a new key to the `[templates]` table in the
673662
config file. Take a look at the [examples](https://sheldon.cli.rs/Examples.html) for some interesting

docs/src/Command-line-interface.md

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ sheldon init --shell zsh
3333

3434
## `lock`
3535

36-
The `lock` command installs the plugins sources and generates the lock file
37-
(`~/.sheldon/plugins.lock`). Rerunning this command without any extra options
38-
will not reinstall plugin sources, just verify that they are correctly
39-
installed. It will always regenerate the lock file.
36+
The `lock` command installs the plugins sources and generates the lock file.
37+
Rerunning this command without any extra options will not reinstall plugin
38+
sources, just verify that they are correctly installed. It will always
39+
regenerate the lock file.
4040

4141
```sh
4242
sheldon lock
@@ -140,20 +140,15 @@ be required if you are using an obscure operating system.
140140

141141
*Environment variable:* `SHELDON_CONFIG_DIR`
142142

143-
Set the config directory where config will store the configuration file. If
144-
Sheldon detects an XDG directory structure ([as described
145-
below](#xdg-directory-structure)) then this will default to
146-
`XDG_CONFIG_HOME/sheldon` otherwise it will default to `<home>/.sheldon` where
147-
`<home>` is the users home directory.
143+
Set the config directory where the configuration file will be stored. This
144+
defaults to `$XDG_CONFIG_HOME/sheldon` or `~/.config/sheldon`.
148145

149146
#### `--data-dir <path>`
150147

151148
*Environment variable:* `SHELDON_DATA_DIR`
152149

153-
Set the data directory where plugins will be downloaded to. If Sheldon detects
154-
an XDG directory structure ([as described below](#xdg-directory-structure)) then
155-
this will default to `XDG_DATA_HOME/sheldon` otherwise it will default to
156-
`<home>/.sheldon` where `<home>` is the users home directory.
150+
Set the data directory where plugins will be downloaded to. This defaults to
151+
`$XDG_DATA_HOME/sheldon` or `~/.local/share/sheldon`.
157152

158153
#### `--config-file <path>`
159154

docs/src/Configuration.md

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ location of the source. There are three types of sources, each kind is described
99
in this section. A plugin may only specify *one* source type.
1010

1111
```toml
12-
# ~/.sheldon/plugins.toml
12+
# ~/.config/sheldon/plugins.toml
1313

1414
# ┌─ Unique name for the plugin
1515
# ┌──┴─┐
@@ -197,11 +197,10 @@ plugins.
197197

198198
### `profiles`
199199

200-
A list of profiles this plugin should be used in. If this field is not given
201-
the plugin will be used regardless of the profile. Otherwise, the plugin is
202-
only used if the specified
203-
[profile](Command-line-interface.md#--profile-profile) is included in the
204-
configured list of profiles.
200+
A list of profiles this plugin should be used in. If this field is not given the
201+
plugin will be used regardless of the profile. Otherwise, the plugin is only
202+
used if the specified [profile](Command-line-interface.md#--profile-profile) is
203+
included in the configured list of profiles.
205204

206205
## Inline plugins
207206

@@ -252,10 +251,6 @@ github = "owner/repo"
252251
apply = ["PATH", "fpath"]
253252
```
254253

255-
The `each` value, as used in the `source` template above, specifies that the
256-
template should be applied to each matched file for the plugin. This defaults to
257-
`false`.
258-
259254
### Custom templates
260255

261256
It is possible to create your own custom templates, and you can even override
@@ -273,10 +268,8 @@ Plugins all have the following information that can be used in templates.
273268

274269
* **One or more files.** These are the matched files in the plugin directory
275270
either discovered using the the global `match` field or specified as a plugin
276-
option with `use`. These can be used in templates using `{{ file }}`. This
277-
information only makes sense in templates with `each` set to `true`.
278-
279-
* **The Sheldon data directory.** This directory can be used as `{{ data_dir }}`.
271+
option with `use`. These can be used in templates by iterating over the files.
272+
For example: `{% for file in files %} ... {{ file }} ... {% endfor %}`.
280273

281274
To add or update a template add a new key to the `[templates]` table in the
282275
config file. Take a look at the [examples](Examples.md) for some interesting

docs/src/Examples.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Add the following to your `~/.zshrc` file.
8282
```sh
8383
# ~/.zshrc
8484

85-
export ZSH="$HOME/.sheldon/repos/github.com/ohmyzsh/ohmyzsh"
85+
export ZSH="$HOME/.local/share/sheldon/repos/github.com/ohmyzsh/ohmyzsh"
8686

8787
# Oh My Zsh settings here
8888

docs/src/Getting-started.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@ or
1616
sheldon init --shell zsh
1717
```
1818

19-
This will create `plugins.toml` under `~/.sheldon` or, if defined,
20-
`$XDG_CONFIG_HOME/sheldon`. You can either edit this file directly or use the
21-
provided command line interface to add or remove plugins.
19+
This will create `plugins.toml` under `$XDG_CONFIG_HOME/sheldon`, on most
20+
systems this will be `~/.config/sheldon/plugins.toml`. You can either edit this
21+
file directly or use the provided command line interface to add or remove
22+
plugins.
2223

2324
## Adding a plugin
2425

2526
To add your first plugin append the following to the Sheldon config file.
2627

2728
```toml
28-
# ~/.sheldon/plugins.toml
29+
# ~/.config/sheldon/plugins.toml
2930

3031
[plugins.base16]
3132
github = "chriskempson/base16-shell"

src/cli/mod.rs

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod tests;
88

99
use std::env;
1010
use std::io;
11-
use std::path::PathBuf;
11+
use std::path::{Path, PathBuf};
1212
use std::process;
1313

1414
use anyhow::anyhow;
@@ -135,35 +135,7 @@ impl Opt {
135135
}
136136
};
137137

138-
let xdg_config_user = env::var_os("XDG_CONFIG_HOME").map(PathBuf::from);
139-
let xdg_data_user = env::var_os("XDG_DATA_HOME").map(PathBuf::from);
140-
141-
// Note: `XDG_RUNTIME_DIR` is not checked as it can be set by the system rather
142-
// than the user, and cannot be relied upon to indicate a preference for XDG
143-
// directory layout.
144-
let using_xdg = any!(
145-
xdg_data_user,
146-
xdg_config_user,
147-
env::var_os("XDG_CACHE_HOME"),
148-
env::var_os("XDG_DATA_DIRS"),
149-
env::var_os("XDG_CONFIG_DIRS")
150-
);
151-
152-
let (config_pre, data_pre) = if using_xdg {
153-
(
154-
xdg_config_user
155-
.unwrap_or_else(|| home.join(".config"))
156-
.join("sheldon"),
157-
xdg_data_user
158-
.unwrap_or_else(|| home.join(".local/share"))
159-
.join("sheldon"),
160-
)
161-
} else {
162-
(home.join(".sheldon"), home.join(".sheldon"))
163-
};
164-
165-
let config_dir = config_dir.unwrap_or(config_pre);
166-
let data_dir = data_dir.unwrap_or(data_pre);
138+
let (config_dir, data_dir) = resolve_dirs(&home, config_dir, data_dir, output.no_color);
167139
let config_file = config_file.unwrap_or_else(|| config_dir.join("plugins.toml"));
168140
let lock_file = match profile.as_deref() {
169141
Some("") | None => data_dir.join("plugins.lock"),
@@ -260,3 +232,62 @@ impl LockMode {
260232
}
261233
}
262234
}
235+
236+
fn resolve_dirs(
237+
home: &Path,
238+
config_dir: Option<PathBuf>,
239+
data_dir: Option<PathBuf>,
240+
no_color: bool,
241+
) -> (PathBuf, PathBuf) {
242+
// TODO: Remove this warning in a later release and stop falling back to
243+
// the old directory.
244+
let err = anyhow!(
245+
r#"using deprecated config file location ~/.sheldon/plugins.toml.
246+
247+
To use the new location move the config file to
248+
~/.config/sheldon/plugins.toml ($XDG_CONFIG_HOME/sheldon/plugins.toml),
249+
~/.sheldon can then be safely deleted.
250+
251+
Or to instead preserve the old behaviour set the following environment variables:
252+
SHELDON_CONFIG_DIR="$HOME/.sheldon"
253+
SHELDON_DATA_DIR="$HOME/.sheldon"
254+
255+
See the release notes at https://github.com/rossmacarthur/sheldon for more information.
256+
"#,
257+
);
258+
let mut using_old = false;
259+
let config_dir = config_dir.unwrap_or_else(|| {
260+
let default = default_config_dir(home);
261+
let old = home.join(".sheldon");
262+
if old.exists() && !default.exists() {
263+
log_error(no_color, Color::Yellow, "warning", &err);
264+
using_old = true;
265+
return old;
266+
}
267+
default
268+
});
269+
let data_dir = data_dir.unwrap_or_else(|| {
270+
let default = default_data_dir(home);
271+
if using_old && !default.exists() {
272+
return config_dir.clone();
273+
}
274+
default
275+
});
276+
(config_dir, data_dir)
277+
}
278+
279+
fn default_config_dir(home: &Path) -> PathBuf {
280+
let mut p = env::var_os("XDG_CONFIG_HOME")
281+
.map(PathBuf::from)
282+
.unwrap_or_else(|| home.join(".config"));
283+
p.push("sheldon");
284+
p
285+
}
286+
287+
fn default_data_dir(home: &Path) -> PathBuf {
288+
let mut p = env::var_os("XDG_DATA_HOME")
289+
.map(PathBuf::from)
290+
.unwrap_or_else(|| home.join(".local/share"));
291+
p.push("sheldon");
292+
p
293+
}

src/macros.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ macro_rules! s {
55
($fmt:expr, $($arg:tt)+) => (|| format!($fmt, $($arg)+))
66
}
77

8-
/// Evaluates a sequence of Options to see if any is a `Some`.
9-
macro_rules! any {
10-
($opt:expr) => { $opt.is_some() };
11-
($opt:expr, $($rest:expr),+) => { $opt.is_some() || { any!($($rest),+) }};
12-
}
13-
148
/// Call .into() on each element in a vec! initialization.
159
macro_rules! vec_into {
1610
($($i:expr),*) => (vec![$($i.into()),*]);

tests/helpers/dirs.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ impl TestDirs {
2222
}
2323

2424
pub fn default() -> io::Result<Self> {
25-
Self::new(".sheldon", ".sheldon")
26-
}
27-
28-
pub fn default_xdg() -> io::Result<Self> {
2925
Self::new(".config/sheldon", ".local/share/sheldon")
3026
}
3127

tests/helpers/process.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ impl TestCommand {
8888
self
8989
}
9090

91+
pub fn env_remove<K>(mut self, key: K) -> Self
92+
where
93+
K: AsRef<OsStr>,
94+
{
95+
self.command.env_remove(key);
96+
self
97+
}
98+
9199
pub fn envs<I, K, V>(mut self, vars: I) -> Self
92100
where
93101
I: IntoIterator<Item = (K, V)>,

0 commit comments

Comments
 (0)