Skip to content

Commit

Permalink
symbolizer
Browse files Browse the repository at this point in the history
  • Loading branch information
kla committed Oct 31, 2024
1 parent 5415b65 commit 6d1a627
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/yamler/expressions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const expressionRegex = /\$\{\{\s*([^}]+)\s*\}\}/
export const expressionRegex = /\$\{\{\s*([^}]+)\s*\}\}/g

const SINGLE_QUOTE = "'"
const DOUBLE_QUOTE = '"'
Expand Down
35 changes: 35 additions & 0 deletions src/yamler/symbolizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { deepMapWithKeys } from '~/utils'
import { expressionRegex } from './expressions'
import { parseTemplateExpression } from './expressions'

export const symbolRegex = /@@stax:([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})@@/g

export function symbolizer(attributes: Record<string, any>, symbols: Record<string, any>): Record<string, any> {
return deepMapWithKeys(attributes, (_path, key, value) => {
return [symbolize(symbols, key), symbolize(symbols, value)]
})
}

function symbolize(symbols: Record<string, any>, value: any): any {
if (!value || typeof(value) !== 'string') return value

const matches = value.match(expressionRegex)
if (!matches) return value

let result = value
for (const match of matches) {
const expression = parseTemplateExpression(match)

if (expression) {
const uuid = crypto.randomUUID()
value = `@@stax:${uuid}@@`
symbols[uuid] = expression

if (result == match)
result = value
else
result = result.replace(match, value)
}
}
return result
}
7 changes: 5 additions & 2 deletions src/yamler/yamler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { dumpOptions, importRegex, extendsRegex, rootExtendsRegex, anchorNamePrefix } from './index'
import { deepRemoveKeys, dig, exit, resolve, deepMapWithKeysAsync } from '~/utils'
import { deepRemoveKeys, dig, exit, resolve, deepMapWithKeys, deepMapWithKeysAsync } from '~/utils'
import { parseTemplateExpression, expressionRegex } from './expressions'
import { ExpressionWarning } from './index'
import { symbolizer } from './symbolizer'
import * as fs from 'fs'
import * as path from 'path'
import yaml from 'js-yaml'
Expand All @@ -18,7 +19,6 @@ export async function loadFile(filePath: string, expressionCallback?: Function |
export function dump(obj: any): string {
return yaml.dump(obj, dumpOptions)
}

export default class YamlER {
public filePath: string
public parentFile: string
Expand All @@ -28,6 +28,7 @@ export default class YamlER {
public attributes: Record<string, any>
public warnings: string[]
private expressionCallback: Function | undefined
private symbols: Record<string, any>

constructor(filePath: string, options: { parentFile?: string, expressionCallback?: Function | undefined } = {}) {
this.filePath = resolve(path.dirname(options.parentFile || filePath), filePath)
Expand All @@ -41,12 +42,14 @@ export default class YamlER {

// does not evaluate expressions
compile(): Record<string, any> {
this.symbols = {}
this.warnings = []
this.content = this.readFile(this.filePath)
this.parseImports()
this.parseExtends()
this.attributes = yaml.load(this.content)
this.attributes = deepRemoveKeys(this.attributes, [ new RegExp(`^${anchorNamePrefix}`) ])
// this.attributes = symbolizer(this.attributes, this.symbols)
return this.attributes
}

Expand Down
45 changes: 25 additions & 20 deletions tests/unit/staxfile.test.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import { describe, it, expect, beforeEach } from 'bun:test'
import { mkdirSync,rmSync } from 'fs'
import { rmSync, mkdirSync } from 'fs'
import { resolve } from '~/utils'
import { dump } from '~/yamler'
import Staxfile from '~/staxfile'
import path from 'path'

const fixturesDir = resolve('tests/fixtures')
const cacheDir = resolve('tmp/tests-staxfile-cache')

describe('Staxfile', () => {
// let staxfile
// const cacheDir = path.join(__dirname, '../../tmp/tests-staxfile-cache')
let staxfile

beforeEach(async () => {
rmSync(cacheDir, { recursive: true, force: true })
mkdirSync(cacheDir, { recursive: true })

// beforeEach(() => {
// rmSync(cacheDir, { recursive: true, force: true })
// mkdirSync(cacheDir, { recursive: true })
// staxfile = new Staxfile({ app: 'some_service', context: 'tests', source: './tests/fixtures', staxfile: './tests/fixtures/some_service.staxfile' }, { cacheDir })
// })
const config = {
app: 'rails_app',
context: 'tests',
source: './tests/fixtures',
staxfile: path.join(fixturesDir, 'rails_app.staxfile'),
cache: true
}
staxfile = new Staxfile(config, { cacheDir })
await staxfile.load()
})

// it('compiles', async () => {
// await staxfile.compile({ force: true })
// // console.log(staxfile.config)
// expect(staxfile.config.app).toBe('some_service')
// expect(staxfile.config.staxfile).toBe(resolve('./tests/fixtures/some_service.staxfile'))
// expect(staxfile.config.source).toBe(resolve('./tests/fixtures'))
// expect(staxfile.config.workspace).toBe('/workspaces/some_service')
// expect(staxfile.config.workspace_volume).toBe('some_service-workspace')
// expect(staxfile.config.vars.rails_server_port).toBe(3000)
// expect(staxfile.config.vars.ubuntu_version).toBe(24.04)
// expect(staxfile.config.vars.ruby_version).toBe('2.0.1')
// })
it('loads the correct app name', async () => {
// console.log(staxfile)
// console.log(dump(staxfile.compose))
// console.log(staxfile)
})
})
22 changes: 19 additions & 3 deletions tests/unit/yamler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,18 @@ describe('YamlER', () => {

beforeEach(async () => {
tempFiles.length = 0
yaml = await loadFile(composeYaml, expressionCallback)
})
afterEach(() => tempFiles.forEach(file => file.removeCallback()))

it('loads and processes a YAML file with imports', () => {
it('loads and processes a YAML file with imports', async () => {
yaml = await loadFile(composeYaml, expressionCallback)
expect(yaml.stax.vars.ruby_version).toBe('1.0.0')
expect(yaml.services.web.command).toBe('bin/rails server --port <stax.vars.rails_server_port> --binding 0.0.0.0')
expect(yaml.services.sidekiq.command).toBe('/usr/local/bin/launch bundle exec sidekiq')
})

it('strips _stax_import_ anchors', () => {
it('strips _stax_import_ anchors', async () => {
yaml = await loadFile(composeYaml, expressionCallback)
expect(dump(yaml)).not.toContain('_stax_import_')
})

Expand Down Expand Up @@ -209,4 +210,19 @@ describe('YamlER', () => {
['quoted "nested" arg'] // Different expected result for double quotes
)
})

describe('symbolizing expressions', () => {
// it('adds expression metadata when compiling', async () => {
// const yaml = new YamlER(composeYaml, { expressionCallback })
// console.log(dump(yaml.compile()))
// // yaml = await loadFile(composeYaml, expressionCallback)
// // expect(yaml.services.web.command).toContain('expression')
// })

it('can handle multiple expressions', async () => {
yaml = tempYamlFile({ value1: 'this is ${{ true }} and this is ${{ false }}.' })
const result = await loadFile(yaml, expressionCallback)
console.log(result)
})
})
})

0 comments on commit 6d1a627

Please sign in to comment.