Skip to content
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

Replace http->https in URLs in DependencyMetadata for some Forges #3583

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import cats.implicits.*
import coursier.cache.{CachePolicy, FileCache}
import coursier.core.{Authentication, Project}
import coursier.{Fetch, Module, ModuleName, Organization}
import org.http4s.Uri
import org.scalasteward.core.data.Resolver.Credentials
import org.scalasteward.core.data.{Dependency, Resolver, Version}
import org.scalasteward.core.forge.ForgeType
import org.scalasteward.core.util.uri
import org.typelevel.log4cats.Logger

Expand Down Expand Up @@ -146,16 +148,26 @@ object CoursierAlg {
)
}

private def metadataFrom(project: Project): DependencyMetadata =
private def metadataFrom(project: Project): DependencyMetadata = {
val updateSchemeMaybe: (Uri.Scheme, Uri.Host) => Option[Uri.Scheme] =
(scheme, host) =>
if (uri.httpSchemes.contains_(scheme))
ForgeType.fromPublicWebHost(host.value).flatMap(_.publicWebScheme)
else
None

DependencyMetadata(
homePage = uri.fromStringWithScheme(project.info.homePage),
scmUrl = project.info.scm.flatMap(_.url).flatMap(uri.fromStringWithScheme),
homePage = uri.fromStringWithScheme(project.info.homePage)(updateSchemeMaybe),
scmUrl = project.info.scm
.flatMap(_.url)
.flatMap(url => uri.fromStringWithScheme(url)(updateSchemeMaybe)),
releaseNotesUrl = project.properties
.collectFirst { case (key, value) if key.equalsIgnoreCase("info.releaseNotesUrl") => value }
.flatMap(uri.fromStringWithScheme),
.flatMap(url => uri.fromStringWithScheme(url)(updateSchemeMaybe)),
versionScheme = project.properties
.collectFirst { case (key, value) if key.equalsIgnoreCase("info.versionScheme") => value }
)
}

private def parentOf(project: Project): Option[coursier.Dependency] =
project.parent.map { case (module, version) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import scala.annotation.nowarn

sealed trait ForgeType extends Product with Serializable {
def publicWebHost: Option[String]
def publicWebScheme: Option[Uri.Scheme]

/** Defines how to construct 'diff' urls for this forge type - ie a url that will show the
* difference between two git tags. These can be very useful for understanding the difference
Expand Down Expand Up @@ -67,6 +68,7 @@ object ForgeType {

case object AzureRepos extends ForgeType {
override val publicWebHost: Some[String] = Some("dev.azure.com")
override val publicWebScheme: Option[Uri.Scheme] = None
override def supportsForking: Boolean = false
override val maximumPullRequestLength: Int = 4000
val diffs: DiffUriPattern = (from, to) =>
Expand All @@ -81,6 +83,7 @@ object ForgeType {

case object Bitbucket extends ForgeType {
override val publicWebHost: Some[String] = Some("bitbucket.org")
override val publicWebScheme: Option[Uri.Scheme] = Some(Uri.Scheme.https)
override def supportsLabels: Boolean = false
val publicApiBaseUrl = uri"https://api.bitbucket.org/2.0"
val diffs: DiffUriPattern = (from, to) => _ / "compare" / s"$to..$from" withFragment "diff"
Expand All @@ -94,6 +97,7 @@ object ForgeType {
*/
case object BitbucketServer extends ForgeType {
override val publicWebHost: None.type = None
override val publicWebScheme: Option[Uri.Scheme] = None
override def supportsForking: Boolean = false
override def supportsLabels: Boolean = false
override val maximumPullRequestLength: Int = 32768
Expand All @@ -103,6 +107,7 @@ object ForgeType {

case object GitHub extends ForgeType {
override val publicWebHost: Some[String] = Some("github.com")
override val publicWebScheme: Option[Uri.Scheme] = Some(Uri.Scheme.https)
val publicApiBaseUrl = uri"https://api.github.com"
val diffs: DiffUriPattern = (from, to) => _ / "compare" / s"$from...$to"
val files: FileUriPattern = fileName => _ / "blob" / "master" / fileName
Expand All @@ -112,13 +117,15 @@ object ForgeType {

case object GitLab extends ForgeType {
override val publicWebHost: Some[String] = Some("gitlab.com")
override val publicWebScheme: Option[Uri.Scheme] = Some(Uri.Scheme.https)
val publicApiBaseUrl = uri"https://gitlab.com/api/v4"
val diffs: DiffUriPattern = GitHub.diffs
val files: FileUriPattern = GitHub.files
}

case object Gitea extends ForgeType {
override val publicWebHost: Option[String] = None
override val publicWebScheme: Option[Uri.Scheme] = None
val diffs: DiffUriPattern = GitHub.diffs
val files: FileUriPattern = fileName => _ / "src" / "branch" / "master" / fileName
}
Expand Down
28 changes: 25 additions & 3 deletions modules/core/src/main/scala/org/scalasteward/core/util/uri.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import cats.syntax.all.*
import io.circe.{Decoder, Encoder, KeyDecoder, KeyEncoder}
import monocle.Optional
import org.http4s.Uri
import org.http4s.Uri.{Authority, Scheme, UserInfo}
import org.http4s.Uri.{Authority, Host, Scheme, UserInfo}

object uri {
implicit val uriDecoder: Decoder[Uri] =
Expand All @@ -44,9 +44,31 @@ object uri {
val withUserInfo: Optional[Uri, UserInfo] =
authorityWithUserInfo.compose(withAuthority)

def fromStringWithScheme(s: String): Option[Uri] =
Uri.fromString(s).toOption.filter(_.scheme.isDefined)
/** Parses the given `String` into a `Uri` and overrides its `Uri.Scheme` according to
* `updateSchemeMaybe`. Otherwise, the `Uri.Scheme` remains unchanged after parsing.
*/
def fromStringWithScheme(
s: String
)(updateSchemeMaybe: (Scheme, Host) => Option[Scheme]): Option[Uri] =
Uri
.fromString(s)
.toOption
.filter(_.scheme.isDefined)
.mapOrKeep { case uri @ UriWithSchemeAndHost(scheme, host) =>
val newSchemeMaybe = updateSchemeMaybe(scheme, host)

newSchemeMaybe.fold(uri)(_ => uri.copy(scheme = newSchemeMaybe))
}

val httpSchemes: Set[Scheme] =
Set(Scheme.https, Scheme.http)

private object UriWithSchemeAndHost {
def unapply(uri: Uri): Option[(Scheme, Host)] = uri match {
case Uri(Some(scheme), Some(authority), _, _, _) =>
(scheme -> authority.host).some
case _ =>
None
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ class CoursierAlgTest extends CatsEffectSuite {
assertIO(obtained, expected)
}

test("getMetadata: homePage and scmUrl with the https scheme instead of http for github") {
val dep = "io.lettuce".g % "lettuce-core".a % "6.5.3.RELEASE"
val obtained = coursierAlg.getMetadata(dep, resolvers).runA(MockState.empty)
val expected = emptyMetadata.copy(
homePage = Some(uri"https://github.com/lettuce-io/lettuce-core"),
scmUrl = Some(uri"https://github.com/lettuce-io/lettuce-core")
)
assertIO(obtained, expected)
}

test("getMetadata: homePage from parent") {
val dep = "net.bytebuddy".g % "byte-buddy".a % "1.10.5"
val obtained = coursierAlg.getMetadata(dep, resolvers).runA(MockState.empty)
Expand Down