2
2
//DEPS eu.maveniverse.maven.mima:context:2.4.15 eu.maveniverse.maven.mima.runtime:standalone-static:2.4.15
3
3
//DEPS info.picocli:picocli:4.7.6
4
4
//DEPS com.google.code.gson:gson:2.11.0
5
+ //DEPS org.jline:jline-console-ui:3.26.2 org.jline:jline-terminal-jni:3.26.2
5
6
//DEPS org.slf4j:slf4j-api:2.0.13 org.slf4j:slf4j-simple:2.0.13
6
7
//SOURCES Jpm.java json/AppInfo.java util/FileUtils.java util/ResolverUtils.java util/SearchUtils.java
7
8
//SOURCES util/SearchResult.java util/SyncStats.java util/Version.java
16
17
import java .util .stream .Collectors ;
17
18
import org .codejive .jpm .util .SyncStats ;
18
19
import org .codejive .jpm .util .Version ;
20
+ import org .jline .consoleui .prompt .ConsolePrompt ;
21
+ import org .jline .consoleui .prompt .ListResult ;
22
+ import org .jline .consoleui .prompt .PromptResultItemIF ;
23
+ import org .jline .consoleui .prompt .builder .ListPromptBuilder ;
24
+ import org .jline .consoleui .prompt .builder .PromptBuilder ;
25
+ import org .jline .terminal .Terminal ;
26
+ import org .jline .terminal .TerminalBuilder ;
19
27
import picocli .CommandLine ;
20
28
import picocli .CommandLine .Command ;
21
29
import picocli .CommandLine .Mixin ;
@@ -74,6 +82,12 @@ static class Sync implements Callable<Integer> {
74
82
@ Mixin QuietMixin quietMixin ;
75
83
@ Mixin CopyMixin copyMixin ;
76
84
85
+ @ Option (
86
+ names = {"-i" , "--interactive" },
87
+ description = "Interactively search and select artifacts to install" ,
88
+ defaultValue = "false" )
89
+ private boolean interactive ;
90
+
77
91
@ Option (
78
92
names = {"-m" , "--max" },
79
93
description = "Maximum number of results to return" ,
@@ -82,22 +96,135 @@ static class Sync implements Callable<Integer> {
82
96
83
97
@ Parameters (
84
98
paramLabel = "artifactPattern" ,
85
- description = "Partial or full artifact name to search for." )
99
+ description = "Partial or full artifact name to search for." ,
100
+ defaultValue = "" )
86
101
private String artifactPattern ;
87
102
88
103
@ Override
89
104
public Integer call () throws Exception {
90
- String [] artifactNames =
91
- Jpm .builder ()
92
- .directory (copyMixin .directory )
93
- .noLinks (copyMixin .noLinks )
94
- .build ()
95
- .search (artifactPattern , Math .min (max , 200 ));
96
- if (artifactNames .length > 0 ) {
97
- Arrays .stream (artifactNames ).forEach (System .out ::println );
105
+ if (interactive || artifactPattern == null || artifactPattern .isEmpty ()) {
106
+ try (Terminal terminal = TerminalBuilder .builder ().build ()) {
107
+ while (true ) {
108
+ ConsolePrompt prompt = new ConsolePrompt (terminal );
109
+ if (artifactPattern == null || artifactPattern .isEmpty ()) {
110
+ artifactPattern = askString (prompt , "Search for:" );
111
+ }
112
+ String [] artifactNames = search (artifactPattern );
113
+ PromptBuilder promptBuilder = prompt .getPromptBuilder ();
114
+ addSelectItem (promptBuilder , "Select artifact:" , artifactNames );
115
+ addSelectArtifactAction (promptBuilder );
116
+ Map <String , PromptResultItemIF > result =
117
+ prompt .prompt (promptBuilder .build ());
118
+ String selectedArtifact = getSelectedId (result , "item" );
119
+ String artifactAction = getSelectedId (result , "action" );
120
+ if ("install" .equals (artifactAction )) {
121
+ SyncStats stats =
122
+ Jpm .builder ()
123
+ .directory (copyMixin .directory )
124
+ .noLinks (copyMixin .noLinks )
125
+ .build ()
126
+ .install (new String [] {selectedArtifact });
127
+ if (!quietMixin .quiet ) {
128
+ printStats (stats );
129
+ }
130
+ } else if ("copy" .equals (artifactAction )) {
131
+ SyncStats stats =
132
+ Jpm .builder ()
133
+ .directory (copyMixin .directory )
134
+ .noLinks (copyMixin .noLinks )
135
+ .build ()
136
+ .copy (new String [] {selectedArtifact }, false );
137
+ if (!quietMixin .quiet ) {
138
+ printStats (stats );
139
+ }
140
+ } else if ("version" .equals (artifactAction )) {
141
+ artifactPattern = selectedArtifact ;
142
+ continue ;
143
+ } else { // quit
144
+ break ;
145
+ }
146
+ String finalAction = selectFinalAction (prompt );
147
+ if ("quit" .equals (finalAction )) {
148
+ break ;
149
+ }
150
+ artifactPattern = null ;
151
+ }
152
+ }
153
+ } else {
154
+ String [] artifactNames = search (artifactPattern );
155
+ if (artifactNames .length > 0 ) {
156
+ Arrays .stream (artifactNames ).forEach (System .out ::println );
157
+ }
98
158
}
99
159
return 0 ;
100
160
}
161
+
162
+ String [] search (String artifactPattern ) throws IOException {
163
+ return Jpm .builder ()
164
+ .directory (copyMixin .directory )
165
+ .noLinks (copyMixin .noLinks )
166
+ .build ()
167
+ .search (artifactPattern , Math .min (max , 200 ));
168
+ }
169
+
170
+ String askString (ConsolePrompt prompt , String message ) throws IOException {
171
+ PromptBuilder promptBuilder = prompt .getPromptBuilder ();
172
+ promptBuilder .createInputPrompt ().name ("input" ).message (message ).addPrompt ();
173
+ Map <String , PromptResultItemIF > result = prompt .prompt (promptBuilder .build ());
174
+ return result .get ("input" ).getResult ();
175
+ }
176
+
177
+ void addSelectItem (PromptBuilder promptBuilder , String message , String [] items )
178
+ throws IOException {
179
+ ListPromptBuilder artifactsList =
180
+ promptBuilder .createListPrompt ().name ("item" ).message (message ).pageSize (10 );
181
+ for (String artifactName : items ) {
182
+ artifactsList .newItem (artifactName ).text (artifactName ).add ();
183
+ }
184
+ artifactsList .addPrompt ();
185
+ }
186
+
187
+ void addSelectArtifactAction (PromptBuilder promptBuilder ) throws IOException {
188
+ promptBuilder
189
+ .createListPrompt ()
190
+ .name ("action" )
191
+ .message ("What to do:" )
192
+ .newItem ("install" )
193
+ .text ("Install artifact" )
194
+ .add ()
195
+ .newItem ("copy" )
196
+ .text ("Copy artifact" )
197
+ .add ()
198
+ .newItem ("version" )
199
+ .text ("Select different version" )
200
+ .add ()
201
+ .newItem ("quit" )
202
+ .text ("Quit" )
203
+ .add ()
204
+ .addPrompt ();
205
+ }
206
+
207
+ String selectFinalAction (ConsolePrompt prompt ) throws IOException {
208
+ PromptBuilder promptBuilder = prompt .getPromptBuilder ();
209
+ promptBuilder
210
+ .createListPrompt ()
211
+ .name ("action" )
212
+ .message ("What to do:" )
213
+ .newItem ("again" )
214
+ .text ("Search again" )
215
+ .add ()
216
+ .newItem ("quit" )
217
+ .text ("Quit" )
218
+ .add ()
219
+ .addPrompt ();
220
+ Map <String , PromptResultItemIF > result = prompt .prompt (promptBuilder .build ());
221
+ return getSelectedId (result , "action" );
222
+ }
223
+
224
+ private static String getSelectedId (
225
+ Map <String , PromptResultItemIF > result , String itemName ) {
226
+ return ((ListResult ) result .get (itemName )).getSelectedId ();
227
+ }
101
228
}
102
229
103
230
@ Command (
0 commit comments