## Why
`codex-rs/core/src/lib.rs` re-exported a broad set of types and modules
from `codex-protocol` and `codex-shell-command`. That made it easy for
workspace crates to import those APIs through `codex-core`, which in
turn hides dependency edges and makes it harder to reduce compile-time
coupling over time.
This change removes those public re-exports so call sites must import
from the source crates directly. Even when a crate still depends on
`codex-core` today, this makes dependency boundaries explicit and
unblocks future work to drop `codex-core` dependencies where possible.
## What Changed
- Removed public re-exports from `codex-rs/core/src/lib.rs` for:
- `codex_protocol::protocol` and related protocol/model types (including
`InitialHistory`)
- `codex_protocol::config_types` (`protocol_config_types`)
- `codex_shell_command::{bash, is_dangerous_command, is_safe_command,
parse_command, powershell}`
- Migrated workspace Rust call sites to import directly from:
- `codex_protocol::protocol`
- `codex_protocol::config_types`
- `codex_protocol::models`
- `codex_shell_command`
- Added explicit `Cargo.toml` dependencies (`codex-protocol` /
`codex-shell-command`) in crates that now import those crates directly.
- Kept `codex-core` internal modules compiling by using `pub(crate)`
aliases in `core/src/lib.rs` (internal-only, not part of the public
API).
- Updated the two utility crates that can already drop a `codex-core`
dependency edge entirely:
- `codex-utils-approval-presets`
- `codex-utils-cli`
## Verification
- `cargo test -p codex-utils-approval-presets`
- `cargo test -p codex-utils-cli`
- `cargo check --workspace --all-targets`
- `just clippy`
70 lines
2.2 KiB
Rust
70 lines
2.2 KiB
Rust
use std::path::Path;
|
||
use std::path::PathBuf;
|
||
|
||
use codex_shell_command::parse_command::extract_shell_command;
|
||
use dirs::home_dir;
|
||
use shlex::try_join;
|
||
|
||
pub(crate) fn escape_command(command: &[String]) -> String {
|
||
try_join(command.iter().map(String::as_str)).unwrap_or_else(|_| command.join(" "))
|
||
}
|
||
|
||
pub(crate) fn strip_bash_lc_and_escape(command: &[String]) -> String {
|
||
if let Some((_, script)) = extract_shell_command(command) {
|
||
return script.to_string();
|
||
}
|
||
escape_command(command)
|
||
}
|
||
|
||
/// If `path` is absolute and inside $HOME, return the part *after* the home
|
||
/// directory; otherwise, return the path as-is. Note if `path` is the homedir,
|
||
/// this will return and empty path.
|
||
pub(crate) fn relativize_to_home<P>(path: P) -> Option<PathBuf>
|
||
where
|
||
P: AsRef<Path>,
|
||
{
|
||
let path = path.as_ref();
|
||
if !path.is_absolute() {
|
||
// If the path is not absolute, we can’t do anything with it.
|
||
return None;
|
||
}
|
||
|
||
let home_dir = home_dir()?;
|
||
let rel = path.strip_prefix(&home_dir).ok()?;
|
||
Some(rel.to_path_buf())
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_escape_command() {
|
||
let args = vec!["foo".into(), "bar baz".into(), "weird&stuff".into()];
|
||
let cmdline = escape_command(&args);
|
||
assert_eq!(cmdline, "foo 'bar baz' 'weird&stuff'");
|
||
}
|
||
|
||
#[test]
|
||
fn test_strip_bash_lc_and_escape() {
|
||
// Test bash
|
||
let args = vec!["bash".into(), "-lc".into(), "echo hello".into()];
|
||
let cmdline = strip_bash_lc_and_escape(&args);
|
||
assert_eq!(cmdline, "echo hello");
|
||
|
||
// Test zsh
|
||
let args = vec!["zsh".into(), "-lc".into(), "echo hello".into()];
|
||
let cmdline = strip_bash_lc_and_escape(&args);
|
||
assert_eq!(cmdline, "echo hello");
|
||
|
||
// Test absolute path to zsh
|
||
let args = vec!["/usr/bin/zsh".into(), "-lc".into(), "echo hello".into()];
|
||
let cmdline = strip_bash_lc_and_escape(&args);
|
||
assert_eq!(cmdline, "echo hello");
|
||
|
||
// Test absolute path to bash
|
||
let args = vec!["/bin/bash".into(), "-lc".into(), "echo hello".into()];
|
||
let cmdline = strip_bash_lc_and_escape(&args);
|
||
assert_eq!(cmdline, "echo hello");
|
||
}
|
||
}
|