Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ some limited ability to make the manipulations dynamic.
![shadowenv in action](https://burkelibbey.s3.amazonaws.com/shadowenv.gif)

In order to use shadowenv, add a line to your shell profile (`.zshrc`, `.bash_profile`,
`config.fish`, or `config.nu`) reading:
or `config.fish`) reading:

```bash
eval "$(shadowenv init bash)" # for bash
eval "$(shadowenv init zsh)" # for zsh
shadowenv init fish | source # for fish
# for nushell, paste the output of `shadowenv init nushell` into config.nu
```

For nushell, run `shadowenv init nushell` which will install a hook into nushell's autoload directory.

With this code loaded, upon entering a directory containing a `.shadowenv.d` directory,
any `*.lisp` files in that directory will be executed and you will see "activated shadowenv." in your
shell.
Expand Down
2 changes: 1 addition & 1 deletion src/exec_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub fn run(cmd: ExecCmd) -> Result<(), Error> {
let data = Shadowenv::from_env();
let pathbuf = cmd
.dir
.map(|d| PathBuf::from(d))
.map(PathBuf::from)
.unwrap_or(get_current_dir_or_exit());

if let Some(shadowenv) = hook::load_env(pathbuf, data, true, false)? {
Expand Down
53 changes: 44 additions & 9 deletions src/init.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use crate::cli::InitCmd::{self, *};
use anyhow::{anyhow, Context, Result};
use std::fs;
use std::path::PathBuf;
use std::process::Command;

/// print a script that can be sourced into the provided shell, and sets up the shadowenv shell
/// hooks.
pub fn run(cmd: InitCmd) {
pub fn run(cmd: InitCmd) -> Result<()> {
let pb = std::env::current_exe().unwrap(); // this would be... an unusual failure.
match cmd {
Bash(opts) => print_script(
Expand All @@ -21,15 +24,47 @@ pub fn run(cmd: InitCmd) {
include_bytes!("../sh/shadowenv.fish.in"),
true, // Fish doesn't use hookbook
),
Nushell => print_script(
pb,
include_bytes!("../sh/shadowenv.nushell.in"),
true, // Nushell doesn't use hookbook
),
};
Nushell => install_nushell_hook(pb),
}
}

fn install_nushell_hook(selfpath: PathBuf) -> Result<()> {
let output = Command::new("nu")
.args(["-c", "$nu.user-autoload-dirs | first"])
.output()
.map_err(|e| {
if e.kind() == std::io::ErrorKind::NotFound {
anyhow!("Could not find 'nu' in PATH. Please ensure nushell is installed.")
} else {
anyhow!("Failed to run 'nu': {}", e)
}
})?;

if !output.status.success() {
return Err(anyhow!(
"Failed to query nushell autoload directory: {}",
String::from_utf8_lossy(&output.stderr).trim()
));
}

let autoload_dir = String::from_utf8_lossy(&output.stdout).trim().to_string();
let autoload_path = PathBuf::from(&autoload_dir);

fs::create_dir_all(&autoload_path)
.with_context(|| format!("Failed to create autoload directory '{}'", autoload_dir))?;

let script_path = autoload_path.join("shadowenv.nu");
let script = String::from_utf8_lossy(include_bytes!("../sh/shadowenv.nushell.in"));
let script = script.replace("@SELF@", selfpath.to_str().unwrap());

fs::write(&script_path, script.as_bytes())
.with_context(|| format!("Failed to write '{}'", script_path.display()))?;

println!("Wrote shadowenv hook to {}", script_path.display());
Ok(())
}

fn print_script(selfpath: PathBuf, bytes: &[u8], no_hookbook: bool) -> i32 {
fn print_script(selfpath: PathBuf, bytes: &[u8], no_hookbook: bool) -> Result<()> {
let script = String::from_utf8_lossy(bytes);
let script = script.replace("@SELF@", selfpath.into_os_string().to_str().unwrap());

Expand All @@ -44,5 +79,5 @@ fn print_script(selfpath: PathBuf, bytes: &[u8], no_hookbook: bool) -> i32 {
let script = script.replace("@HOOKBOOK@", &padded_hookbook);
println!("{}", script);
}
0
Ok(())
}
2 changes: 1 addition & 1 deletion src/lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl ShadowenvWrapper {
fn new(shadowenv: Shadowenv) -> Self {
Self(RefCell::new(shadowenv))
}
fn borrow_mut_env(&self) -> std::cell::RefMut<Shadowenv> {
fn borrow_mut_env(&self) -> std::cell::RefMut<'_, Shadowenv> {
self.0.borrow_mut()
}
fn borrow_env(&self) -> Ref<'_, Shadowenv> {
Expand Down
12 changes: 9 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@ fn main() {
use cli::ShadowenvApp::*;

let result = match cli::ShadowenvApp::parse() {
Diff(cmd) => Ok(diff::run(cmd)),
Diff(cmd) => {
diff::run(cmd);
Ok(())
}
Exec(cmd) => exec_cmd::run(cmd),
Hook(cmd) => hook::run(cmd),
Init(cmd) => Ok(init::run(cmd)),
Init(cmd) => init::run(cmd),
Trust(_) => trust::run(),
PromptWidget(_) => Ok(prompt_widget::run()),
PromptWidget(_) => {
prompt_widget::run();
Ok(())
}
};

if let Err(err) = result {
Expand Down
Loading