From 906cb1635524d70297a20e708bcb0e0edf3021fc Mon Sep 17 00:00:00 2001 From: Ava Hahn Date: Fri, 26 May 2023 06:41:18 +0000 Subject: [PATCH] POSIX conditional compilation: * All features related to POSIX environments (env vars, shell stuff) gated by feature flags * Dependencies optional per feature flags * new CI target for non-POSIX build * new CI target for release binary artifact Signed-off-by: Ava Hahn [ava@sunnypup.io](mailto:ava@sunnypup.io) --- .gitlab-ci.yml | 20 ++++- Cargo.toml | 12 ++- Readme.org | 5 -- src/bin/relish.rs | 45 ++++++---- src/lib.rs | 3 + src/stl.rs | 18 ++-- tests/test_lib_append.rs | 70 ++++++---------- tests/test_lib_bools.rs | 92 ++++++++++---------- tests/test_lib_control.rs | 48 +++++------ tests/test_lib_decl.rs | 84 +++++++++---------- tests/test_lib_math.rs | 172 +++++++++++++++++++------------------- tests/test_lib_posix.rs | 20 ++--- tests/test_lib_str.rs | 60 ++++++------- 13 files changed, 330 insertions(+), 319 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 36d55a3..4778215 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,11 +1,29 @@ default: image: rust:latest -compile: +compile-with-posix-features: stage: build script: - cargo build +compile-without-posix-features: + stage: build + script: + - cargo build --no-default-features + +compile-release: + stage: build + script: + - cargo build --release + artifacts: + paths: + - target/release/relish + only: + variables: + - $CI_COMMIT_TAG =~ /^v\d+.\d+.\d+-?.*$/ + except: + - branches + unit-tests: stage: test script: diff --git a/Cargo.toml b/Cargo.toml index 3338b55..2efea6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,15 @@ dirs = "3.0" # these two are used in src/bin/relish.rs to manage a prompt nu-ansi-term = "0.47.0" reedline = "0.17.0" +# used by main shell to update console dimensions +termion = "2.0.1" # these two used in posix shell layer (src/stl/posix.rs) -nix = "0.26.2" +nix = { version = "0.26.2", optional = true } +libc = { version = "0.2.144", optional = true } # this one provides a global constant lookup table for simple # string escaping in the lexer phf = { version = "0.11", default-features = false, features = ["macros"] } -libc = "0.2.144" -# used by main shell to update consol dimensions -termion = "2.0.1" + +[features] +default = ["posix"] +posix = ["dep:nix", "dep:libc"] diff --git a/Readme.org b/Readme.org index 5f74b0c..2531418 100644 --- a/Readme.org +++ b/Readme.org @@ -505,11 +505,6 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt - (path functions) - (add this all to the readme) - finish basic goals in the [[file:snippets/interactive-devel.rls][interactive development library]] -- Be able to use features to compile without env or posix stuff - - add a new binary target that is a simple posix repl demo - - I think you'll need to refactor userlib to hide set behind a conditional - based on whether CFG_RELISH_POSIX is set or not - - add a compilation task to CI - Release CI - Rename to Flesh - Make an icon if you feel like it diff --git a/src/bin/relish.rs b/src/bin/relish.rs index b2430e8..73e7aaa 100644 --- a/src/bin/relish.rs +++ b/src/bin/relish.rs @@ -28,7 +28,6 @@ use { CONSOLE_XDIM_VNAME, CONSOLE_YDIM_VNAME, CFG_FILE_VNAME, L_PROMPT_VNAME, R_PROMPT_VNAME, PROMPT_DELIM_VNAME, }, - aux::{ShellState, check_jobs}, }, std::{ cell::RefCell, @@ -46,12 +45,17 @@ use { ColumnarMenu, Emacs, ReedlineMenu, default_emacs_keybindings, }, - nix::unistd, nu_ansi_term::{Color, Style}, dirs::home_dir, termion::terminal_size, }; +#[cfg(feature="posix")] +use relish::aux::{ShellState, check_jobs}; +#[cfg(feature="posix")] +use nix::unistd; + + #[derive(Clone)] pub struct CustomPrompt(String, String, String); #[derive(Clone)] @@ -237,24 +241,16 @@ fn main() { let hist_file_name = home_dir.clone() + HIST_FILE; let cfg_file_name = home_dir + CONFIG_FILE_DEFAULT; - // TODO: the next two decls should probably be conditional on CFG_RELISH_POSIX - // but in both cases the data must live for the whole program - let shell_state_bindings = Rc::new(RefCell::from(ShellState { - parent_pid: unistd::Pid::from_raw(0), - parent_sid: unistd::Pid::from_raw(0), - children: vec![], - last_exit_code: 0, - attr: None, - })); - let prompt_ss = shell_state_bindings.clone(); - // setup symtable let mut syms = SymTable::new(); load_defaults(&mut syms); load_environment(&mut syms); - static_stdlib(&mut syms).unwrap_or_else(|err: String| eprintln!("{}", err)); + static_stdlib(&mut syms); // reload this later with the state bindings - dynamic_stdlib(&mut syms, None).unwrap_or_else(|err: String| eprintln!("{}", err)); + #[cfg(feature="posix")] + dynamic_stdlib(&mut syms, None); + #[cfg(not(feature="posix"))] + dynamic_stdlib(&mut syms); // if there are args those are scripts, run them and exit if env::args().count() > 1 { @@ -274,10 +270,23 @@ fn main() { run(cfg_file.clone(), &mut syms) .unwrap_or_else(|err: Traceback| eprintln!("failed to load script {}\n{}", cfg_file, err)); } - dynamic_stdlib(&mut syms, Some(shell_state_bindings)).unwrap_or_else(|err: String| eprintln!("{}", err)); + + #[cfg(feature="posix")] + let prompt_ss: Rc>; + #[cfg(feature="posix")] + { + let shell_state_bindings = Rc::new(RefCell::from(ShellState { + parent_pid: unistd::Pid::from_raw(0), + parent_sid: unistd::Pid::from_raw(0), + children: vec![], + last_exit_code: 0, + attr: None, + })); + prompt_ss = shell_state_bindings.clone(); + dynamic_stdlib(&mut syms, Some(shell_state_bindings)); + } // setup readline - let completion_menu = Box::new(ColumnarMenu::default().with_name("completion_menu")); let mut keybindings = default_emacs_keybindings(); add_menu_keybindings(&mut keybindings); @@ -305,8 +314,8 @@ fn main() { let mut xdimension: u16 = 0; let mut ydimension: u16 = 0; loop { + #[cfg(feature="posix")] { - // update state check_jobs(&mut prompt_ss.borrow_mut()); } let readline_prompt = make_prompt(&mut syms); diff --git a/src/lib.rs b/src/lib.rs index 46858a4..2a6f2c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,7 +51,10 @@ pub mod stdlib { } pub mod aux { + #[cfg(feature="posix")] pub use crate::stl::posix::args_from_ast; + #[cfg(feature="posix")] pub use crate::stl::posix::ShellState; + #[cfg(feature="posix")] pub use crate::stl::posix::check_jobs; } diff --git a/src/stl.rs b/src/stl.rs index 82ac1d7..b18781c 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -23,7 +23,9 @@ use std::rc::Rc; use std::cell::RefCell; use std::env::vars; +#[cfg(feature = "posix")] pub mod posix; + pub mod append; pub mod boolean; pub mod control; @@ -57,7 +59,7 @@ fn prompt_delimiter_default_callback(_: &Seg, _: &mut SymTable) -> Result Result<(), String> { +pub fn static_stdlib(syms: &mut SymTable) { append::add_list_lib(syms); strings::add_string_lib(syms); decl::add_decl_lib_static(syms); @@ -76,24 +78,21 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> { ..Default::default() } ); - - Ok(()) } /// dynamic_stdlib /// takes configuration data and uses it to insert dynamic /// callbacks with configuration into a symtable -pub fn dynamic_stdlib(syms: &mut SymTable, shell: Option>>) -> Result<(), String> { - //get CFG_RELISH_ENV from syms +#[cfg(feature="posix")] +pub fn dynamic_stdlib(syms: &mut SymTable, shell: Option>>) { + // get CFG_RELISH_ENV from syms let env_cfg_user_form = syms .call_symbol(&MODENV_CFG_VNAME.to_string(), &Seg::new(), true) .unwrap_or_else(|_: Traceback| Box::new(Ctr::None)) .to_string() .eq("true"); - decl::add_decl_lib_dynamic(syms, env_cfg_user_form); - // This should be replaced by actual compiler conditionals in the future if let Some(shell_state) = shell { let posix_cfg_user_form = syms .call_symbol(&POSIX_CFG_VNAME.to_string(), &Seg::new(), true) @@ -105,8 +104,11 @@ pub fn dynamic_stdlib(syms: &mut SymTable, shell: Option