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

Download single edition by name #7771

Merged
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 @@ -422,7 +422,7 @@ class DistributionManager(val env: Environment) {
* Should be used in places where not being able to determine the data
* directory is not a fatal error.
*/
def safeDataDirectory: Option[Path] =
private def safeDataDirectory: Option[Path] =
Try(dataDirectory).toOption

/** Determines whether a locally installed distribution exists on the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package org.enso.distribution.config
import io.circe.syntax._
import io.circe.{Decoder, Encoder, Json, JsonObject}
import org.enso.distribution.config
import org.enso.pkg.Contact

/** Global user configuration.
*
Expand All @@ -26,17 +25,7 @@ case class GlobalConfig(
authorEmail: Option[String],
editionProviders: Seq[String],
original: JsonObject
) {

/** Returns a [[Contact]] for the default author if at least one of the name
* and email is set.
*
* If both name and email are not set, returns None.
*/
def defaultAuthor: Option[Contact] =
if (authorName.isEmpty && authorEmail.isEmpty) None
else Some(Contact(name = authorName, email = authorEmail))
}
)

object GlobalConfig {
private val defaultEditionProviders: Seq[String] = Seq(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ import scala.util.{Failure, Try}
class EditionUpdater(cachePath: Path, sources: Seq[String]) {
private lazy val logger = Logger[EditionUpdater]

/** Downloads requested edition from the [[sources]] to the [[cachePath]].
*
* If there are errors when processing one of the edition sources or
* downloading the editions, the errors are logged as warnings, but other
* sources proceed as normal.
*/
def downloadEdition(name: String): Try[Unit] = Try {
for {
repositoryManifests <- fetchManifests()
(repositoryRoot, manifest) <- repositoryManifests
edition <- manifest.editions
if edition.name == name
} {
downloadEdition(repositoryRoot, edition)
}
}

/** Downloads edition lists from the [[sources]] and downloads any missing
* editions to the [[cachePath]].
*
Expand All @@ -35,23 +52,12 @@ class EditionUpdater(cachePath: Path, sources: Seq[String]) {
*/
def updateEditions(): Try[Unit] = Try {
for {
source <- sources
repositoryRoot <- Try { URIBuilder.fromUri(source) }
.recoverWith { error =>
logger.warn(s"Failed to parse the source URI [$source]: $error")
Failure(error)
}
manifest <- downloadEditionRepositoryManifest(repositoryRoot)
.recoverWith { error =>
logger.warn(s"Failed to fetch editions from [$source]: $error")
Failure(error)
}
edition <- manifest.editions
repositoryManifests <- fetchManifests()
(repositoryRoot, manifest) <- repositoryManifests
edition <- manifest.editions
if !isEditionAlreadyCached(edition)
} {
downloadEdition(repositoryRoot, edition).getOrElse {
logger.warn(s"Failed to download edition [$edition] from [$source].")
}
downloadEdition(repositoryRoot, edition)
}
}

Expand All @@ -65,7 +71,7 @@ class EditionUpdater(cachePath: Path, sources: Seq[String]) {
YamlHelper.parseString[Manifest](response.content).toTry.get
}

private def downloadEdition(
private def tryDownloadEdition(
repositoryRoot: URIBuilder,
editionName: EditionName
): Try[Unit] = Try {
Expand All @@ -78,6 +84,33 @@ class EditionUpdater(cachePath: Path, sources: Seq[String]) {
HTTPDownload.download(request, destinationPath).force()
}

private def downloadEdition(
repositoryRoot: URIBuilder,
editionName: EditionName
): Unit =
tryDownloadEdition(repositoryRoot, editionName).getOrElse {
logger.warn(
s"Failed to download edition [$editionName] from [${repositoryRoot.uri}]."
)
}

private def fetchManifests(): Try[Seq[(URIBuilder, Manifest)]] = Try {
for {
source <- sources
repositoryRoot <- Try { URIBuilder.fromUri(source) }.recoverWith {
error =>
logger.warn(s"Failed to parse the source URI [$source]: $error")
Failure(error)
}.toOption
manifest <- downloadEditionRepositoryManifest(
repositoryRoot
).recoverWith { error =>
logger.warn(s"Failed to fetch editions from [$source]: $error")
Failure(error)
}.toOption
} yield (repositoryRoot, manifest)
}

private def isEditionAlreadyCached(editionName: EditionName): Boolean =
Files.exists(cachePath.resolve(editionName.toFileName))
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,17 @@ class UpdatingEditionProvider(
private val provider = new FileSystemEditionProvider(actualSearchPaths)
private val updater = new EditionUpdater(cachePath, sources)

private var wasUpdateTried: Boolean = false

/** @inheritdoc */
override def findEditionForName(
name: String
): Either[EditionLoadingError, Editions.Raw.Edition] = {
): Either[EditionLoadingError, Editions.Raw.Edition] =
provider.findEditionForName(name) match {
case Left(EditionNotFound(_)) =>
if (!wasUpdateTried) {
wasUpdateTried = true
updater.updateEditions()
provider.findEditionForName(name)
} else Left(EditionNotFound(name))
updater.downloadEdition(name)
provider.findEditionForName(name)
case Left(otherError) => Left(otherError)
case Right(value) => Right(value)
}
}

/** Finds all editions available on the [[searchPaths]]. */
override def findAvailableEditions(): Seq[String] =
Expand All @@ -52,7 +46,6 @@ class UpdatingEditionProvider(
def findAvailableEditions(update: Boolean): Seq[String] = {
if (update) {
updater.updateEditions()
wasUpdateTried = true
}

provider.findAvailableEditions()
Expand Down
Loading