-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
158 additions
and
52 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { existsSync } from 'fs' | ||
import { dasherize } from '~/utils' | ||
import * as path from 'path' | ||
import Staxfile from './index' | ||
|
||
export default class Expressions { | ||
private staxfile: Staxfile | ||
|
||
constructor(staxfile: Staxfile) { | ||
this.staxfile = staxfile | ||
} | ||
|
||
evaluate(name: string, args: any[]): string { | ||
if (name.startsWith('stax.')) return this.fetchConfigValue(name) | ||
if (name === 'read') return this.read(args[0], args[1]) | ||
if (name === 'mount_workspace') return this.mountWorkspace() | ||
if (name === 'mount_ssh_auth_sock') return this.mountSshAuthSock() | ||
if (name === 'path.resolve') return path.resolve(args[0]) | ||
if (name === 'user') return process.env.USER || '' | ||
if (name === 'user_id') return process.getuid().toString() | ||
if (name === 'dasherize') return dasherize(args[0]) | ||
if (name === 'exists') return existsSync(args[0]).toString() | ||
|
||
this.staxfile.warnings.add(`Invalid template expression: ${name}`) | ||
} | ||
|
||
private fetchConfigValue(name: string): string { | ||
const key = name.slice(5) // strip 'stax.' prefix | ||
|
||
if (key === 'host_services') | ||
return process.env.STAX_HOST_SERVICES || '' | ||
|
||
if (key === 'ssh_auth_sock') | ||
return '/run/host-services/ssh-auth.sock' | ||
|
||
if (!this.staxfile.config.hasProperty(key)) { | ||
if (name === 'config.workspace_volume' && !this.staxfile.location.local) | ||
this.staxfile.warnings.add(`A '${name}' name must be defined when setting up from a remote source.`) | ||
|
||
this.staxfile.warnings.add(`Undefined reference to '${name}'`) | ||
} | ||
|
||
return this.staxfile.config.fetch(key) | ||
} | ||
|
||
private read(file: string, defaultValue: string): string { | ||
try { | ||
return (this.staxfile.location.readSync(file) || defaultValue).trim() | ||
} catch (e) { | ||
console.warn(`Couldn't read ${file}: ${e.code}... using default value of '${defaultValue}'`) | ||
return defaultValue | ||
} | ||
} | ||
|
||
private mountWorkspace(): string { | ||
const src = this.staxfile.config.location.local ? this.staxfile.config.source : this.staxfile.config.workspace_volume | ||
const dest = this.staxfile.config.workspace | ||
return `${src}:${dest}` | ||
} | ||
|
||
private mountSshAuthSock(): string { | ||
return process.platform === 'darwin' ? | ||
'${{ stax.ssh_auth_sock }}:${{ stax.ssh_auth_sock }}' : | ||
'${{ stax.host_services }}:/run/host-services' | ||
} | ||
} |
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,88 @@ | ||
import { describe, it, expect, beforeEach, mock } from 'bun:test' | ||
import Expressions from '~/staxfile/expressions' | ||
|
||
describe('Expressions', () => { | ||
let expression | ||
let mockStaxfile | ||
|
||
beforeEach(() => { | ||
mockStaxfile = { | ||
warnings: { add: mock(() => {}) }, | ||
config: { | ||
hasProperty: mock(() => true), | ||
fetch: mock((key) => `mock_${key}`), | ||
}, | ||
location: { | ||
local: true, | ||
readSync: mock(() => 'mock_file_content'), | ||
}, | ||
} | ||
expression = new Expressions(mockStaxfile) | ||
}) | ||
|
||
it('evaluates stax config values', () => { | ||
const result = expression.evaluate('stax.some_key', []) | ||
expect(result).toBe('mock_some_key') | ||
expect(mockStaxfile.config.fetch).toHaveBeenCalledWith('some_key') | ||
}) | ||
|
||
it('evaluates read function', () => { | ||
const result = expression.evaluate('read', ['test.txt', 'default']) | ||
expect(result).toBe('mock_file_content') | ||
expect(mockStaxfile.location.readSync).toHaveBeenCalledWith('test.txt') | ||
}) | ||
|
||
// it('evaluates mount_workspace function', () => { | ||
// mockStaxfile.config.source = '/mock/source' | ||
// mockStaxfile.config.workspace = '/mock/workspace' | ||
// const result = expression.evaluate('mount_workspace', []) | ||
// expect(result).toBe('/mock/source:/mock/workspace') | ||
// }) | ||
|
||
it('evaluates mount_ssh_auth_sock function', () => { | ||
const originalPlatform = process.platform | ||
Object.defineProperty(process, 'platform', { value: 'darwin' }) | ||
const result = expression.evaluate('mount_ssh_auth_sock', []) | ||
expect(result).toBe('${{ stax.ssh_auth_sock }}:${{ stax.ssh_auth_sock }}') | ||
Object.defineProperty(process, 'platform', { value: originalPlatform }) | ||
}) | ||
|
||
it('evaluates path.resolve function', () => { | ||
const result = expression.evaluate('path.resolve', ['/test/path']) | ||
expect(result).toBe('/test/path') | ||
}) | ||
|
||
it('evaluates user function', () => { | ||
const originalUser = process.env.USER | ||
process.env.USER = 'testuser' | ||
const result = expression.evaluate('user', []) | ||
expect(result).toBe('testuser') | ||
process.env.USER = originalUser | ||
}) | ||
|
||
it('evaluates user_id function', () => { | ||
const result = expression.evaluate('user_id', []) | ||
expect(result).toBe(process.getuid().toString()) | ||
}) | ||
|
||
it('evaluates dasherize function', () => { | ||
const result = expression.evaluate('dasherize', ['TestString']) | ||
expect(result).toBe('test-string') | ||
}) | ||
|
||
// it('evaluates exists function', () => { | ||
// const result = expression.evaluate('exists', ['/existing/path']) | ||
// expect(result).toBe('true') | ||
// }) | ||
|
||
it('adds warning for invalid expression', () => { | ||
expression.evaluate('invalid_expression', []) | ||
expect(mockStaxfile.warnings.add).toHaveBeenCalledWith('Invalid template expression: invalid_expression') | ||
}) | ||
|
||
it('adds warning for undefined stax config', () => { | ||
mockStaxfile.config.hasProperty = mock(() => false) | ||
expression.evaluate('stax.undefined_key', []) | ||
expect(mockStaxfile.warnings.add).toHaveBeenCalledWith("Undefined reference to 'stax.undefined_key'") | ||
}) | ||
}) |