-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow package when referencing rules in github #1817
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -3,20 +3,24 @@ package scalafix.internal.reflect | |||||
import java.io.FileNotFoundException | ||||||
import java.net.URL | ||||||
|
||||||
import scala.util.Try | ||||||
|
||||||
import metaconfig.Conf | ||||||
import metaconfig.ConfError | ||||||
import metaconfig.Configured | ||||||
import metaconfig.Configured.Ok | ||||||
|
||||||
object GitHubUrlRule { | ||||||
|
||||||
private val DefaultBranch = "master" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this actually be changed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sounds like a good idea to favor |
||||||
|
||||||
def unapply(arg: Conf.Str): Option[Configured[URL]] = arg.value match { | ||||||
case GitHubOrgRepoVersionSha(org, repo, version, sha) => | ||||||
Option(Ok(guessGitHubURL(org, repo, version, sha))) | ||||||
case GitHubOrgRepoVersion(org, repo, version) => | ||||||
Option(Ok(guessGitHubURL(org, repo, version, "master"))) | ||||||
case GitHubOrgRepoVersionSha(org, repo, rule, sha) => | ||||||
Some(Ok(guessGitHubURL(org, repo, rule, sha))) | ||||||
case GitHubOrgRepoVersion(org, repo, rule) => | ||||||
Some(Ok(guessGitHubURL(org, repo, rule, DefaultBranch))) | ||||||
case GitHubOrgRepo(org, repo) => | ||||||
Option(Ok(guessGitHubURL(org, repo, normalCamelCase(repo), "master"))) | ||||||
Some(Ok(guessGitHubURL(org, repo, normalCamelCase(repo), DefaultBranch))) | ||||||
case GitHubFallback(invalid) => | ||||||
Some( | ||||||
ConfError | ||||||
|
@@ -32,17 +36,21 @@ object GitHubUrlRule { | |||||
private def guessGitHubURL( | ||||||
org: String, | ||||||
repo: String, | ||||||
filename: String, | ||||||
rule: String, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe
Suggested change
|
||||||
sha: String | ||||||
): URL = { | ||||||
val firstGuess = expandGitHubURL(org, repo, filename, sha) | ||||||
if (is404(firstGuess)) { | ||||||
val secondGuess = expandGitHubURL(org, repo, g8CamelCase(filename), sha) | ||||||
if (is404(secondGuess)) firstGuess | ||||||
else secondGuess | ||||||
} else { | ||||||
firstGuess | ||||||
val (path, name) = rule.split("\\.").toList match { | ||||||
case name :: Nil => ("", name) | ||||||
case p :+ name => (p.mkString("", "/", "/"), name) | ||||||
} | ||||||
val file = path + name + ".scala" | ||||||
val url = expandGitHubURL(org, repo, file, sha) | ||||||
checkUrl(url) | ||||||
.recoverWith { case _: FileNotFoundException => | ||||||
val fallbackFile = path + g8CamelCase(name) + ".scala" | ||||||
checkUrl(expandGitHubURL(org, repo, fallbackFile, sha)) | ||||||
} | ||||||
.getOrElse(url) | ||||||
} | ||||||
|
||||||
private val GitHubOrgRepo = | ||||||
|
@@ -54,35 +62,27 @@ object GitHubUrlRule { | |||||
private val GitHubFallback = | ||||||
"""github:(.*)""".r | ||||||
|
||||||
private val alphanumerical = "[^a-zA-Z0-9]" | ||||||
private val NonAlphaNumeric = "[^a-zA-Z0-9]" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
|
||||||
// approximates the "format=Camel" formatter in giter8. | ||||||
// http://www.foundweekends.org/giter8/Combined+Pages.html#Formatting+template+fields | ||||||
// toLowerCase is required to fix https://github.com/scalacenter/scalafix/issues/342 | ||||||
private def g8CamelCase(string: String): String = | ||||||
string.split(alphanumerical).mkString.toLowerCase.capitalize | ||||||
string.split(NonAlphaNumeric).mkString.toLowerCase.capitalize | ||||||
|
||||||
private def normalCamelCase(string: String): String = | ||||||
string.split(alphanumerical).map(_.capitalize).mkString | ||||||
string.split(NonAlphaNumeric).map(_.capitalize).mkString | ||||||
|
||||||
private def checkUrl(url: URL): Try[URL] = | ||||||
Try(url.openStream().close()).map(_ => url) | ||||||
|
||||||
private def is404(url: URL): Boolean = { | ||||||
try { | ||||||
url.openStream().close() | ||||||
false | ||||||
} catch { | ||||||
case _: FileNotFoundException => | ||||||
true | ||||||
} | ||||||
} | ||||||
private def expandGitHubURL( | ||||||
org: String, | ||||||
repo: String, | ||||||
filename: String, | ||||||
file: String, | ||||||
sha: String | ||||||
): URL = { | ||||||
new URL( | ||||||
s"https://raw.githubusercontent.com/$org/$repo/$sha/scalafix/rules/src/main/scala/fix/$filename.scala" | ||||||
) | ||||||
} | ||||||
): URL = new URL( | ||||||
s"https://raw.githubusercontent.com/$org/$repo/$sha/scalafix/rules/src/main/scala/fix/$file" | ||||||
) | ||||||
|
||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,11 @@ class GitHubUrlRuleSuite extends AnyFunSuite with DiffAssertions { | |
"https://raw.githubusercontent.com/someorg/some-repo/master/scalafix/rules/" + | ||
"src/main/scala/fix/RuleName.scala" | ||
) | ||
check( | ||
"github:someorg/some-repo/version.RuleName", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could we add a test with several segments? like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also, a test with the sha maybe? (it's not documented but I would expect the most verbose/complicated syntax to support all features) |
||
"https://raw.githubusercontent.com/someorg/some-repo/master/scalafix/rules/" + | ||
"src/main/scala/fix/version/RuleName.scala" | ||
) | ||
check( | ||
"github:someorg/some-repo/RuleName?sha=master~1", | ||
"https://raw.githubusercontent.com/someorg/some-repo/master~1/scalafix/rules/" + | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if package is explicit, shouldn't we remove the
fix
prefix?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks that scalafix requires the root package to be
fix
.When only the rule name is provided, it searches in the
fix
package, this changes keep the same behaviorThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not aware of this constraint in scalafix-core, and none of the built-in rules is rooted in
fix
. Can you elaborate where you observed this limitation?I agree that the existing behavior should remain, but it feels strange that the user provides a package that is only a suffix. If the example would look like this, would it make more sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, I double checked
scalafix
uses the rule name only, regardless of the class name/package.I agree with the suggestion. Will update the PR