6060import java .util .logging .Logger ;
6161import edu .umd .cs .findbugs .annotations .NonNull ;
6262import edu .umd .cs .findbugs .annotations .CheckForNull ;
63- import java .util .Set ;
64- import java .util .TreeSet ;
6563import jenkins .model .Jenkins ;
6664import jenkins .scm .api .SCMRevision ;
6765import jenkins .scm .api .SCMSource ;
6866import jenkins .scm .api .SCMSourceDescriptor ;
6967import java .util .regex .Pattern ;
70- import java .util .stream .Collectors ;
7168import org .jenkinsci .Symbol ;
7269import org .jenkinsci .plugins .structs .describable .CustomDescribableModel ;
7370import org .jenkinsci .plugins .structs .describable .UninstantiatedDescribable ;
@@ -143,18 +140,18 @@ public String getLibraryPath() {
143140 }
144141
145142 @ Override public void retrieveJar (String name , String version , boolean changelog , FilePath target , Run <?, ?> run , TaskListener listener ) throws Exception {
143+ if (libraryPath != null && PROHIBITED_DOUBLE_DOT .matcher (libraryPath ).matches ()) {
144+ throw new AbortException ("Library path may not contain '..'" );
145+ }
146146 SCMRevision revision = retrySCMOperation (listener , () -> scm .fetch (version , listener , run .getParent ()));
147147 if (revision == null ) {
148148 throw new AbortException ("No version " + version + " found for library " + name );
149149 }
150- if (clone ) {
151- if (changelog ) {
152- listener .getLogger ().println ("WARNING: ignoring request to compute changelog in clone mode" );
153- }
154- doClone (name , scm .build (revision .getHead (), revision ), libraryPath , target , run , listener );
155- } else {
156- doRetrieve (name , changelog , scm .build (revision .getHead (), revision ), libraryPath , target , run , listener );
150+ if (clone && changelog ) {
151+ listener .getLogger ().println ("WARNING: ignoring request to compute changelog in clone mode" );
152+ changelog = false ;
157153 }
154+ doRetrieve (name , changelog , scm .build (revision .getHead (), revision ), libraryPath , target , run , listener , clone );
158155 }
159156
160157 private static <T > T retrySCMOperation (TaskListener listener , Callable <T > task ) throws Exception {
@@ -188,42 +185,57 @@ private static <T> T retrySCMOperation(TaskListener listener, Callable<T> task)
188185 return ret ;
189186 }
190187
191- static void doRetrieve (String name , boolean changelog , @ NonNull SCM scm , String libraryPath , FilePath target , Run <?, ?> run , TaskListener listener ) throws Exception {
188+ static void doRetrieve (String name , boolean changelog , @ NonNull SCM scm , String libraryPath , FilePath target , Run <?, ?> run , TaskListener listener , boolean clone ) throws Exception {
192189 // Adapted from CpsScmFlowDefinition:
193190 SCMStep delegate = new GenericSCMStep (scm );
194191 delegate .setPoll (false ); // TODO we have no API for determining if a given SCMHead is branch-like or tag-like; would we want to turn on polling if the former?
195192 delegate .setChangelog (changelog );
196- FilePath dir ;
197193 Node node = Jenkins .get ();
198- if (run .getParent () instanceof TopLevelItem ) {
199- FilePath baseWorkspace = node .getWorkspaceFor ((TopLevelItem ) run .getParent ());
200- if (baseWorkspace == null ) {
194+ if (clone ) {
195+ FilePath tmp = target .sibling (target .getBaseName () + "-checkout" );
196+ if (tmp == null ) {
197+ throw new IOException ();
198+ }
199+ try {
200+ retrySCMOperation (listener , () -> {
201+ delegate .checkout (run , tmp , listener , node .createLauncher (listener ));
202+ return null ;
203+ });
204+ LibraryRetriever .dir2Jar (name , libraryPath != null ? tmp .child (libraryPath ) : tmp , target , listener );
205+ } finally {
206+ tmp .deleteRecursive ();
207+ FilePath tmp2 = WorkspaceList .tempDir (tmp );
208+ if (tmp2 != null ) {
209+ tmp2 .deleteRecursive ();
210+ }
211+ }
212+ } else {
213+ FilePath dir ;
214+ if (run .getParent () instanceof TopLevelItem ) {
215+ FilePath baseWorkspace = node .getWorkspaceFor ((TopLevelItem ) run .getParent ());
216+ if (baseWorkspace == null ) {
217+ throw new IOException (node .getDisplayName () + " may be offline" );
218+ }
219+ String checkoutDirName = LibraryRecord .directoryNameFor (scm .getKey ());
220+ dir = baseWorkspace .withSuffix (getFilePathSuffix () + "libs" ).child (checkoutDirName );
221+ } else { // should not happen, but just in case:
222+ throw new AbortException ("Cannot check out in non-top-level build" );
223+ }
224+ Computer computer = node .toComputer ();
225+ if (computer == null ) {
201226 throw new IOException (node .getDisplayName () + " may be offline" );
202227 }
203- String checkoutDirName = LibraryRecord .directoryNameFor (scm .getKey ());
204- dir = baseWorkspace .withSuffix (getFilePathSuffix () + "libs" ).child (checkoutDirName );
205- } else { // should not happen, but just in case:
206- throw new AbortException ("Cannot check out in non-top-level build" );
207- }
208- Computer computer = node .toComputer ();
209- if (computer == null ) {
210- throw new IOException (node .getDisplayName () + " may be offline" );
211- }
212- try (WorkspaceList .Lease lease = computer .getWorkspaceList ().allocate (dir )) {
213- // Write the SCM key to a file as a debugging aid.
214- lease .path .withSuffix ("-scm-key.txt" ).write (scm .getKey (), "UTF-8" );
215- retrySCMOperation (listener , () -> {
216- delegate .checkout (run , lease .path , listener , node .createLauncher (listener ));
217- return null ;
218- });
219- if (libraryPath == null ) {
220- libraryPath = "." ;
221- } else if (PROHIBITED_DOUBLE_DOT .matcher (libraryPath ).matches ()) {
222- throw new AbortException ("Library path may not contain '..'" );
228+ try (WorkspaceList .Lease lease = computer .getWorkspaceList ().allocate (dir )) {
229+ // Write the SCM key to a file as a debugging aid.
230+ lease .path .withSuffix ("-scm-key.txt" ).write (scm .getKey (), "UTF-8" );
231+ retrySCMOperation (listener , () -> {
232+ delegate .checkout (run , lease .path , listener , node .createLauncher (listener ));
233+ return null ;
234+ });
235+ // Cannot add WorkspaceActionImpl to private CpsFlowExecution.flowStartNodeActions; do we care?
236+ // Copy sources with relevant files from the checkout:
237+ LibraryRetriever .dir2Jar (name , libraryPath != null ? lease .path .child (libraryPath ) : lease .path , target , listener );
223238 }
224- // Cannot add WorkspaceActionImpl to private CpsFlowExecution.flowStartNodeActions; do we care?
225- // Copy sources with relevant files from the checkout:
226- LibraryRetriever .dir2Jar (name , lease .path .child (libraryPath ), target , listener );
227239 }
228240 }
229241
@@ -232,42 +244,6 @@ private static String getFilePathSuffix() {
232244 return System .getProperty (WorkspaceList .class .getName (), "@" );
233245 }
234246
235- /**
236- * Similar to {@link #doRetrieve} but used in {@link #clone} mode.
237- */
238- private static void doClone (@ NonNull String name , @ NonNull SCM scm , String libraryPath , FilePath target , Run <?, ?> run , TaskListener listener ) throws Exception {
239- // TODO merge into doRetrieve
240- SCMStep delegate = new GenericSCMStep (scm );
241- delegate .setPoll (false );
242- delegate .setChangelog (false );
243- FilePath tmp = target .sibling (target .getBaseName () + "-checkout" );
244- if (tmp == null ) {
245- throw new IOException ();
246- }
247- try {
248- retrySCMOperation (listener , () -> {
249- delegate .checkout (run , tmp , listener , Jenkins .get ().createLauncher (listener ));
250- return null ;
251- });
252- FilePath root ;
253- if (libraryPath == null ) {
254- root = tmp ;
255- } else {
256- if (PROHIBITED_DOUBLE_DOT .matcher (libraryPath ).matches ()) {
257- throw new AbortException ("Library path may not contain '..'" );
258- }
259- root = tmp .child (libraryPath );
260- }
261- LibraryRetriever .dir2Jar (name , root , target , listener );
262- } finally {
263- tmp .deleteRecursive ();
264- FilePath tmp2 = WorkspaceList .tempDir (tmp );
265- if (tmp2 != null ) {
266- tmp2 .deleteRecursive ();
267- }
268- }
269- }
270-
271247 @ Override public FormValidation validateVersion (String name , String version , Item context ) {
272248 StringWriter w = new StringWriter ();
273249 try {
0 commit comments