Navigation Menu

Skip to content

Commit

Permalink
Make shell a config file setting
Browse files Browse the repository at this point in the history
- Setting `shell = "bash"` in the config file will now make the global
  `match` value default to Bash relevant matches.
  • Loading branch information
rossmacarthur committed Jul 27, 2020
1 parent 9951723 commit ed872e9
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 57 deletions.
65 changes: 58 additions & 7 deletions README.md
Expand Up @@ -49,6 +49,7 @@
- [Command line interface](#command-line-interface)
- [`lock` command](#lock-command)
- [`source` command](#source-command)
- [`init` command](#init-command)
- [`add` command](#add-command)
- [`edit` command](#edit-command)
- [`remove` command](#remove-command)
Expand All @@ -73,6 +74,7 @@
- [Example: symlinking files](#example-symlinking-files)
- [Example: overriding the PATH template](#example-overriding-the-path-template)
- [Configuration: global options](#configuration-global-options)
- [`shell`](#shell)
- [`match`](#match)
- [`apply`](#apply-1)
- [Examples](#examples)
Expand Down Expand Up @@ -130,18 +132,27 @@ required plugin sources, generate a lock file, and then output shell source.

By default the config file is located at `~/.sheldon/plugins.toml`. You can
either edit this file directly or use the provided command line interface to add
or remove plugins. To add your first plugin to the config file run the `sheldon
add` command.
or remove plugins. To initialize this file run the following.

```sh
sheldon init --shell bash
```

or if you're using Zsh

```sh
sheldon init
```

To add your first plugin to the config file run the `sheldon add` command.

```sh
sheldon add oh-my-zsh --github "ohmyzsh/ohmyzsh"
```

The first argument given here `oh-my-zsh` is a unique name for the plugin. The
`--github` option specifies that we want **sheldon** to manage a clone of
http://github.com/ohmyzsh/ohmyzsh. If this is the first time you are running
**sheldon**, you will be asked if you want to initialize a new config file at
`~/.sheldon/plugins.toml`.
http://github.com/ohmyzsh/ohmyzsh.

You can then use `sheldon source` to install the configured plugins, generate
the lock file, and print out the shell script to source. Simply add the
Expand Down Expand Up @@ -187,6 +198,23 @@ configuration prior to generating the script. The output of this command is
highly configurable. You can define your own [custom
templates](#configuration-templates) to apply to your plugins.

### `init` command

This command initializes a new config file. If a config file exists then this
command is a noop.

For example

```sh
sheldon init
```

Or you can specify the shell.

```sh
sheldon init --shell bash
```

### `add` command

This command adds a new plugin to the config file. It does nothing else but edit
Expand Down Expand Up @@ -564,6 +592,17 @@ apply = ["source", "PATH"]

## Configuration: global options

### `shell`

Indicates the shell that you are using **sheldon** with. If this field is set to
`bash` the global [`match`](#match) default configuration will use Bash relevant
defaults. If you are using Zsh you don't need to set this value but you may set
it to `zsh`. For example

```toml
shell = "bash"
```

### `match`

A list of glob patterns to match against a plugin's contents. The first pattern
Expand All @@ -583,8 +622,20 @@ match = [
]
```

**Note:** if you are not using [Zsh] then you should probably change this
setting.
If `shell = "bash"` then this defaults to

```toml
match = [
"{{ name }}.plugin.bash",
"{{ name }}.plugin.sh",
"{{ name }}.bash",
"{{ name }}.sh",
"*.plugin.bash",
"*.plugin.sh",
"*.bash",
"*.sh"
]
```

### `apply`

Expand Down
42 changes: 38 additions & 4 deletions src/config.rs
Expand Up @@ -29,7 +29,7 @@ const GITHUB_HOST: &str = "github.com";
/////////////////////////////////////////////////////////////////////////

/// The type of shell that we are using.
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Shell {
Bash,
Zsh,
Expand Down Expand Up @@ -170,6 +170,8 @@ pub enum Plugin {
#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct RawConfig {
/// What type of shell is being used.
pub shell: Option<Shell>,
/// Which files to match and use in a plugin's directory.
#[serde(rename = "match")]
matches: Option<Vec<String>>,
Expand All @@ -187,6 +189,8 @@ pub struct RawConfig {
/// The user configuration.
#[derive(Debug)]
pub struct Config {
/// What type of shell is being used.
pub shell: Option<Shell>,
/// Which files to match and use in a plugin's directory.
pub matches: Option<Vec<String>>,
/// The default list of template names to apply to each matched file.
Expand Down Expand Up @@ -258,6 +262,7 @@ macro_rules! impl_serialize_as_str {
};
}

impl_serialize_as_str!(Shell);
impl_serialize_as_str!(GitProtocol);
impl_serialize_as_str!(GistRepository);
impl_serialize_as_str!(GitHubRepository);
Expand Down Expand Up @@ -503,6 +508,7 @@ macro_rules! impl_deserialize_from_str {
};
}

impl_deserialize_from_str!(shell, Shell, "a supported shell type");
impl_deserialize_from_str!(git_protocol, GitProtocol, "a Git protocol type");
impl_deserialize_from_str!(gist_repository, GistRepository, "a Gist identifier");
impl_deserialize_from_str!(github_repository, GitHubRepository, "a GitHub repository");
Expand Down Expand Up @@ -775,6 +781,7 @@ impl RawConfig {
/// Normalize a `RawConfig` into a `Config`.
fn normalize(self, mut warnings: &mut Vec<Error>) -> Result<Config> {
let Self {
shell,
matches,
apply,
templates,
Expand Down Expand Up @@ -822,6 +829,7 @@ impl RawConfig {
}

Ok(Config {
shell,
matches,
apply,
templates,
Expand Down Expand Up @@ -849,9 +857,10 @@ mod tests {
use super::*;
use pretty_assertions::assert_eq;

#[derive(Debug, Deserialize)]
struct TemplateTest {
t: Template,
#[test]
fn shell_to_string() {
assert_eq!(Shell::Bash.to_string(), "bash");
assert_eq!(Shell::Zsh.to_string(), "zsh");
}

#[test]
Expand Down Expand Up @@ -884,6 +893,31 @@ mod tests {
assert_eq!(test.to_string(), "rossmacarthur/sheldon-test");
}

#[derive(Debug, Deserialize)]
struct ShellTest {
s: Shell,
}

#[test]
fn shell_deserialize_as_str() {
let test: ShellTest = toml::from_str("s = 'bash'").unwrap();
assert_eq!(test.s, Shell::Bash)
}

#[test]
fn shell_deserialize_invalid() {
let error = toml::from_str::<ShellTest>("s = 'ksh'").unwrap_err();
assert_eq!(
error.to_string(),
"expected one of `bash` or `zsh` for key `s` at line 1 column 5"
)
}

#[derive(Debug, Deserialize)]
struct TemplateTest {
t: Template,
}

#[test]
fn template_deserialize_as_str() {
let test: TemplateTest = toml::from_str("t = 'test'").unwrap();
Expand Down
30 changes: 0 additions & 30 deletions src/configs/bash.plugins.toml

This file was deleted.

31 changes: 28 additions & 3 deletions src/edit.rs
Expand Up @@ -32,10 +32,20 @@ impl fmt::Display for Config {
}

impl Config {
pub fn default(shell: Shell) -> Self {
/// Returns the default `Config` for the given shell.
pub fn default(shell: Option<Shell>) -> Self {
let config = include_str!("plugins.toml");
match shell {
Shell::Bash => Self::from_str(include_str!("configs/bash.plugins.toml")).unwrap(),
Shell::Zsh => Self::from_str(include_str!("configs/zsh.plugins.toml")).unwrap(),
Some(shell) => {
// FIXME: figure out how to do this with `toml_edit`, it always places
// shell = ... above the header comment.
let config = config.replace(
"\n[plugins]",
&format!("\nshell = \"{}\"\n\n[plugins]", shell),
);
Self::from_str(config).unwrap()
}
None => Self::from_str(config).unwrap(),
}
}

Expand Down Expand Up @@ -123,6 +133,21 @@ mod tests {
use std::{io::Write, path::PathBuf};
use url::Url;

#[test]
fn config_default() {
Config::default(None);
}

#[test]
fn config_default_bash() {
Config::default(Some(Shell::Bash));
}

#[test]
fn config_default_zsh() {
Config::default(Some(Shell::Zsh));
}

#[test]
fn config_from_str_invalid() {
Config::from_str("x = \n").unwrap_err();
Expand Down
12 changes: 3 additions & 9 deletions src/lib.rs
Expand Up @@ -29,7 +29,7 @@ use anyhow::{bail, Context as ResultExt, Error, Result};

use crate::{
cli::{Command, Opt},
config::{Config, Shell},
config::Config,
context::{Context, EditContext, LockContext, SettingsExt},
edit::Plugin,
lock::LockedConfig,
Expand All @@ -52,19 +52,13 @@ impl Sheldon {
bail!("aborted initialization!");
};

let shell = ctx.shell.unwrap_or_else(|| {
casual::prompt("Are you using sheldon with Bash or Zsh? [default: zsh] ")
.default(Shell::default())
.get()
});

if let Some(parent) = path.parent() {
fs::create_dir_all(parent).with_context(s!(
"failed to create directory `{}`",
&ctx.replace_home(parent).display()
))?;
}
Ok(edit::Config::default(shell))
Ok(edit::Config::default(ctx.shell))
} else {
Err(err)
}
Expand All @@ -78,7 +72,7 @@ impl Sheldon {
.with_context(s!("failed to check `{}`", path.display()))
{
Ok(_) => {
header!(ctx, "Checked", path);
header!(ctx, "Already initialized", path);
}
Err(err) => {
Self::init_config(ctx, path, err)?.to_path(path)?;
Expand Down

0 comments on commit ed872e9

Please sign in to comment.