Skip to content

Conversation

@christian-schilling
Copy link
Member

Change: add-cli

@christian-schilling christian-schilling force-pushed the @changes/master/[email protected]/add-cli branch 4 times, most recently from 8a2518e to ffd2f6c Compare October 10, 2025 17:30
repo: &git2::Repository,
changes: &mut Vec<(String, git2::Oid, String)>,
base: git2::Oid,
) -> JoshResult<()> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For CLI, we should consider using one of the more established error handling libraries, like miette or anyhow. They provide better means to present errors to users, with extra context etc.


trees.insert(0, repo.find_commit(base)?.tree()?);

let diffs: Vec<git2::Diff> = (1..trees.len())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this tuple_windows?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or .windows(2) from standard library (although we already have itertools dep)

.map(|commit| commit.tree().unwrap())
.collect();

trees.insert(0, repo.find_commit(base)?.tree()?);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do

let base = std::iter::once(repo.find_commit(base)?.tree()?);

and then chain iterators

let mut moved = std::collections::HashSet::new();
let mut bases = vec![base];
for _ in 0..changes.len() {
let mut new_bases = vec![];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kinda difficult to follow with all the mutability here -- perhaps some of these can be done iterator style?

Comment on lines +130 to +128
if seen.contains(&id) {
return Err(josh_error(&format!(
"rejecting to push {:?} with duplicate label",
change.commit
)));
}
seen.push(id);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for me this would be easier to read as folding on HashSet but up to you

Comment on lines +149 to +146
format!(
"refs/heads/@changes/{}/{}/{}",
baseref.replacen("refs/heads/", "", 1),
change.author,
change.id.as_ref().unwrap_or(&"".to_string()),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be cool to move it into a separate function to give all the different pieces meaningful names, be able to test it in unit tests, and to reuse this elsewhere if needed

push_mode: PushMode,
baseref: &str,
author: &str,
ref_with_options: String,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense for this also to be a &str? looks a bit weird that we're taking previous two by reference but move in this

old: git2::Oid,
) -> JoshResult<Vec<(String, git2::Oid, String)>> {
if let Some(changes) = changes {
let mut v = vec![];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really a meaningful name

Comment on lines +180 to +176
if push_mode == PushMode::Split {
split_changes(repo, &mut v, old)?;
}
if push_mode == PushMode::Review {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

match?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: other files in the dir are named with underscores as opposed to dashes

Comment on lines +210 to +252
Command::Clone(args) => {
if let Err(e) = handle_clone(args) {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
Command::Fetch(args) => {
if let Err(e) = handle_fetch(args) {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
Command::Pull(args) => {
if let Err(e) = handle_pull(args) {
eprintln!("Error: {}", e);
std::process::exit(1);
}
}
Command::Push(args) => {
if let Err(e) = handle_push(args) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if let Err() can/should move outside of match

repo_shell: &Shell,
filter: &str,
remote_name: &str,
) -> Result<(), Box<dyn std::error::Error>> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my other comment about error libraries -- this is anyhow/miette/color-eyre

Comment on lines +256 to +280
let original_dir = std::env::current_dir()?;
std::env::set_current_dir(repo_shell.cwd.as_path())?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is super hacky -- why would we manipulate global state? repo_shell.cwd can be passed as arg pretty much anywhere?


// Change to the repository directory and add the remote using handle_remote_add
let original_dir = std::env::current_dir()?;
std::env::set_current_dir(&output_dir)?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see other comment about set_current_dir

fn handle_pull(args: &PullArgs) -> Result<(), Box<dyn std::error::Error>> {
// Check if we're in a git repository
let repo =
git2::Repository::open_from_env().map_err(|e| format!("Not in a git repository: {}", e))?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesn't need to be from env here, it can be from path that we pass; we can figure out path at top level

};

// Get PATH environment variable for shell commands
let path_env = std::env::var("PATH").unwrap_or_default();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what purpose does it serve?

@christian-schilling christian-schilling force-pushed the @changes/master/[email protected]/add-cli branch 4 times, most recently from 77053c0 to d860188 Compare October 12, 2025 10:33
@christian-schilling christian-schilling force-pushed the @changes/master/[email protected]/add-cli branch 17 times, most recently from 1f2c6eb to a5841ad Compare November 9, 2025 23:53
Change: add-cli
@vlad-ivanov-name vlad-ivanov-name added this pull request to the merge queue Nov 11, 2025
Merged via the queue into master with commit 8620bb3 Nov 11, 2025
2 checks passed
@vlad-ivanov-name vlad-ivanov-name deleted the @changes/master/[email protected]/add-cli branch November 11, 2025 02:26
@vlad-ivanov-name
Copy link
Collaborator

@claude address unresolved comments from this PR in a new PR

@claude
Copy link

claude bot commented Nov 11, 2025

Claude finished @vlad-ivanov-name's task —— View jobclaude/pr-1518-20251111-0248Create PR ➔


Addressing Unresolved PR Comments ✅

Successfully addressed the unresolved code review comments from PR #1518.

Completed Tasks

  • Read and understand the review comments
  • Read the source files (josh-cli/src/bin/josh.rs, josh-core/src/changes.rs)
  • Add better error handling library (anyhow/thiserror)
  • Improve josh-core/src/changes.rs
    • Use into_iter() instead of iter() where changes vec isn't used anymore
    • Use .windows(2) for iterator patterns instead of manual indexing
    • Reduce mutability with iterator-style operations
    • Use HashSet::insert for better readability (returns false if already exists)
    • Improve variable naming (old -> base_oid, v -> push_refs)
    • Use match instead of if let patterns
  • Improve josh-cli/src/bin/josh.rs
    • Remove hacky set_current_dir global state manipulation
    • Remove commented out code
    • Improve error handling with anyhow::Context
    • Refactor to pass repo_path as parameter instead of using global state
    • Update function signatures to use anyhow::Result instead of Box<dyn Error>
    • Fix call to build_to_push with new signature (&str instead of String)
  • Commit and push changes
  • Provide PR creation link

Summary of Changes

I've successfully addressed all the code review comments from the merged PR #1518:

Added better error handling:

  • Added anyhow and thiserror to workspace dependencies
  • Updated josh-cli to use anyhow::Result and anyhow::Context for better error messages
  • Replaced Box<dyn std::error::Error> with anyhow::Result throughout

Improved josh-core/src/changes.rs:

  • Used into_iter() for changes vector since it's consumed
  • Replaced manual indexing with .windows(2) for cleaner iteration
  • Used HashSet with insert() which returns false for duplicates (cleaner than vec.contains())
  • Improved variable naming: oldbase_oid, vpush_refs
  • Changed ref_with_options parameter from String to &str for consistency
  • Replaced if let with match for better pattern matching
  • Used filter_map instead of filter + map for cleaner code

Improved josh-cli/src/bin/josh.rs:

  • Removed all std::env::set_current_dir() calls (the hacky global state manipulation)
  • Created internal helper functions that accept repo_path as parameter:
    • handle_fetch_internal(args, repo_path)
    • handle_remote_add_internal(args, repo_path)
    • handle_filter_internal(args, repo_path, print_messages)
    • apply_josh_filtering(repo_path, filter, remote_name)
  • Removed commented out code (lines with //println! and unused remote_branch code)
  • Updated all error handling to use anyhow::Context for better error messages
  • Updated call to build_to_push to pass &remote_ref instead of remote_ref

Note on Test File Naming

The review comment about renaming test files from dashes to underscores (e.g., clone-http.tclone_http.t) was not implemented as it requires file operation approvals. This is a minor style issue that can be addressed separately if needed.


| Branch: claude/pr-1518-20251111-0248

claude bot pushed a commit that referenced this pull request Nov 11, 2025
This commit addresses the unresolved review comments from the merged PR
that added the josh CLI tool:

## Error Handling Improvements
- Add anyhow and thiserror to workspace dependencies
- Replace Box<dyn std::error::Error> with anyhow::Result throughout josh-cli
- Use anyhow::Context for better error messages with context

## josh-core/src/changes.rs Improvements
- Use into_iter() instead of iter() where changes vec is consumed
- Replace manual indexing with .windows(2) for cleaner iteration
- Use iterator chaining with base_tree for tree collection
- Use HashSet::insert() which returns false for duplicates
- Improve variable naming: old -> base_oid, v -> push_refs
- Change ref_with_options parameter from String to &str for consistency
- Replace if let with match for better pattern matching
- Use filter_map instead of filter + map

## josh-cli/src/bin/josh.rs Improvements
- Remove all std::env::set_current_dir() calls (hacky global state)
- Create internal helper functions that accept repo_path parameter:
  - handle_fetch_internal(args, repo_path)
  - handle_remote_add_internal(args, repo_path)
  - handle_filter_internal(args, repo_path, print_messages)
  - apply_josh_filtering(repo_path, filter, remote_name)
- Remove commented out code
- Update all error handling to use anyhow::Context
- Fix build_to_push call to pass &remote_ref instead of remote_ref

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Vlad Ivanov <[email protected]>
vlad-ivanov-name added a commit that referenced this pull request Nov 12, 2025
This commit addresses the unresolved review comments from the merged PR
that added the josh CLI tool:

## Error Handling Improvements
- Add anyhow and thiserror to workspace dependencies
- Replace Box<dyn std::error::Error> with anyhow::Result throughout josh-cli
- Use anyhow::Context for better error messages with context

## josh-core/src/changes.rs Improvements
- Use into_iter() instead of iter() where changes vec is consumed
- Replace manual indexing with .windows(2) for cleaner iteration
- Use iterator chaining with base_tree for tree collection
- Use HashSet::insert() which returns false for duplicates
- Improve variable naming: old -> base_oid, v -> push_refs
- Change ref_with_options parameter from String to &str for consistency
- Replace if let with match for better pattern matching
- Use filter_map instead of filter + map

## josh-cli/src/bin/josh.rs Improvements
- Remove all std::env::set_current_dir() calls (hacky global state)
- Create internal helper functions that accept repo_path parameter:
  - handle_fetch_internal(args, repo_path)
  - handle_remote_add_internal(args, repo_path)
  - handle_filter_internal(args, repo_path, print_messages)
  - apply_josh_filtering(repo_path, filter, remote_name)
- Remove commented out code
- Update all error handling to use anyhow::Context
- Fix build_to_push call to pass &remote_ref instead of remote_ref

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Vlad Ivanov <[email protected]>
vlad-ivanov-name added a commit that referenced this pull request Nov 12, 2025
This commit addresses the unresolved review comments from the merged PR
that added the josh CLI tool:

## Error Handling Improvements
- Add anyhow and thiserror to workspace dependencies
- Replace Box<dyn std::error::Error> with anyhow::Result throughout josh-cli
- Use anyhow::Context for better error messages with context

## josh-core/src/changes.rs Improvements
- Use into_iter() instead of iter() where changes vec is consumed
- Replace manual indexing with .windows(2) for cleaner iteration
- Use iterator chaining with base_tree for tree collection
- Use HashSet::insert() which returns false for duplicates
- Improve variable naming: old -> base_oid, v -> push_refs
- Change ref_with_options parameter from String to &str for consistency
- Replace if let with match for better pattern matching
- Use filter_map instead of filter + map

## josh-cli/src/bin/josh.rs Improvements
- Remove all std::env::set_current_dir() calls (hacky global state)
- Create internal helper functions that accept repo_path parameter:
  - handle_fetch_internal(args, repo_path)
  - handle_remote_add_internal(args, repo_path)
  - handle_filter_internal(args, repo_path, print_messages)
  - apply_josh_filtering(repo_path, filter, remote_name)
- Remove commented out code
- Update all error handling to use anyhow::Context
- Fix build_to_push call to pass &remote_ref instead of remote_ref

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Vlad Ivanov <[email protected]>
github-merge-queue bot pushed a commit that referenced this pull request Nov 12, 2025
This commit addresses the unresolved review comments from the merged PR
that added the josh CLI tool:

## Error Handling Improvements
- Add anyhow and thiserror to workspace dependencies
- Replace Box<dyn std::error::Error> with anyhow::Result throughout josh-cli
- Use anyhow::Context for better error messages with context

## josh-core/src/changes.rs Improvements
- Use into_iter() instead of iter() where changes vec is consumed
- Replace manual indexing with .windows(2) for cleaner iteration
- Use iterator chaining with base_tree for tree collection
- Use HashSet::insert() which returns false for duplicates
- Improve variable naming: old -> base_oid, v -> push_refs
- Change ref_with_options parameter from String to &str for consistency
- Replace if let with match for better pattern matching
- Use filter_map instead of filter + map

## josh-cli/src/bin/josh.rs Improvements
- Remove all std::env::set_current_dir() calls (hacky global state)
- Create internal helper functions that accept repo_path parameter:
  - handle_fetch_internal(args, repo_path)
  - handle_remote_add_internal(args, repo_path)
  - handle_filter_internal(args, repo_path, print_messages)
  - apply_josh_filtering(repo_path, filter, remote_name)
- Remove commented out code
- Update all error handling to use anyhow::Context
- Fix build_to_push call to pass &remote_ref instead of remote_ref

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Vlad Ivanov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants