@@ -45,6 +45,14 @@ pub struct BuildStatus {
4545 pub in_queue : bool ,
4646}
4747
48+ #[ doc( hidden) ]
49+ pub struct BranchOptionsInput < ' a > {
50+ pub branches : & ' a [ String ] ,
51+ pub default_branch : Option < & ' a str > ,
52+ pub current_branch : Option < & ' a str > ,
53+ pub manual_input : & ' a str ,
54+ }
55+
4856/// Represents a Jenkins client.
4957pub struct JenkinsClient {
5058 pub base_url : String ,
@@ -672,6 +680,34 @@ impl JenkinsClient {
672680 Ok ( parameters)
673681 }
674682
683+ /// Build branch picker options for GIT_BRANCH-like parameters.
684+ ///
685+ /// Order priority is:
686+ /// 1) manual input
687+ /// 2) default branch
688+ /// 3) current local branch
689+ /// 4) remaining remote branches
690+ ///
691+ /// Remove duplicate branch names while preserving first-seen order in the prioritized list.
692+ #[ doc( hidden) ]
693+ pub fn build_branch_options ( input : BranchOptionsInput < ' _ > ) -> Vec < String > {
694+ let mut options = Vec :: new ( ) ;
695+ options. push ( input. manual_input . to_string ( ) ) ;
696+ if let Some ( default_branch) = input. default_branch . filter ( |value| !value. is_empty ( ) ) {
697+ options. push ( default_branch. to_string ( ) ) ;
698+ }
699+ if let Some ( current_branch) = input. current_branch . filter ( |value| !value. is_empty ( ) ) {
700+ options. push ( current_branch. to_string ( ) ) ;
701+ }
702+ options. extend ( input. branches . iter ( ) . cloned ( ) ) ;
703+
704+ let mut seen = HashSet :: new ( ) ;
705+ options
706+ . into_iter ( )
707+ . filter ( |branch| seen. insert ( branch. clone ( ) ) )
708+ . collect ( )
709+ }
710+
675711 /// Prompts the user to enter values for the given parameter definitions.
676712 ///
677713 /// # Arguments
@@ -687,7 +723,7 @@ impl JenkinsClient {
687723 use dialoguer:: theme:: ColorfulTheme ; // ColorfulTheme/SimpleTheme
688724 use std:: io:: { self , Write } ;
689725 let mut parameters = HashMap :: new ( ) ;
690- let mut branches = get_git_branches ( ) ;
726+ let branches = get_git_branches ( ) ;
691727 let branch_names = [ "GIT_BRANCH" , "gitBranch" ] ;
692728
693729 // for string, text, password
@@ -852,30 +888,21 @@ impl JenkinsClient {
852888 . iter ( )
853889 . any ( |& b| name. to_lowercase ( ) . contains ( & b. to_lowercase ( ) ) )
854890 {
855- // branches.retain(|branch| branch != &default_value); // Remove branch
856891 // If the parameter name contains GIT_BRANCH
857892 let current_branch = get_current_branch ( ) ;
858- // Add `manual input` option at the front
859893 let manual_input = t ! ( "manual-input" ) ;
860- branches. insert ( 0 , manual_input. clone ( ) ) ;
861- // Move current_branch to the front
862- if let Some ( pos) = branches. iter ( ) . position ( |b| b == & current_branch) {
863- branches. remove ( pos) ;
864- branches. insert ( 1 , current_branch. clone ( ) ) ;
865- }
866- // Move default branch to the front
867- if !default_value. is_empty ( ) {
868- if let Some ( pos) = branches. iter ( ) . position ( |b| b == & default_value) {
869- branches. remove ( pos) ;
870- }
871- branches. insert ( 1 , default_value. clone ( ) ) ;
872- }
894+ let branch_options = Self :: build_branch_options ( BranchOptionsInput {
895+ branches : & branches,
896+ default_branch : Some ( & default_value) ,
897+ current_branch : Some ( & current_branch) ,
898+ manual_input : & manual_input,
899+ } ) ;
873900
874901 // Priority: default_value, then current_branch, finally use 0
875- let default_selection = branches
902+ let default_selection = branch_options
876903 . iter ( )
877904 . position ( |b| b == & default_value)
878- . or_else ( || branches . iter ( ) . position ( |b| b == & current_branch) )
905+ . or_else ( || branch_options . iter ( ) . position ( |b| b == & current_branch) )
879906 . unwrap_or ( 0 ) ;
880907 let custom_theme = ColorfulTheme {
881908 // active_item_style: console::Style::new(), // Cancel default style
@@ -888,21 +915,21 @@ impl JenkinsClient {
888915 t!( "prompt-select-branch" , "name" => & fmt_name) ,
889916 fmt_desc
890917 ) )
891- . items ( & branches )
918+ . items ( & branch_options )
892919 . default ( default_selection)
893920 . vim_mode ( true ) // Esc, j|k
894921 . with_initial_text ( "" )
895922 . interact ( )
896923 } ) ) ;
897924
898925 match selected_idx {
899- Some ( idx) if branches [ idx] == manual_input => {
926+ Some ( idx) if branch_options [ idx] == manual_input => {
900927 match prompt_user_input ( & fmt_name, & fmt_desc, "" , trim) {
901928 Some ( v) => ( v, ParamType :: String ) ,
902929 None => return None , // Ctrl+C in manual input
903930 }
904931 }
905- Some ( idx) => ( branches [ idx] . clone ( ) , ParamType :: String ) ,
932+ Some ( idx) => ( branch_options [ idx] . clone ( ) , ParamType :: String ) ,
906933 None => return None , // Ctrl+C pressed - go back
907934 }
908935 } else {
0 commit comments