diff --git a/README.md b/README.md index ec16f7c..c5bd4f9 100644 --- a/README.md +++ b/README.md @@ -627,9 +627,7 @@ Environments are passed into the garden when it boots up, typically by overlayin In some cases you want to set environment variables for seeds in a packet by default. Instead of having annoying, error-prone duplicated `let-multi` for each seed entrypoint, you can define an environment overlay at the top of the seed packet. -The actual environment used by any seed when it is first grown will be the garden's base environment, overlaid with the contents of the packet's environment. - -Note that if a seed is grown as a sub-seed it will not use its own environment and instead use the environment that is passed down to it by its calling seed. (TODO: this behavior makes this functionality not useful for seeds used as sub-expressions in other packets, who expect a given amount of values being set) +The actual environment used by any seed when it is first grown will be the garden's base environment, overlaid with any `let`/`let-multi` overrides from seeds higher in the call stack, and finally have the packet's `environment` values overlaid. This creates behavior semantically similar to if every seed in the packet was wrapped in a `let-multi` with the packet's environment, and ensure that seeds have environment values set in a way they expect. The environment can contain any number of values, but some are used for specific uses by the framework, documented below. diff --git a/src/seed.ts b/src/seed.ts index c12f8c8..65757e5 100644 --- a/src/seed.ts +++ b/src/seed.ts @@ -174,7 +174,8 @@ export class Seed { } async grow(env? : Environment) : Promise { - if (!env) env = this.garden.environment.clone(this._environmentOverlay); - return grow(this, env); + if (!env) env = this.garden.environment; + const subEnv = env.clone(this._environmentOverlay); + return grow(this, subEnv); } } \ No newline at end of file diff --git a/test/base/test.ts b/test/base/test.ts index c8376eb..e0465a6 100644 --- a/test/base/test.ts +++ b/test/base/test.ts @@ -639,7 +639,7 @@ Suffix`; assert.deepStrictEqual(actual, golden); }); - it ('environment overlay is ignored in sub-seed execution', async () => { + it ('environment overlay overrides parent seed let', async () => { const garden = loadTestGarden(); const packet = seedPacket.parse({ version: 0, @@ -656,8 +656,7 @@ Suffix`; name: 'komoroske.com:test', value: 5, block: { - type: 'var', - name: 'komoroske.com:test' + id: 'env-test' } } } @@ -665,11 +664,52 @@ Suffix`; garden.plantSeedPacket('test/base/c_test.json', packet); const seed = await garden.seed('other-test'); const actual = await seed.grow(); - //The other-test should shadow the environment variable. - const golden = 5; + //The other-test value should be shadowed by the environment packet + const golden = 3; assert.deepStrictEqual(actual, golden); }); + it ('environment overlay passed into sub-seed', async () => { + const garden = loadTestGarden(); + const packet = seedPacket.parse({ + version: 0, + environment: { + 'komoroske.com:test': 3 + }, + seeds: { + 'env-test': { + type: 'array', + items: [ + { + type: 'var', + name: 'komoroske.com:test' + }, + { + type: 'var', + name: 'komoroske.com:other' + } + ] + }, + 'other-test': { + type: 'let', + name: 'komoroske.com:other', + value: 5, + block: { + id: 'env-test' + } + } + } + }); + garden.plantSeedPacket('test/base/c_test.json', packet); + const seed = await garden.seed('other-test'); + const actual = await seed.grow(); + //The other value should make it through from the parent seed, and main + //value should not be affected. + const golden = [3, 5]; + assert.deepStrictEqual(actual, golden); + }); + + });