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

fix issue 459 #460

Merged
merged 3 commits into from
Apr 17, 2024
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
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
Loading