@@ -136,7 +136,98 @@ static Scalafix fetchAndClassloadInstance(String requestedScalaVersion) throws S
136136     */ 
137137    static  Scalafix  fetchAndClassloadInstance (String  requestedScalaVersion , List <Repository > repositories )
138138            throws  ScalafixException  {
139+         Properties  properties  = new  Properties ();
140+         String  propertiesPath  = "scalafix-interfaces.properties" ;
141+         try  {
142+             InputStream  stream  = Scalafix .class .getClassLoader ().getResourceAsStream (propertiesPath );
143+             properties .load (stream );
144+             return  fetchAndClassloadInstance (properties , requestedScalaVersion , repositories );
145+         } catch  (Exception  e ) {
146+             System .err .println (
147+                 "Failed to load '"  + propertiesPath  +  "' from local artifact, "  +
148+                 "falling back to fetching the latest scalafix version..." );
149+ 
150+             String  latestVersion ;
151+             try  {
152+                 latestVersion  = ScalafixCoursier .latestScalafixProperties (repositories );
153+             } catch  (Exception  ee ) {
154+                 throw  new  ScalafixException (
155+                     "Failed to lookup latest scalafix version" , ee );
156+             }   
157+             return  fetchAndClassloadInstance (latestVersion , requestedScalaVersion , repositories );
158+         }
159+     }
160+ 
161+     /** 
162+      * Fetch JARs containing an implementation of {@link Scalafix} using Coursier and classload an instance of it via 
163+      * runtime reflection. 
164+      * <p> 
165+      * The custom classloader optionally provided with {@link ScalafixArguments#withToolClasspath} to compile and 
166+      * classload external rules must have the classloader of the returned instance as ancestor to share a common 
167+      * loaded instance of `scalafix-core`, and therefore have been compiled against the requested Scala version. 
168+      * 
169+      * @param scalafixVersion    Fetch a specific, implementation of {@link Scalafix}. Must be binary-compatible. 
170+      * @param requestedScalaVersion A full Scala version (i.e. "3.3.4") or a major.minor one (i.e. "3.3") to infer 
171+      *                              the major.minor Scala version that should be available in the classloader of the 
172+      *                              returned instance. To be able to run advanced semantic rules using the Scala 
173+      *                              Presentation Compiler such as ExplicitResultTypes, this must be source-compatible 
174+      *                              with the version that the target classpath is built with, as provided with 
175+      *                              {@link ScalafixArguments#withScalaVersion}. 
176+      * @return An implementation of the {@link Scalafix} interface. 
177+      * @throws ScalafixException in case of errors during artifact resolution/fetching. 
178+      */ 
179+     static  Scalafix  fetchAndClassloadInstance (String  scalafixVersion ,  String  requestedScalaVersion  )
180+             throws  ScalafixException  {
181+         return  fetchAndClassloadInstance (scalafixVersion , requestedScalaVersion , Repository .defaults ());
182+     }
183+ 
184+     /** 
185+      * Fetch JARs containing an implementation of {@link Scalafix} from the provided repositories using Coursier and 
186+      * classload an instance of it via runtime reflection. 
187+      * <p> 
188+      * The custom classloader optionally provided with {@link ScalafixArguments#withToolClasspath} to compile and 
189+      * classload external rules must have the classloader of the returned instance as ancestor to share a common 
190+      * loaded instance of `scalafix-core`, and therefore have been compiled against the requested Scala version. 
191+      * 
192+      * @param scalafixVersion    Fetch a specific, implementation of {@link Scalafix}. Must be binary-compatible. 
193+      * @param requestedScalaVersion A full Scala version (i.e. "3.3.4") or a major.minor one (i.e. "3.3") to infer 
194+      *                              the major.minor Scala version that should be available in the classloader of the 
195+      *                              returned instance. To be able to run advanced semantic rules using the Scala 
196+      *                              Presentation Compiler such as ExplicitResultTypes, this must be source-compatible 
197+      *                              with the version that the target classpath is built with, as provided with 
198+      *                              {@link ScalafixArguments#withScalaVersion}. 
199+      * @param repositories       Maven/Ivy repositories to fetch the JARs from. 
200+      * @return An implementation of the {@link Scalafix} interface. 
201+      * @throws ScalafixException in case of errors during artifact resolution/fetching. 
202+      */ 
203+     static  Scalafix  fetchAndClassloadInstance (
204+         String  scalafixVersion ,
205+         String  requestedScalaVersion ,
206+         List <Repository > repositories 
207+     ) throws  ScalafixException  {
208+         Properties  properties  = new  Properties ();
209+         String  propertiesPath  = "scalafix-interfaces.properties" ;
210+         try  {
211+             List <URL > jars  = ScalafixCoursier .scalafixPropertiesJars (repositories , scalafixVersion );
212+             URLClassLoader  classLoader  =
213+                 new  URLClassLoader (jars .stream ().toArray (URL []::new ), null );
214+             
215+             InputStream  stream  = classLoader .getResourceAsStream (propertiesPath );
216+             properties .load (stream );
217+         } catch  (Exception  e ) {
218+             throw  new  ScalafixException (
219+                 "Failed to fetch '"  + propertiesPath  + "' for scalafix version "  + scalafixVersion ,
220+                 e );
221+         }
139222
223+         return  fetchAndClassloadInstance (properties , requestedScalaVersion , repositories );
224+     }
225+ 
226+     private  static  Scalafix  fetchAndClassloadInstance (
227+         Properties  properties ,
228+         String  requestedScalaVersion ,
229+         List <Repository > repositories 
230+     ) throws  ScalafixException  {
140231        String  requestedScalaMajorMinorOrMajorVersion  =
141232            requestedScalaVersion .replaceAll ("^(\\ d+\\ .\\ d+).*" , "$1" );
142233
@@ -161,34 +252,10 @@ static Scalafix fetchAndClassloadInstance(String requestedScalaVersion, List<Rep
161252            throw  new  IllegalArgumentException ("Unsupported scala version "  + requestedScalaVersion );
162253        }
163254
164-         Properties  properties  = new  Properties ();
165-         String  propertiesPath  = "scalafix-interfaces.properties" ;
166-         try  {
167-             InputStream  stream  = Scalafix .class .getClassLoader ().getResourceAsStream (propertiesPath );
168-             properties .load (stream );
169-         } catch  (Exception  e ) {
170-             System .err .println (
171-                 "Failed to load '"  + propertiesPath  +  "' from local artifact, "  +
172-                 "falling back to fetching the latest scalafix version..." );
173- 
174-             try  {
175-                 List <URL > jars  = ScalafixCoursier .latestScalafixPropertiesJars (repositories );
176-                 URLClassLoader  classLoader  =
177-                     new  URLClassLoader (jars .stream ().toArray (URL []::new ), null );
178-                 
179-                 InputStream  stream  = classLoader .getResourceAsStream (propertiesPath );
180-                 properties .load (stream );
181-             } catch  (Exception  ee ) {
182-                 throw  new  ScalafixException (
183-                     "Failed to load '"  + propertiesPath  + "' from local & remote artifacts" ,
184-                     ee );
185-             }
186-         }
187- 
188255        String  scalafixVersion  = properties .getProperty ("scalafixVersion" );
189256        String  scalaVersion  = properties .getProperty (scalaVersionKey );
190257        if  (scalafixVersion  == null  || scalaVersion  == null )
191-             throw  new  ScalafixException ("Failed to lookup versions from '"   +  propertiesPath  +  "' "
258+             throw  new  ScalafixException ("Failed to lookup versions from properties file " );
192259
193260        List <URL > jars  = ScalafixCoursier .scalafixCliJars (repositories , scalafixVersion , scalaVersion );
194261        ClassLoader  parent  = new  ScalafixInterfacesClassloader (Scalafix .class .getClassLoader ());
0 commit comments