1717import java .util .stream .Collectors ;
1818import org .codejive .jpm .util .SyncStats ;
1919import org .codejive .jpm .util .Version ;
20+ import org .jline .consoleui .elements .InputValue ;
21+ import org .jline .consoleui .elements .ListChoice ;
22+ import org .jline .consoleui .elements .PageSizeType ;
23+ import org .jline .consoleui .elements .PromptableElementIF ;
24+ import org .jline .consoleui .elements .items .ListItemIF ;
25+ import org .jline .consoleui .elements .items .impl .ListItem ;
2026import org .jline .consoleui .prompt .ConsolePrompt ;
2127import org .jline .consoleui .prompt .ListResult ;
2228import org .jline .consoleui .prompt .PromptResultItemIF ;
23- import org .jline .consoleui .prompt .builder .ListPromptBuilder ;
2429import org .jline .consoleui .prompt .builder .PromptBuilder ;
2530import org .jline .terminal .Terminal ;
2631import org .jline .terminal .TerminalBuilder ;
@@ -81,7 +86,10 @@ public Integer call() throws Exception {
8186 name = "search" ,
8287 aliases = {"s" },
8388 description =
84- "Finds and returns the names of those artifacts that match the given (partial) name.\n \n "
89+ "Without arguments this command will start an interactive search asking the user to "
90+ + "provide details of the artifact to look for and the actions to take. When provided "
91+ + "with an argument this command finds and returns the names of those artifacts that "
92+ + "match the given (partial) name.\n \n "
8593 + "Example:\n jpm search httpclient\n " )
8694 static class Search implements Callable <Integer > {
8795 @ Mixin QuietMixin quietMixin ;
@@ -112,16 +120,13 @@ public Integer call() throws Exception {
112120 }
113121 try (Terminal terminal = TerminalBuilder .builder ().build ()) {
114122 while (true ) {
115- ConsolePrompt prompt = new ConsolePrompt (terminal );
116- if (artifactPattern == null || artifactPattern .isEmpty ()) {
117- artifactPattern = askString (prompt , "Search for:" );
123+ ConsolePrompt .UiConfig cfg = new ConsolePrompt .UiConfig ();
124+ cfg .setCancellableFirstPrompt (true );
125+ ConsolePrompt prompt = new ConsolePrompt (null , terminal , cfg );
126+ Map <String , PromptResultItemIF > result = prompt .prompt (this ::nextQuestion );
127+ if (result .isEmpty ()) {
128+ break ;
118129 }
119- String [] artifactNames = search (artifactPattern );
120- PromptBuilder promptBuilder = prompt .getPromptBuilder ();
121- addSelectItem (promptBuilder , "Select artifact:" , artifactNames );
122- addSelectArtifactAction (promptBuilder );
123- Map <String , PromptResultItemIF > result =
124- prompt .prompt (promptBuilder .build ());
125130 String selectedArtifact = getSelectedId (result , "item" );
126131 String artifactAction = getSelectedId (result , "action" );
127132 if ("install" .equals (artifactAction )) {
@@ -144,9 +149,6 @@ public Integer call() throws Exception {
144149 if (!quietMixin .quiet ) {
145150 printStats (stats );
146151 }
147- } else if ("version" .equals (artifactAction )) {
148- artifactPattern = selectedArtifact ;
149- continue ;
150152 } else { // quit
151153 break ;
152154 }
@@ -169,57 +171,73 @@ public Integer call() throws Exception {
169171 return (Integer ) 0 ;
170172 }
171173
172- String [] search (String artifactPattern ) throws IOException {
173- return Jpm .builder ()
174- .directory (copyMixin .directory )
175- .noLinks (copyMixin .noLinks )
176- .build ()
177- .search (artifactPattern , Math .min (max , 200 ));
174+ String [] search (String artifactPattern ) {
175+ try {
176+ return Jpm .builder ()
177+ .directory (copyMixin .directory )
178+ .noLinks (copyMixin .noLinks )
179+ .build ()
180+ .search (artifactPattern , Math .min (max , 200 ));
181+ } catch (IOException e ) {
182+ throw new UncheckedIOException (e );
183+ }
178184 }
179185
180- String askString (ConsolePrompt prompt , String message ) throws IOException {
181- PromptBuilder promptBuilder = prompt .getPromptBuilder ();
182- promptBuilder .createInputPrompt ().name ("input" ).message (message ).addPrompt ();
183- Map <String , PromptResultItemIF > result = prompt .prompt (promptBuilder .build ());
184- return result .get ("input" ).getResult ();
185- }
186+ List <PromptableElementIF > nextQuestion (Map <String , PromptResultItemIF > results ) {
187+ String pattern ;
188+ if (artifactPattern == null || artifactPattern .isEmpty ()) {
189+ if (!results .containsKey ("input" )) {
190+ return List .of (stringElement ("Search for:" ));
191+ }
192+ pattern = results .get ("input" ).getResult ();
193+ } else {
194+ pattern = artifactPattern ;
195+ }
196+
197+ if (!results .containsKey ("item" )) {
198+ String [] artifactNames = search (pattern );
199+ return List .of (selectElement ("Select artifact:" , artifactNames ));
200+ }
186201
187- void addSelectItem (PromptBuilder promptBuilder , String message , String [] items )
188- throws IOException {
189- ListPromptBuilder artifactsList =
190- promptBuilder .createListPrompt ().name ("item" ).message (message ).pageSize (10 );
191- for (String artifactName : items ) {
192- artifactsList .newItem (artifactName ).text (artifactName ).add ();
202+ if (!results .containsKey ("action" )) {
203+ return List .of (selectArtifactActionElement ());
204+ } else if ("version" .equals (getSelectedId (results , "action" ))) {
205+ results .remove ("action" );
206+ pattern = getSelectedId (results , "item" );
207+ String [] artifactNames = search (pattern );
208+ return List .of (selectElement ("Select version:" , artifactNames ));
193209 }
194- artifactsList .addPrompt ();
210+
211+ return null ;
195212 }
196213
197- void addSelectArtifactAction (PromptBuilder promptBuilder ) throws IOException {
198- promptBuilder
199- .createListPrompt ()
200- .name ("action" )
201- .message ("What to do:" )
202- .newItem ("install" )
203- .text ("Download & Install artifact" )
204- .add ()
205- .newItem ("copy" )
206- .text ("Download & Copy artifact" )
207- .add ()
208- .newItem ("version" )
209- .text ("Select different version" )
210- .add ()
211- .newItem ("quit" )
212- .text ("Quit" )
213- .add ()
214- .addPrompt ();
214+ InputValue stringElement (String message ) {
215+ return new InputValue ("input" , message );
216+ }
217+
218+ ListChoice selectElement (String message , String [] items ) {
219+ List <ListItemIF > itemList =
220+ Arrays .stream (items )
221+ .map (it -> new ListItem (it , it ))
222+ .collect (Collectors .toList ());
223+ return new ListChoice (message , "item" , 10 , PageSizeType .ABSOLUTE , itemList );
224+ }
225+
226+ ListChoice selectArtifactActionElement () {
227+ List <ListItemIF > itemList = new ArrayList <>();
228+ itemList .add (new ListItem ("Download & Install artifact" , "install" ));
229+ itemList .add (new ListItem ("Download & Copy artifact" , "copy" ));
230+ itemList .add (new ListItem ("Select different version" , "version" ));
231+ itemList .add (new ListItem ("Quit" , "quit" ));
232+ return new ListChoice ("What to do:" , "action" , 10 , PageSizeType .ABSOLUTE , itemList );
215233 }
216234
217235 String selectFinalAction (ConsolePrompt prompt ) throws IOException {
218236 PromptBuilder promptBuilder = prompt .getPromptBuilder ();
219237 promptBuilder
220238 .createListPrompt ()
221239 .name ("action" )
222- .message ("What to do :" )
240+ .message ("Next step :" )
223241 .newItem ("again" )
224242 .text ("Search again" )
225243 .add ()
@@ -242,7 +260,7 @@ private static String getSelectedId(
242260 aliases = {"i" },
243261 description =
244262 "This adds the given artifacts to the list of dependencies available in the app.json file. "
245- + "It then behaves just like 'sync' and copies all artifacts in that list and all their dependencies to the target directory while at the same time removing any artifacts that are no longer needed (ie the ones that are not mentioned in the app.json file)."
263+ + "It then behaves just like 'copy -- sync' and copies all artifacts in that list and all their dependencies to the target directory while at the same time removing any artifacts that are no longer needed (ie the ones that are not mentioned in the app.json file). "
246264 + "If no artifacts are passed the app.json file will be left untouched and only the existing dependencies in the file will be copied.\n \n "
247265 + "Example:\n jpm install org.apache.httpcomponents:httpclient:4.5.14\n " )
248266 static class Install implements Callable <Integer > {
0 commit comments