apply method

  1. @override
Future<ResourceChange> apply(
  1. ResolvedResource resource,
  2. ResourceState current,
  3. FormulaContext context
)
override

Moves the resource to its declared state.

current is what read just found, passed in so a provider does not have to look twice. Returns what it did — create, update, remove, noop when it turned out there was nothing to do, or failed with a reason.

Implementation

@override
Future<ResourceChange> apply(
  ResolvedResource resource,
  ResourceState current,
  FormulaContext context,
) async {
  final formula = registry.byId(resource.id.name);
  if (formula == null) {
    return ResourceChange(
      id: resource.id,
      kind: ChangeKind.failed,
      reason: 'this node has no formula "${resource.id.name}"',
      origin: resource.origin,
    );
  }

  // A pinned version travels through the context, which is where a formula
  // already looks for one.
  final result = await formula.run(
    resource.ensure.action,
    context.copyWith(
      targetVersion: resource.resource.version,
      parameters: resource.resource.params,
    ),
  );

  if (!result.success) {
    return ResourceChange(
      id: resource.id,
      kind: ChangeKind.failed,
      reason: result.message,
      origin: resource.origin,
    );
  }

  // `changed: false` from an idempotent formula means it looked, found the
  // work already done, and did nothing — which is a no-op however the planner
  // got here. Worth reporting honestly: an operator counting what an apply
  // touched should not be told about work that never happened.
  if (!result.changed) {
    return ResourceChange(
      id: resource.id,
      kind: ChangeKind.noop,
      reason: result.message,
      origin: resource.origin,
    );
  }

  return ResourceChange(
    id: resource.id,
    kind: _kindFor(resource.ensure, current),
    reason: result.message,
    origin: resource.origin,
  );
}