Skip to content

Commit 62b60a9

Browse files
committed
feat: Added refresh context
1 parent 4e20a5e commit 62b60a9

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed

src/resource/resource-controller.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,4 +746,51 @@ describe('Resource tests', () => {
746746
}
747747
})
748748
})
749+
750+
it('Can plan with settings', async () => {
751+
const resource = new class extends TestResource {
752+
getSettings(): ResourceSettings<any> {
753+
return {
754+
id: 'path',
755+
parameterSettings: {
756+
path: { type: 'string', isEqual: 'directory' },
757+
paths: { canModify: true, type: 'array', isElementEqual: 'directory' },
758+
prepend: { default: false, setting: true },
759+
declarationsOnly: { default: false, setting: true },
760+
},
761+
importAndDestroy: {
762+
refreshKeys: ['paths', 'declarationsOnly'],
763+
defaultRefreshValues: {
764+
paths: [],
765+
declarationsOnly: true,
766+
}
767+
},
768+
allowMultiple: {
769+
matcher: (desired, current) => {
770+
// console.log('Matcher');
771+
// console.log(desired);
772+
// console.log(current);
773+
774+
if (desired.path) {
775+
return desired.path === current.path;
776+
}
777+
778+
const currentPaths = new Set(current.paths)
779+
return desired.paths?.some((p) => currentPaths.has(p));
780+
}
781+
}
782+
}
783+
}
784+
785+
async refresh(parameters: Partial<TestConfig>): Promise<Partial<TestConfig> | null> {
786+
return { path: '$HOME/.bun/bin', prepend: false, declarationsOnly: false }
787+
}
788+
}
789+
790+
const controller = new ResourceController(resource);
791+
const plan = await controller.plan({ type: 'path' }, { path: '$HOME/.bun/bin' }, null, false);
792+
793+
expect(plan.requiresChanges()).to.be.false;
794+
console.log(JSON.stringify(plan, null, 2));
795+
})
749796
});

src/resource/resource-controller.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Plan } from '../plan/plan.js';
1313
import { CreatePlan, DestroyPlan, ModifyPlan } from '../plan/plan-types.js';
1414
import { ConfigParser } from './config-parser.js';
1515
import { ParsedResourceSettings } from './parsed-resource-settings.js';
16-
import { Resource } from './resource.js';
16+
import { RefreshContext, Resource } from './resource.js';
1717
import { ResourceSettings } from './resource-settings.js';
1818

1919
export class ResourceController<T extends StringIndexedObject> {
@@ -151,6 +151,11 @@ export class ResourceController<T extends StringIndexedObject> {
151151
isStateful = false,
152152
): Promise<Plan<T>> {
153153
this.validatePlanInputs(core, desired, state, isStateful);
154+
const context: RefreshContext<T> = {
155+
commandType: 'plan',
156+
isStateful,
157+
originalDesiredConfig: structuredClone(desired),
158+
};
154159

155160
this.addDefaultValues(desired);
156161
await this.applyTransformParameters(desired);
@@ -167,7 +172,7 @@ export class ResourceController<T extends StringIndexedObject> {
167172
} = parsedConfig;
168173

169174
// Refresh resource parameters. This refreshes the parameters that configure the resource itself
170-
const currentArray = await this.refreshNonStatefulParameters(allNonStatefulParameters);
175+
const currentArray = await this.refreshNonStatefulParameters(allNonStatefulParameters, context);
171176

172177
// Short circuit here. If the resource is non-existent, there's no point checking stateful parameters
173178
if (currentArray === null
@@ -259,6 +264,12 @@ export class ResourceController<T extends StringIndexedObject> {
259264
throw new Error(`Type: ${this.typeId} cannot be imported`);
260265
}
261266

267+
const context: RefreshContext<T> = {
268+
commandType: 'import',
269+
isStateful: true,
270+
originalDesiredConfig: structuredClone(parameters),
271+
};
272+
262273
this.addDefaultValues(parameters);
263274
await this.applyTransformParameters(parameters);
264275

@@ -287,7 +298,7 @@ export class ResourceController<T extends StringIndexedObject> {
287298
allStatefulParameters,
288299
} = parsedConfig;
289300

290-
const currentParametersArray = await this.refreshNonStatefulParameters(allNonStatefulParameters);
301+
const currentParametersArray = await this.refreshNonStatefulParameters(allNonStatefulParameters, context);
291302

292303
if (currentParametersArray === null
293304
|| currentParametersArray === undefined
@@ -434,8 +445,8 @@ ${JSON.stringify(refresh, null, 2)}
434445

435446
}
436447

437-
private async refreshNonStatefulParameters(resourceParameters: Partial<T>): Promise<Array<Partial<T>> | null> {
438-
const result = await this.resource.refresh(resourceParameters);
448+
private async refreshNonStatefulParameters(resourceParameters: Partial<T>, context: RefreshContext<T>): Promise<Array<Partial<T>> | null> {
449+
const result = await this.resource.refresh(resourceParameters, context);
439450

440451
const currentParametersArray = Array.isArray(result) || result === null
441452
? result

src/resource/resource.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import { ParameterChange } from '../plan/change-set.js';
44
import { CreatePlan, DestroyPlan, ModifyPlan } from '../plan/plan-types.js';
55
import { ResourceSettings } from './resource-settings.js';
66

7+
export interface RefreshContext<T extends StringIndexedObject> {
8+
isStateful: boolean;
9+
commandType: 'destroy' | 'import' | 'plan';
10+
originalDesiredConfig: Partial<T> | null;
11+
}
12+
713
/**
814
* A resource represents an object on the system (application, CLI tool, or setting)
915
* that has state and can be created and destroyed. Examples of resources include CLI tools
@@ -73,10 +79,12 @@ export abstract class Resource<T extends StringIndexedObject> {
7379
* of the desired config. In stateful mode, this will be parameters of the state config + the desired
7480
* config of any new parameters.
7581
*
82+
* @param context Context surrounding the request
83+
*
7684
* @return A config or an array of configs representing the status of the resource on the
7785
* system currently
7886
*/
79-
abstract refresh(parameters: Partial<T>): Promise<Array<Partial<T>> | Partial<T> | null>;
87+
abstract refresh(parameters: Partial<T>, context: RefreshContext<T>): Promise<Array<Partial<T>> | Partial<T> | null>;
8088

8189
/**
8290
* Create the resource (install) based on the parameters passed in. Only the desired parameters will

0 commit comments

Comments
 (0)