-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: Rewrite presets on new architecture
- Loading branch information
Showing
16 changed files
with
719 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import type {Preset, Presets} from './types'; | ||
|
||
import {dirname, join} from 'node:path'; | ||
import {merge} from 'lodash'; | ||
import {dump, load} from 'js-yaml'; | ||
|
||
import {Run} from '~/commands/build'; | ||
import {freeze, own} from '~/utils'; | ||
import {AsyncParallelHook, AsyncSeriesWaterfallHook} from 'tapable'; | ||
|
||
export type VarsServiceConfig = { | ||
varsPreset: string; | ||
vars: Hash; | ||
}; | ||
|
||
type VarsServiceHooks = { | ||
/** | ||
* Async waterfall hook. | ||
* Called after any presets.yaml was loaded. | ||
*/ | ||
PresetsLoaded: AsyncSeriesWaterfallHook<[Presets, RelativePath]>; | ||
/** | ||
* Async parallel hook. | ||
* Called after vars was resolved on any level. | ||
* Vars data is sealed here. | ||
*/ | ||
Resolved: AsyncParallelHook<[Preset, RelativePath]>; | ||
}; | ||
|
||
export class VarsService { | ||
hooks: VarsServiceHooks; | ||
|
||
private run: Run; | ||
|
||
private fs: Run['fs']; | ||
|
||
private logger: Run['logger']; | ||
|
||
private config: VarsServiceConfig; | ||
|
||
private cache: Record<RelativePath, Hash> = {}; | ||
|
||
constructor(run: Run) { | ||
this.run = run; | ||
this.fs = run.fs; | ||
this.logger = run.logger; | ||
this.config = run.config; | ||
this.hooks = { | ||
PresetsLoaded: new AsyncSeriesWaterfallHook(['presets', 'path']), | ||
Resolved: new AsyncParallelHook(['vars', 'path']), | ||
}; | ||
} | ||
|
||
async load(path: RelativePath) { | ||
const varsPreset = this.config.varsPreset || 'default'; | ||
const file = join(dirname(path), 'presets.yaml'); | ||
|
||
if (this.cache[file]) { | ||
return this.cache[file]; | ||
} | ||
|
||
this.logger.proc(path); | ||
|
||
const scopes = []; | ||
|
||
if (dirname(path) !== '.') { | ||
scopes.push(await this.load(dirname(path))); | ||
} | ||
|
||
try { | ||
const presets = await this.hooks.PresetsLoaded.promise( | ||
load(await this.fs.readFile(join(this.run.input, file), 'utf8')) as Presets, | ||
file, | ||
); | ||
|
||
scopes.push(presets['default']); | ||
|
||
if (varsPreset && varsPreset !== 'default') { | ||
scopes.push(presets[varsPreset] || {}); | ||
} | ||
} catch (error) { | ||
if (!own(error, 'code') || error.code !== 'ENOENT') { | ||
throw error; | ||
} | ||
} | ||
|
||
scopes.push(this.config.vars); | ||
|
||
this.cache[file] = freeze(merge({}, ...scopes)); | ||
|
||
await this.hooks.Resolved.promise(this.cache[file], file); | ||
|
||
return this.cache[file]; | ||
} | ||
|
||
dump(presets: Hash): string { | ||
return dump(presets, { | ||
lineWidth: 120, | ||
}); | ||
} | ||
|
||
entries() { | ||
return Object.entries(this.cache); | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
src/commands/build/core/vars/__snapshots__/index.spec.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html | ||
|
||
exports[`vars > service > load > should allow content extending in PresetsLoaded hook 1`] = ` | ||
"field1: value1 | ||
field2: value2 | ||
" | ||
`; | ||
|
||
exports[`vars > service > load > should allow content updating in PresetsLoaded hook 1`] = ` | ||
"field1: value2 | ||
" | ||
`; | ||
|
||
exports[`vars > service > load > should load presets file default scope 1`] = ` | ||
"field1: value1 | ||
field2: value2 | ||
" | ||
`; | ||
|
||
exports[`vars > service > load > should load presets file target scope 1`] = ` | ||
"field1: value3 | ||
field2: value2 | ||
" | ||
`; | ||
|
||
exports[`vars > service > load > should load super layers 1`] = ` | ||
"field1: value1 | ||
override1: value1 | ||
override2: value1 | ||
override3: value1 | ||
override4: value1 | ||
field2: value1 | ||
sub1: value1 | ||
sub2: value1 | ||
override5: value1 | ||
override6: value1 | ||
subsub1: value1 | ||
subsub2: value1 | ||
" | ||
`; | ||
|
||
exports[`vars > service > load > should override default presets with vars 1`] = ` | ||
"field1: value6 | ||
field2: value2 | ||
" | ||
`; | ||
|
||
exports[`vars > service > load > should override target presets with vars 1`] = ` | ||
"field1: value6 | ||
field2: value2 | ||
" | ||
`; | ||
|
||
exports[`vars > service > load > should use vars if presets not found 1`] = ` | ||
"field1: value6 | ||
" | ||
`; |
Oops, something went wrong.