Skip to content

Commit a9eda34

Browse files
committed
refactor(cd/wt): move path check logic to command level
Move fzf selection and clipboard logic from shared helper to cd/wt commands. This makes the flow clearer and implementation consistent across all three versions. Flow: - Path provided → call _open_shell/openShellInDir (opens shell) - No path → use fzf selection, then copy to clipboard Justfile.cross: - _open_shell now only opens shell (path required) - cd/wt commands handle path check and fzf/clipboard logic - 3 lines in _open_shell, clear logic in cd/wt Go (src-go/main.go): - openShellInDir helper (path required, opens shell) - cdCmd/wtCmd handle path check and fzf/clipboard logic - Same structure as Justfile Rust (src-rust/src/main.rs): - open_shell_in_dir helper (path required, opens shell) - Commands::Cd/Wt handle path check and fzf/clipboard logic - Same structure as Justfile and Go All three implementations now have identical logic flow.
1 parent cad6256 commit a9eda34

File tree

3 files changed

+187
-153
lines changed

3 files changed

+187
-153
lines changed

Justfile.cross

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -771,36 +771,47 @@ _copy_to_clipboard text:
771771
exit 1
772772
fi
773773

774-
# Internal: Open shell or copy path (shared logic for cd/wt)
774+
# Internal: Open shell in target directory
775775
# target: "local_path" or "worktree"
776+
# path: must be provided (non-empty)
776777
[no-cd]
777-
_open_shell target path="":
778+
_open_shell target path:
778779
#!/usr/bin/env fish
779-
# If no path provided, use fzf to select
780-
set -l selected_path "{{path}}"
781-
if test -z "$selected_path"
782-
set selected_path (just cross list | tail -n +3 | fzf --height 40% 2>/dev/null | awk '{print $NF}')
783-
test -z "$selected_path" && exit 0
784-
end
785-
# Resolve context and determine target directory
786-
just cross _resolve_context2 "$selected_path" | source || exit 1
780+
just cross _resolve_context2 "{{path}}" | source || exit 1
787781
set -l dir (test "{{target}}" = "local_path" && echo $local_path || echo $worktree)
788-
# Open shell if path was provided, else copy to clipboard (fzf case)
789-
test -n "{{path}}" && cd {{REPO_DIR}}/$dir && exec $SHELL || just cross _copy_to_clipboard {{REPO_DIR}}/$dir && just cross _log success "Path copied: $dir"
782+
cd {{REPO_DIR}}/$dir && exec $SHELL
790783

791784
# Go to worktree directory (for working with git history)
792785
# With path: opens subshell
793786
# Without path: uses fzf selection and copies to clipboard
794787
[no-cd]
795788
wt path="":
796-
just cross _open_shell worktree "{{path}}"
789+
#!/usr/bin/env fish
790+
if test -n "{{path}}"
791+
just cross _open_shell worktree "{{path}}"
792+
else
793+
set -l selected (just cross list | tail -n +3 | fzf --height 40% 2>/dev/null | awk '{print $NF}')
794+
test -z "$selected" && exit 0
795+
just cross _resolve_context2 "$selected" | source || exit 1
796+
just cross _copy_to_clipboard {{REPO_DIR}}/$worktree
797+
just cross _log success "Path copied: $worktree"
798+
end
797799

798800
# Go to local_path directory (for editing patched files)
799801
# With path: opens subshell
800802
# Without path: uses fzf selection and copies to clipboard
801803
[no-cd]
802804
cd path="":
803-
just cross _open_shell local_path "{{path}}"
805+
#!/usr/bin/env fish
806+
if test -n "{{path}}"
807+
just cross _open_shell local_path "{{path}}"
808+
else
809+
set -l selected (just cross list | tail -n +3 | fzf --height 40% 2>/dev/null | awk '{print $NF}')
810+
test -z "$selected" && exit 0
811+
just cross _resolve_context2 "$selected" | source || exit 1
812+
just cross _copy_to_clipboard {{REPO_DIR}}/$local_path
813+
just cross _log success "Path copied: $local_path"
814+
end
804815

805816

806817
# AICONTEXT: "status" shows status of current local_path patch vs. WT, and WT upstream. Input argument is local_path (or understand user stand in the under git-cross'ed local_path and call this comand). It shall be called to get status of local_path from "list" command. Either the status of remote WT upstream (as resource consuming, shall be optional or only ocasional)

src-go/main.go

Lines changed: 92 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -700,106 +700,59 @@ func main() {
700700
return cmd.Run()
701701
}
702702

703-
// Shared helper function for cd/wt commands
704-
// If args provided: open subshell in target directory
705-
// If no args (fzf): copy selected path to clipboard
706-
openShellInPatch := func(args []string, targetType string) error {
703+
// Helper: Open shell in target directory (path must be provided)
704+
openShellInDir := func(path string, targetType string) error {
707705
meta, _ := loadMetadata()
708706
if len(meta.Patches) == 0 {
709707
fmt.Println("No patches configured.")
710708
return nil
711709
}
712710

713-
var patch *Patch
714-
pathProvided := len(args) > 0 // Track if user provided explicit path
715-
716-
if pathProvided {
717-
// User provided explicit path
718-
path := strings.TrimSpace(args[0])
719-
patch = findPatchForPath(meta, path)
720-
if patch == nil {
721-
for i := range meta.Patches {
722-
if meta.Patches[i].LocalPath == path {
723-
patch = &meta.Patches[i]
724-
break
725-
}
726-
}
727-
}
728-
if patch == nil {
729-
return fmt.Errorf("patch not found for path: %s", path)
730-
}
731-
} else {
732-
// No path provided - use fzf selection
733-
selected, err := selectPatchInteractive(&meta)
734-
if err != nil {
735-
targetName := "local_path"
736-
if targetType == "worktree" {
737-
targetName = "worktree"
738-
}
739-
logInfo(fmt.Sprintf("fzf not available. Showing patch list; rerun with a path to enter %s.", targetName))
740-
table := tablewriter.NewWriter(os.Stdout)
741-
table.Header("REMOTE", "REMOTE PATH", "LOCAL PATH")
742-
for _, p := range meta.Patches {
743-
table.Append(p.Remote, p.RemotePath, p.LocalPath)
711+
// Find patch for provided path
712+
patch := findPatchForPath(meta, path)
713+
if patch == nil {
714+
for i := range meta.Patches {
715+
if meta.Patches[i].LocalPath == path {
716+
patch = &meta.Patches[i]
717+
break
744718
}
745-
table.Render()
746-
return nil
747719
}
748-
if selected == nil {
749-
logInfo("No selection made.")
750-
return nil
751-
}
752-
patch = selected
753720
}
754-
755721
if patch == nil {
756-
return nil
722+
return fmt.Errorf("patch not found for path: %s", path)
757723
}
758724

759-
// Determine target directory based on type
725+
// Determine target directory
760726
var targetDir string
761-
var targetName string
762727
if targetType == "worktree" {
763728
targetDir = patch.Worktree
764-
targetName = "worktree"
765729
} else {
766730
targetDir = patch.LocalPath
767-
targetName = "local_path"
768731
}
769732

770733
if _, err := os.Stat(targetDir); os.IsNotExist(err) {
771-
return fmt.Errorf("%s not found: %s", targetName, targetDir)
734+
return fmt.Errorf("%s not found: %s", targetType, targetDir)
772735
}
773736

774-
// Apply logic based on whether path was provided
775-
if pathProvided {
776-
// Path provided: open subshell
777-
shell := os.Getenv("SHELL")
778-
if shell == "" {
779-
shell = "/bin/sh"
780-
}
781-
782-
if dry != "" {
783-
fmt.Printf("%s cd %s\n", dry, targetDir)
784-
fmt.Printf("%s exec %s\n", dry, shell)
785-
return nil
786-
}
737+
// Open subshell
738+
shell := os.Getenv("SHELL")
739+
if shell == "" {
740+
shell = "/bin/sh"
741+
}
787742

788-
logInfo(fmt.Sprintf("Opening shell in %s", targetDir))
789-
c := exec.Command(shell)
790-
c.Dir = targetDir
791-
c.Stdin = os.Stdin
792-
c.Stdout = os.Stdout
793-
c.Stderr = os.Stderr
794-
return c.Run()
795-
} else {
796-
// No path (fzf selection): copy to clipboard
797-
if err := copyToClipboard(targetDir); err != nil {
798-
return fmt.Errorf("failed to copy to clipboard: %v", err)
799-
}
800-
logSuccess(fmt.Sprintf("Path copied to clipboard: %s", targetDir))
743+
if dry != "" {
744+
fmt.Printf("%s cd %s\n", dry, targetDir)
745+
fmt.Printf("%s exec %s\n", dry, shell)
801746
return nil
802747
}
748+
749+
logInfo(fmt.Sprintf("Opening shell in %s", targetDir))
750+
c := exec.Command(shell)
751+
c.Dir = targetDir
752+
c.Stdin = os.Stdin
753+
c.Stdout = os.Stdout
754+
c.Stderr = os.Stderr
755+
return c.Run()
803756
}
804757

805758
cdCmd := &cobra.Command{
@@ -810,7 +763,38 @@ func main() {
810763
With path: opens subshell in the specified local_path directory.
811764
Without path: uses fzf to select a patch, then copies the path to clipboard.`,
812765
RunE: func(cmd *cobra.Command, args []string) error {
813-
return openShellInPatch(args, "local_path")
766+
meta, _ := loadMetadata()
767+
if len(meta.Patches) == 0 {
768+
fmt.Println("No patches configured.")
769+
return nil
770+
}
771+
772+
if len(args) > 0 {
773+
// Path provided: open shell
774+
return openShellInDir(strings.TrimSpace(args[0]), "local_path")
775+
} else {
776+
// No path: use fzf and copy to clipboard
777+
selected, err := selectPatchInteractive(&meta)
778+
if err != nil {
779+
logInfo("fzf not available. Showing patch list; rerun with a path.")
780+
table := tablewriter.NewWriter(os.Stdout)
781+
table.Header("REMOTE", "REMOTE PATH", "LOCAL PATH")
782+
for _, p := range meta.Patches {
783+
table.Append(p.Remote, p.RemotePath, p.LocalPath)
784+
}
785+
table.Render()
786+
return nil
787+
}
788+
if selected == nil {
789+
logInfo("No selection made.")
790+
return nil
791+
}
792+
if err := copyToClipboard(selected.LocalPath); err != nil {
793+
return fmt.Errorf("failed to copy to clipboard: %v", err)
794+
}
795+
logSuccess(fmt.Sprintf("Path copied to clipboard: %s", selected.LocalPath))
796+
return nil
797+
}
814798
},
815799
}
816800

@@ -822,7 +806,38 @@ Without path: uses fzf to select a patch, then copies the path to clipboard.`,
822806
With path: opens subshell in the specified worktree directory.
823807
Without path: uses fzf to select a patch, then copies the path to clipboard.`,
824808
RunE: func(cmd *cobra.Command, args []string) error {
825-
return openShellInPatch(args, "worktree")
809+
meta, _ := loadMetadata()
810+
if len(meta.Patches) == 0 {
811+
fmt.Println("No patches configured.")
812+
return nil
813+
}
814+
815+
if len(args) > 0 {
816+
// Path provided: open shell
817+
return openShellInDir(strings.TrimSpace(args[0]), "worktree")
818+
} else {
819+
// No path: use fzf and copy to clipboard
820+
selected, err := selectPatchInteractive(&meta)
821+
if err != nil {
822+
logInfo("fzf not available. Showing patch list; rerun with a path.")
823+
table := tablewriter.NewWriter(os.Stdout)
824+
table.Header("REMOTE", "REMOTE PATH", "LOCAL PATH")
825+
for _, p := range meta.Patches {
826+
table.Append(p.Remote, p.RemotePath, p.LocalPath)
827+
}
828+
table.Render()
829+
return nil
830+
}
831+
if selected == nil {
832+
logInfo("No selection made.")
833+
return nil
834+
}
835+
if err := copyToClipboard(selected.Worktree); err != nil {
836+
return fmt.Errorf("failed to copy to clipboard: %v", err)
837+
}
838+
logSuccess(fmt.Sprintf("Path copied to clipboard: %s", selected.Worktree))
839+
return nil
840+
}
826841
},
827842
}
828843

0 commit comments

Comments
 (0)