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: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,8 @@ dbg_macro = "deny"
todo = "deny"
# Forbid explicit `panic!` calls; unreachable arms belong in `unreachable!`
panic = "deny"
# Forbid `.expect()`: it aborts the process on an unexpected value instead of
# surfacing a recoverable error. Call sites that print a stack trace by design
# (invariants the caller already checked, intentionally documented panics)
# carry a localized `#[allow]`; everywhere else propagate via `anyhow::Result`.
expect_used = "deny"
5 changes: 3 additions & 2 deletions src/commands/restore.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::Result;
use anyhow::{Context, Result};
use worktree_io::git::{create_worktree, git_worktree_prune};
use worktree_io::ttl::WorkspaceRegistry;

Expand All @@ -12,7 +12,7 @@ use worktree_io::ttl::WorkspaceRegistry;
/// automatically because the original project path is not stored in the
/// registry; the user is asked to run `worktree open <issue-ref>` instead.
pub fn cmd_restore() -> Result<()> {
let home = dirs::home_dir().expect("could not determine home directory");
let home = dirs::home_dir().context("could not determine home directory")?;
let local_prefix = home.join("worktrees").join("local");

let registry = WorkspaceRegistry::load()?;
Expand Down Expand Up @@ -47,6 +47,7 @@ pub fn cmd_restore() -> Result<()> {
};
// If file_name() returned Some, the path is not a root, so parent()
// always returns Some here.
#[allow(clippy::expect_used)]
let bare_path = path.parent().expect("non-root path must have a parent");

if !bare_path.exists() {
Expand Down
6 changes: 3 additions & 3 deletions src/issue/parse/centy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ pub(super) fn find_centy_root(start: &Path) -> Option<PathBuf> {
/// cannot be determined, or no `.centy/` directory is found in the current directory or
/// any of its ancestors.
pub(super) fn parse_centy(s: &str) -> Result<IssueRef> {
let id_str = s
.strip_prefix("centy:")
.expect("caller checked starts_with(\"centy:\")");
let Some(id_str) = s.strip_prefix("centy:") else {
unreachable!("caller checked starts_with(\"centy:\")")
};
let Ok(display_number) = id_str.parse::<u32>() else {
return Err(anyhow::anyhow!(
"Invalid Centy issue number: {id_str:?} — expected a positive integer"
Expand Down
6 changes: 3 additions & 3 deletions src/issue/parse/gh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ pub(super) fn parse_github_remote_url(url: &str) -> Option<(String, String)> {
/// determined, the `origin` remote URL cannot be read, or the URL is not a
/// GitHub remote.
pub(super) fn parse_gh(s: &str) -> Result<IssueRef> {
let num_str = s
.strip_prefix("gh:")
.expect("caller checked starts_with(\"gh:\")");
let Some(num_str) = s.strip_prefix("gh:") else {
unreachable!("caller checked starts_with(\"gh:\")")
};
let Ok(number) = num_str.parse::<u64>() else {
return Err(anyhow::anyhow!(
"Invalid issue number for gh shorthand: {num_str:?} — expected a positive integer"
Expand Down
6 changes: 3 additions & 3 deletions src/issue/parse/gitlab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ pub(super) fn parse_gitlab_url(s: &str) -> Result<IssueRef> {
/// determined, the `origin` remote URL cannot be read, or the URL is not a
/// GitLab remote.
pub(super) fn parse_gl(s: &str) -> Result<IssueRef> {
let num_str = s
.strip_prefix("gl:")
.expect("caller checked starts_with(\"gl:\")");
let Some(num_str) = s.strip_prefix("gl:") else {
unreachable!("caller checked starts_with(\"gl:\")")
};
let Ok(number) = num_str.parse::<u64>() else {
return Err(anyhow::anyhow!(
"Invalid issue number for gl shorthand: {num_str:?} — expected a positive integer"
Expand Down
5 changes: 5 additions & 0 deletions src/issue/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ impl IssueRef {
let base = if temp {
std::env::temp_dir()
} else {
// Documented in `bare_clone_path`'s `# Panics` section: this is a
// narrow, path-building helper with no `Result` to propagate
// into, and a missing home directory is an unrecoverable
// environment problem for every caller.
#[allow(clippy::expect_used)]
dirs::home_dir().expect("could not determine home directory")
}
.join("worktrees");
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
//! `worktree-io` — open GitHub, Linear, and local Centy issues as git worktree workspaces.
// `.expect()` with a descriptive message is the idiomatic way to fail a test
// fast on a broken fixture; only production code paths need to avoid it.
#![cfg_attr(test, allow(clippy::expect_used))]

/// Configuration loading and serialization.
pub mod config;
Expand Down
10 changes: 5 additions & 5 deletions src/multi_workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ pub fn create_multi_workspace(specs: &[MultiSpec], workspaces_root: &Path) -> Re
Ok(root)
}

fn github_bare_path(owner: &str, repo: &str) -> PathBuf {
dirs::home_dir()
.expect("could not determine home directory")
fn github_bare_path(owner: &str, repo: &str) -> Result<PathBuf> {
Ok(dirs::home_dir()
.context("could not determine home directory")?
.join("worktrees")
.join("github")
.join(owner)
.join(repo)
.join(repo))
}

fn open_one(spec: &MultiSpec, root: &Path) -> Result<()> {
Expand Down Expand Up @@ -82,7 +82,7 @@ fn open_one_issue(issue: &IssueRef, root: &Path) -> Result<()> {
}

fn open_one_bare(owner: &str, repo: &str, root: &Path) -> Result<()> {
let bare_path = github_bare_path(owner, repo);
let bare_path = github_bare_path(owner, repo)?;
let url = format!("https://github.com/{owner}/{repo}.git");
if bare_path.exists() {
eprintln!("Fetching origin for {}…", bare_path.display());
Expand Down
3 changes: 3 additions & 0 deletions tests/snapshot_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
//! clean Docker container (see `docker/Dockerfile.test`) eliminates host-state
//! pollution and keeps the snapshots deterministic.
#![allow(missing_docs)]
// Integration test fixtures: `.expect()` with a descriptive message is the
// idiomatic way to fail a test fast on a broken fixture.
#![allow(clippy::expect_used)]

use worktree_io::repo_hooks_scaffold::SCAFFOLD;
use worktree_io::{config::Config, ttl::WorkspaceRegistry};
Expand Down
Loading