Commit e317e16b authored by AdminXVII's avatar AdminXVII Committed by Michael Aaron Murphy
Browse files

feat: dd the source-sh to improve compatibility with POSIX environments

Many tools rely on the current shell being a POSIX shell to set
environments (ex: Nix). Add the `source-sh` builtin which spawns the sh
shell, and then sync the new environment variables.

Also, a update the new fmt
parent 6b250581
......@@ -808,6 +808,7 @@ dependencies = [
"ion-ranges 0.1.0",
"itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lexical 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mktemp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.15.0 (git+https://github.com/AdminXVII/nix?branch=add-redox-support)",
"object-pool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"permutate 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -979,6 +980,14 @@ dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mktemp"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.14.1"
......@@ -2025,6 +2034,14 @@ dependencies = [
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "uuid"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vec_map"
version = "0.8.1"
......@@ -2299,6 +2316,7 @@ source = "git+https://gitlab.redox-os.org/redox-os/termion#c27678efc2ed14576361c
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
"checksum mktemp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "edf4fc746c5c977923b802d86fc9a95ca79a27d8c487613f68830d68d07c7b27"
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
"checksum nix 0.15.0 (git+https://github.com/AdminXVII/nix?branch=add-redox-support)" = "<none>"
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
......@@ -2419,6 +2437,7 @@ source = "git+https://gitlab.redox-os.org/redox-os/termion#c27678efc2ed14576361c
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum users 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c72f4267aea0c3ec6d07eaabea6ead7c5ddacfafc5e22bcf8d186706851fb4cf"
"checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363"
"checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum vecmath 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "956ae1e0d85bca567dee1dcf87fb1ca2e792792f66f87dced8381f99cd91156a"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
......
......@@ -80,6 +80,7 @@ atty = "0.2"
permutate = "0.3"
xdg = "2.1"
nix = { git = "https://github.com/AdminXVII/nix", branch = "add-redox-support" }
mktemp = "0.4"
# window example
piston-ai_behavior = { version = "0.31", optional = true }
......
......@@ -41,11 +41,14 @@ use crate::{
use builtins_proc::builtin;
use itertools::Itertools;
use liner::{Completer, Context, Prompt};
use mktemp::Temp;
use std::{
borrow::Cow,
collections::HashMap,
io::{self, BufRead},
fs::File,
io::{self, BufRead, BufReader},
path::{Path, PathBuf},
process::{Command, Stdio},
};
const HELP_DESC: &str = "Display helpful information about a given command or list commands if \
......@@ -240,11 +243,73 @@ impl<'a> BuiltinMap<'a> {
///
/// Contains `eval`, `set`
pub fn with_unsafe(&mut self) -> &mut Self {
self.add("eval", &builtin_eval, "Evaluates the evaluated expression").add(
"set",
&builtin_set,
"Set or unset values of shell options and positional parameters.",
)
self.add("eval", &builtin_eval, "Evaluates the evaluated expression")
.add(
"set",
&builtin_set,
"Set or unset values of shell options and positional parameters.",
)
.add("source-sh", &builtin_source_sh, "Execute a sh script and load the env diff")
}
}
#[builtin(
desc = "execute a sh script and source environment variables",
man = "
SYNOPSYS
source-sh SCRIPT
DESCRIPTION
Execute the script literal given in argument and apply env vars diff to the current shell"
)]
pub fn source_sh(args: &[types::Str], _shell: &mut Shell<'_>) -> Status {
let arg = match args.get(1) {
None => return Status::bad_argument("Please pass a shell script as option"),
Some(arg) => arg,
};
let temp = match Temp::new_file() {
Ok(f) => f,
Err(e) => return Status::error(format!("Could not create temp file for source-sh: {}", e)),
};
let script = format!("{};env | sort > {}", arg, temp.as_path().display());
match Command::new("sh")
.args(&["-c", &script])
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
{
Ok(_) => {
let env = match File::open(temp) {
Ok(env) => env,
Err(e) => {
return Status::error(format!("Could not read script environment: {}", e))
}
};
for var in BufReader::new(env).lines() {
let var = match var {
Ok(v) => v,
Err(e) => return Status::error(format!("Could not read env: {}", e)),
};
let mut iter = var.splitn(2, "=");
let name = iter.next().unwrap();
let val = match iter.next() {
Some(v) => v,
None => {
return Status::error(format!(
"Could not parse env file, no value for: '{}'",
name
))
}
};
let prev_val = std::env::var_os(name);
if prev_val.as_ref().and_then(|x| x.to_str()) != Some(val) {
std::env::set_var(name, val);
}
}
Status::SUCCESS
}
Err(e) => Status::error(format!("Could not execute sh script: {}", e)),
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment