-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implements `file:`/`github:`/...
- Loading branch information
Showing
17 changed files
with
348 additions
and
284 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
scalafix-reflect/src/main/scala/scalafix/internal/reflect/GitHubUrlRule.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package scalafix.internal.reflect | ||
|
||
import java.net.URL | ||
import metaconfig.Conf | ||
import metaconfig.ConfError | ||
import metaconfig.Configured | ||
import metaconfig.Configured.Ok | ||
|
||
object GitHubUrlRule { | ||
private[this] val GitHubShorthand = | ||
"""github:([^\/]+)\/([^\/]+)\/([^\/]+)""".r | ||
private[this] val GitHubShorthandWithSha = | ||
"""github:([^\/]+)\/([^\/]+)\/([^\/]+)\?sha=(.+)""".r | ||
private[this] val GitHubFallback = | ||
"""github:(.*)""".r | ||
|
||
private[this] val alphanumerical = "[^a-zA-Z0-9]" | ||
|
||
// approximates the "format=Camel" formatter in giter8. | ||
// http://www.foundweekends.org/giter8/Combined+Pages.html#Formatting+template+fields | ||
private[this] def CamelCase(string: String): String = | ||
string.split(alphanumerical).mkString.capitalize | ||
|
||
// approximates the "format=Snake" formatter in giter8. | ||
private[this] def SnakeCase(string: String): String = | ||
string.split(alphanumerical).map(_.toLowerCase).mkString("_") | ||
|
||
private[this] def expandGitHubURL( | ||
org: String, | ||
repo: String, | ||
version: String, | ||
sha: String): URL = { | ||
val fileName = s"${CamelCase(repo)}_${SnakeCase(version)}.scala" | ||
new URL( | ||
s"https://raw.githubusercontent.com/$org/$repo/$sha/scalafix/rules/src/main/scala/fix/$fileName") | ||
} | ||
|
||
def unapply(arg: Conf.Str): Option[Configured[URL]] = arg.value match { | ||
case GitHubShorthandWithSha(org, repo, version, sha) => | ||
Option(Ok(expandGitHubURL(org, repo, version, sha))) | ||
case GitHubShorthand(org, repo, version) => | ||
Option(Ok(expandGitHubURL(org, repo, version, "master"))) | ||
case GitHubFallback(invalid) => | ||
Some( | ||
ConfError | ||
.message(s"""Invalid url 'github:$invalid'. Valid formats are: | ||
|- github:org/repo/version | ||
|- github:org/repo/version?sha=branch""".stripMargin) | ||
.notOk) | ||
case _ => None | ||
} | ||
} |
104 changes: 104 additions & 0 deletions
104
scalafix-reflect/src/main/scala/scalafix/internal/reflect/RuleDecoderOps.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package scalafix.internal.reflect | ||
|
||
import java.io.FileNotFoundException | ||
import java.net.URL | ||
import java.nio.file.Files | ||
import java.nio.file.Path | ||
import java.nio.file.Paths | ||
import metaconfig.Conf | ||
import metaconfig.Configured | ||
import metaconfig.Configured.Ok | ||
import metaconfig.Input | ||
import scala.collection.concurrent.TrieMap | ||
import scala.meta.io.AbsolutePath | ||
import scalafix.SemanticdbIndex | ||
import scalafix.internal.config.ScalafixMetaconfigReaders.UriRule | ||
import scalafix.internal.util.FileOps | ||
import scalafix.internal.v1.LegacySemanticRule | ||
import scalafix.internal.v1.LegacySyntacticRule | ||
import scalafix.rule.Rule | ||
import scalafix.rule.SemanticRule | ||
import scalafix.v0 | ||
import scalafix.v1 | ||
|
||
object RuleDecoderOps { | ||
|
||
val legacySemanticRuleClass: Class[SemanticRule] = | ||
classOf[scalafix.rule.SemanticRule] | ||
val legacyRuleClass: Class[Rule] = | ||
classOf[scalafix.rule.Rule] | ||
def toRule(cls: Class[_]): v1.Rule = { | ||
if (legacySemanticRuleClass.isAssignableFrom(cls)) { | ||
val fn: SemanticdbIndex => v0.Rule = { index => | ||
val ctor = cls.getDeclaredConstructor(classOf[SemanticdbIndex]) | ||
ctor.setAccessible(true) | ||
ctor.newInstance(index).asInstanceOf[v0.Rule] | ||
} | ||
new LegacySemanticRule(fn(SemanticdbIndex.empty).name, fn) | ||
} else if (legacyRuleClass.isAssignableFrom(cls)) { | ||
val ctor = cls.getDeclaredConstructor() | ||
ctor.setAccessible(true) | ||
new LegacySyntacticRule(ctor.newInstance().asInstanceOf[v0.Rule]) | ||
} else { | ||
val ctor = cls.getDeclaredConstructor() | ||
ctor.setAccessible(true) | ||
cls.newInstance().asInstanceOf[v1.Rule] | ||
} | ||
} | ||
|
||
def tryClassload(classloader: ClassLoader, fqn: String): Option[v1.Rule] = { | ||
try { | ||
Some(toRule(classloader.loadClass(fqn))) | ||
} catch { | ||
case _: ClassNotFoundException | _: NoSuchMethodException => | ||
try { | ||
Some(toRule(classloader.loadClass(fqn + "$"))) | ||
} catch { | ||
case _: ClassNotFoundException => | ||
None | ||
} | ||
} | ||
} | ||
|
||
object UrlRule { | ||
def unapply(arg: Conf.Str): Option[Configured[URL]] = arg match { | ||
case UriRule("http" | "https", uri) if uri.isAbsolute => | ||
Option(Ok(uri.toURL)) | ||
case GitHubUrlRule(url) => Option(url) | ||
case _ => None | ||
} | ||
} | ||
|
||
// Warning: evil global mutable state | ||
val scalafixRoot: Path = Files.createTempDirectory("scalafix") | ||
scalafixRoot.toFile.deleteOnExit() | ||
val fileCache: TrieMap[Int, Path] = | ||
scala.collection.concurrent.TrieMap.empty[Int, Path] | ||
|
||
class FromSourceRule(cwd: AbsolutePath) { | ||
private def getTempFile(url: URL, code: String): Path = | ||
fileCache.getOrElseUpdate( | ||
code.hashCode, { | ||
val filename = Paths.get(url.getPath).getFileName.toString | ||
val tmp = Files.createTempFile(scalafixRoot, filename, ".scala") | ||
Files.write(tmp, code.getBytes) | ||
tmp | ||
} | ||
) | ||
def unapply(arg: Conf.Str): Option[Configured[Input]] = arg match { | ||
case UriRule("file", uri) => | ||
val path = AbsolutePath(Paths.get(uri.getSchemeSpecificPart))(cwd) | ||
Option(Ok(Input.File(path.toNIO))) | ||
case UrlRule(Ok(url)) => | ||
try { | ||
val code = FileOps.readURL(url) | ||
val file = getTempFile(url, code) | ||
Option(Ok(Input.File(file))) | ||
} catch { | ||
case _: FileNotFoundException => | ||
Option(Configured.error(s"404 - not found $url")) | ||
} | ||
case _ => None | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.