Skip to content

Commit

Permalink
fix issue 459 (#460)
Browse files Browse the repository at this point in the history
* fix issue 459
  • Loading branch information
lbialy authored and polkx committed Apr 18, 2024
1 parent 3cfae0c commit 26a0b89
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 13 deletions.
2 changes: 1 addition & 1 deletion core/src/main/scala/besom/internal/BesomSyntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ trait BesomSyntax:
s"Urn for component resource $name is not available. This should not happen."
}

val componentContext = ComponentContext(ctx, urnRes)
val componentContext = ComponentContext(ctx, urnRes, componentBase)
val componentOutput =
try Output(Result.pure(f(using componentContext)(using componentBase)))
catch case e: Exception => Output(Result.fail(e))
Expand Down
15 changes: 13 additions & 2 deletions core/src/main/scala/besom/internal/Context.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ trait Context extends TaskTracker:
private[besom] def monitor: Monitor
private[besom] def memo: Memo
private[besom] def getParentURN: Result[URN]
private[besom] def getParent: Option[Resource]
private[besom] def config: Config
private[besom] def isDryRun: Boolean
private[besom] def logger: BesomLogger
Expand Down Expand Up @@ -93,11 +94,18 @@ trait Context extends TaskTracker:

end Context

class ComponentContext(private val globalContext: Context, private val componentURN: Result[URN]) extends Context:
export globalContext.{getParentURN => _, *}
class ComponentContext(
private val globalContext: Context,
private val componentURN: Result[URN],
private val componentBase: ComponentBase
) extends Context:
export globalContext.{getParentURN => _, getParent => _, *}

def getParentURN: Result[URN] = componentURN

// components provide themselves as the parent to facilitate provider inheritance
def getParent: Option[Resource] = Some(componentBase)

class ContextImpl(
private[besom] val runInfo: RunInfo,
private[besom] val featureSupport: FeatureSupport,
Expand Down Expand Up @@ -126,6 +134,9 @@ class ContextImpl(
case None => Result.fail(Exception("Stack urn is not available. This should not happen."))
}

// top level Context does not return a parent (stack is the top level resource and it's providers are default provider instances)
override private[besom] def getParent: Option[Resource] = None

override private[besom] def initializeStack: Result[Unit] =
StackResource.initializeStack(runInfo)(using this).flatMap(stackPromise.fulfill)

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/besom/internal/Output.scala
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ trait OutputExtensionsFactory:
* @see
* [[OutputFactory.fail]] for creating a failed [[Output]] with a [[Throwable]]
*/
def getOrFail(throwable: Throwable)(using ctx: Context): Output[A] =
def getOrFail(throwable: => Throwable)(using ctx: Context): Output[A] =
output.flatMap {
case Some(a) => Output(a)
case None => Output.fail(throwable)
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/besom/internal/ResourceOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ResourceOps(using ctx: Context, mdc: BesomMDC[Label]):
(resource, resolver) <- ResourceDecoder.forResource[R].makeResourceAndResolver
_ <- log.debug(s"$mode resource ${mode.suffix}")
options <- options.resolve
_ <- log.debug(s"$mode resource, added to cache...")
_ <- log.debug(s"$mode resource, resolved options:\n${printer.render(options)}")
state <- createResourceState(typ, name, resource, options, remote)
_ <- log.debug(s"Created resource state")
_ <- ctx.resources.add(resource, state)
Expand Down Expand Up @@ -597,7 +597,7 @@ class ResourceOps(using ctx: Context, mdc: BesomMDC[Label]):
initialProviders <- getParentProviders
_ <- log.trace(s"mergeProviders for $typ - initialProviders: $initialProviders")
providers <- overwriteWithProvidersFromOptions(initialProviders)
_ <- log.trace(s"final providers for $typ - initialProviders: $initialProviders")
_ <- log.trace(s"final providers for $typ - providers: $providers")
yield providers

private[internal] def getProvider(
Expand Down
18 changes: 11 additions & 7 deletions core/src/main/scala/besom/internal/ResourceOptions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ trait CommonResourceOptions:
end CommonResourceOptions

extension (cro: CommonResourceOptions)
def resolve(using Context): Result[CommonResolvedResourceOptions] =
def resolve(implicitParent: Option[Resource])(using Context): Result[CommonResolvedResourceOptions] =
for
parent <- cro.parent.getData
explicitParent <- cro.parent.getData
dependsOn <- cro.dependsOn.getData
protect <- cro.protect.getData
ignoreChanges <- cro.ignoreChanges.getData
Expand All @@ -107,7 +107,8 @@ extension (cro: CommonResourceOptions)
pluginDownloadUrl <- cro.pluginDownloadUrl.getData
deletedWith <- cro.deletedWith.getData
yield CommonResolvedResourceOptions(
parent = parent.getValueOrElse(None),
// if no parent is provided by the user explicitly, use the implicit parent from Context
parent = explicitParent.getValueOrElse(None).orElse(implicitParent),
dependsOn = dependsOn.getValueOrElse(List.empty),
protect = protect.getValueOrElse(false),
ignoreChanges = ignoreChanges.getValueOrElse(List.empty),
Expand Down Expand Up @@ -147,10 +148,12 @@ sealed trait ResourceOptions:
def retainOnDelete: Output[Boolean]
def urn: Output[Option[URN]]

private[besom] def resolve(using Context): Result[ResolvedResourceOptions] =
private[besom] def resolve(using ctx: Context): Result[ResolvedResourceOptions] =
val maybeComponentParent = ctx.getParent

this match
case cr: CustomResourceOptions =>
cr.common.resolve.flatMap { common =>
cr.common.resolve(maybeComponentParent).flatMap { common =>
for
provider <- cr.provider.getValueOrElse(None)
importId <- cr.importId.getValueOrElse(None)
Expand All @@ -165,21 +168,22 @@ sealed trait ResourceOptions:
)
}
case sr: StackReferenceResourceOptions =>
sr.common.resolve.flatMap { common =>
sr.common.resolve(maybeComponentParent).flatMap { common =>
for importId <- sr.importId.getValueOrElse(None)
yield StackReferenceResolvedResourceOptions(
common,
importId = importId
)
}
case co: ComponentResourceOptions =>
co.common.resolve.flatMap { common =>
co.common.resolve(maybeComponentParent).flatMap { common =>
for providers <- co.providers.getValueOrElse(List.empty)
yield ComponentResolvedResourceOptions(
common,
providers = providers
)
}
end resolve

private[besom] def hasURN: Result[Boolean] = urn.map(_.isDefined).getValueOrElse(false)

Expand Down

0 comments on commit 26a0b89

Please sign in to comment.