Workspace lints and disallow unwrap (#855)

Sets submodules to use workspace lints. Added denying unwrap as a
workspace level lint, which found a couple of cases where we could have
propagated errors. Also manually labeled ones that were fine by my eye.
This commit is contained in:
jcoens-openai
2025-05-08 09:46:18 -07:00
committed by GitHub
parent 9fdf2fa066
commit 87cf120873
22 changed files with 95 additions and 8 deletions

View File

@@ -22,6 +22,12 @@ version = "0.0.0"
# edition.
edition = "2024"
[workspace.lints]
rust = { }
[workspace.lints.clippy]
unwrap_used = "deny"
[profile.release]
lto = "fat"
# Because we bundle some of these executables with the TypeScript CLI, we

View File

@@ -7,6 +7,9 @@ edition = "2024"
name = "codex_apply_patch"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
anyhow = "1"
regex = "1.11.1"

View File

@@ -223,7 +223,9 @@ fn extract_heredoc_body_from_apply_patch_command(src: &str) -> anyhow::Result<St
loop {
let node = c.node();
if node.kind() == "heredoc_body" {
let text = node.utf8_text(bytes).unwrap();
let text = node
.utf8_text(bytes)
.with_context(|| "failed to interpret heredoc body as UTF-8")?;
return Ok(text.trim_end_matches('\n').to_owned());
}
@@ -605,6 +607,8 @@ pub fn print_summary(
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]
use super::*;
use pretty_assertions::assert_eq;
use std::fs;

View File

@@ -15,6 +15,9 @@ path = "src/linux-sandbox/main.rs"
name = "codex_cli"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
anyhow = "1"
clap = { version = "4", features = ["derive"] }

View File

@@ -3,6 +3,9 @@ name = "codex-common"
version = { workspace = true }
edition = "2024"
[lints]
workspace = true
[dependencies]
chrono = { version = "0.4.40", optional = true }
clap = { version = "4", features = ["derive", "wrap_help"], optional = true }

View File

@@ -7,6 +7,9 @@ edition = "2024"
name = "codex_core"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
anyhow = "1"
async-channel = "2.3.1"

View File

@@ -1,3 +1,6 @@
// Poisoned mutex should fail the program
#![allow(clippy::unwrap_used)]
use std::collections::HashMap;
use std::collections::HashSet;
use std::path::Path;

View File

@@ -351,5 +351,6 @@ fn synthetic_exit_status(code: i32) -> ExitStatus {
#[cfg(windows)]
fn synthetic_exit_status(code: i32) -> ExitStatus {
use std::os::windows::process::ExitStatusExt;
#[expect(clippy::unwrap_used)]
std::process::ExitStatus::from_raw(code.try_into().unwrap())
}

View File

@@ -166,7 +166,9 @@ fn create_log_file() -> std::io::Result<LogFileInfo> {
// Custom format for YYYY-MM-DD.
let format: &[FormatItem] = format_description!("[year]-[month]-[day]");
let date_str = timestamp.format(format).unwrap();
let date_str = timestamp
.format(format)
.map_err(|e| IoError::new(ErrorKind::Other, format!("failed to format timestamp: {e}")))?;
let filename = format!("rollout-{date_str}-{session_id}.jsonl");

View File

@@ -11,6 +11,9 @@ path = "src/main.rs"
name = "codex_exec"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
anyhow = "1"
chrono = "0.4.40"

View File

@@ -78,10 +78,12 @@ pub async fn run_main(cli: Cli) -> anyhow::Result<()> {
// TODO(mbolin): Take a more thoughtful approach to logging.
let default_level = "error";
let _ = tracing_subscriber::fmt()
// Fallback to the `default_level` log filter if the environment
// variable is not set _or_ contains an invalid value
.with_env_filter(
EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new(default_level))
.unwrap(),
.unwrap_or_else(|_| EnvFilter::new(default_level)),
)
.with_ansi(stderr_with_ansi)
.with_writer(std::io::stderr)

View File

@@ -11,6 +11,9 @@ path = "src/main.rs"
name = "codex_execpolicy"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
anyhow = "1"
starlark = "0.13.0"

View File

@@ -45,7 +45,12 @@ pub fn resolve_observed_args_with_patterns(
let prefix = get_range_checked(&args, 0..num_prefix_args)?;
let mut prefix_arg_index = 0;
for pattern in prefix_patterns {
let n = pattern.cardinality().is_exact().unwrap();
let n = pattern
.cardinality()
.is_exact()
.ok_or(Error::InternalInvariantViolation {
message: "expected exact cardinality".to_string(),
})?;
for positional_arg in &prefix[prefix_arg_index..prefix_arg_index + n] {
let matched_arg = MatchedArg::new(
positional_arg.index,
@@ -111,7 +116,12 @@ pub fn resolve_observed_args_with_patterns(
let suffix = get_range_checked(&args, initial_suffix_args_index..args.len())?;
let mut suffix_arg_index = 0;
for pattern in suffix_patterns {
let n = pattern.cardinality().is_exact().unwrap();
let n = pattern
.cardinality()
.is_exact()
.ok_or(Error::InternalInvariantViolation {
message: "expected exact cardinality".to_string(),
})?;
for positional_arg in &suffix[suffix_arg_index..suffix_arg_index + n] {
let matched_arg = MatchedArg::new(
positional_arg.index,

View File

@@ -168,6 +168,8 @@ fn policy_builtins(builder: &mut GlobalsBuilder) {
.map(|v| v.items.to_vec())
.collect(),
);
#[expect(clippy::unwrap_used)]
let policy_builder = eval
.extra
.as_ref()
@@ -182,6 +184,7 @@ fn policy_builtins(builder: &mut GlobalsBuilder) {
strings: UnpackList<String>,
eval: &mut Evaluator,
) -> anyhow::Result<NoneType> {
#[expect(clippy::unwrap_used)]
let policy_builder = eval
.extra
.as_ref()
@@ -197,6 +200,7 @@ fn policy_builtins(builder: &mut GlobalsBuilder) {
reason: String,
eval: &mut Evaluator,
) -> anyhow::Result<NoneType> {
#[expect(clippy::unwrap_used)]
let policy_builder = eval
.extra
.as_ref()

View File

@@ -3,6 +3,9 @@ name = "codex-mcp-client"
version = { workspace = true }
edition = "2024"
[lints]
workspace = true
[dependencies]
anyhow = "1"
mcp-types = { path = "../mcp-types" }

View File

@@ -3,6 +3,9 @@ name = "codex-mcp-server"
version = { workspace = true }
edition = "2024"
[lints]
workspace = true
[dependencies]
codex-core = { path = "../core" }
mcp-types = { path = "../mcp-types" }

View File

@@ -227,6 +227,8 @@ impl MessageProcessor {
where
T: ModelContextProtocolRequest,
{
// result has `Serialized` instance so should never fail
#[expect(clippy::unwrap_used)]
let response = JSONRPCMessage::Response(JSONRPCResponse {
jsonrpc: JSONRPC_VERSION.into(),
id,

View File

@@ -3,6 +3,9 @@ name = "mcp-types"
version = { workspace = true }
edition = "2024"
[lints]
workspace = true
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"

View File

@@ -102,6 +102,8 @@ pub enum CallToolResultContent {
impl From<CallToolResult> for serde_json::Value {
fn from(value: CallToolResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -240,6 +242,8 @@ pub struct CompleteResultCompletion {
impl From<CompleteResult> for serde_json::Value {
fn from(value: CompleteResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -312,6 +316,8 @@ pub enum CreateMessageResultContent {
impl From<CreateMessageResult> for serde_json::Value {
fn from(value: CreateMessageResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -366,6 +372,8 @@ pub struct GetPromptResult {
impl From<GetPromptResult> for serde_json::Value {
fn from(value: GetPromptResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -420,6 +428,8 @@ pub struct InitializeResult {
impl From<InitializeResult> for serde_json::Value {
fn from(value: InitializeResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -538,6 +548,8 @@ pub struct ListPromptsResult {
impl From<ListPromptsResult> for serde_json::Value {
fn from(value: ListPromptsResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -572,6 +584,8 @@ pub struct ListResourceTemplatesResult {
impl From<ListResourceTemplatesResult> for serde_json::Value {
fn from(value: ListResourceTemplatesResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -605,6 +619,8 @@ pub struct ListResourcesResult {
impl From<ListResourcesResult> for serde_json::Value {
fn from(value: ListResourcesResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -628,6 +644,8 @@ pub struct ListRootsResult {
impl From<ListRootsResult> for serde_json::Value {
fn from(value: ListRootsResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -661,6 +679,8 @@ pub struct ListToolsResult {
impl From<ListToolsResult> for serde_json::Value {
fn from(value: ListToolsResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -782,6 +802,8 @@ pub struct PaginatedResult {
impl From<PaginatedResult> for serde_json::Value {
fn from(value: PaginatedResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}
@@ -904,6 +926,8 @@ pub enum ReadResourceResultContents {
impl From<ReadResourceResult> for serde_json::Value {
fn from(value: ReadResourceResult) -> Self {
// Leave this as it should never fail
#[expect(clippy::unwrap_used)]
serde_json::to_value(value).unwrap()
}
}

View File

@@ -11,6 +11,9 @@ path = "src/main.rs"
name = "codex_tui"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
anyhow = "1"
clap = { version = "4", features = ["derive"] }

View File

@@ -107,7 +107,7 @@ impl App<'_> {
pub(crate) fn run(&mut self, terminal: &mut tui::Tui) -> Result<()> {
// Insert an event to trigger the first render.
let app_event_tx = self.app_event_tx.clone();
app_event_tx.send(AppEvent::Redraw).unwrap();
app_event_tx.send(AppEvent::Redraw)?;
while let Ok(event) = self.app_event_rx.recv() {
match event {
@@ -128,7 +128,7 @@ impl App<'_> {
modifiers: crossterm::event::KeyModifiers::CONTROL,
..
} => {
self.app_event_tx.send(AppEvent::ExitRequest).unwrap();
self.app_event_tx.send(AppEvent::ExitRequest)?;
}
_ => {
self.dispatch_key_event(key_event);

View File

@@ -2,7 +2,6 @@
// The standalone `codex-tui` binary prints a short help message before the
// alternatescreen mode starts; that file optsout locally via `allow`.
#![deny(clippy::print_stdout, clippy::print_stderr)]
use app::App;
use codex_core::config::Config;
use codex_core::config::ConfigOverrides;