Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion js/bsc.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./config.js').loadConfig('./bsc.json', '.bys')
module.exports = require('../dist/modules/config.js').loadConfig('./bsc.json', '.bys')
2 changes: 1 addition & 1 deletion js/bsconfig.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./config.js').loadConfig('./bsconfig.json', '.bs')
module.exports = require('../dist/modules/config.js').loadConfig('./bsconfig.json', '.bs')
31 changes: 0 additions & 31 deletions js/config.js

This file was deleted.

29 changes: 0 additions & 29 deletions js/dirProcess.js

This file was deleted.

15 changes: 0 additions & 15 deletions js/download.js

This file was deleted.

34 changes: 0 additions & 34 deletions js/error.js

This file was deleted.

43 changes: 0 additions & 43 deletions js/watcher.js

This file was deleted.

37 changes: 31 additions & 6 deletions scripts/build.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,55 @@ const root = path.resolve(__dirname, '..')
const temporary = fs.mkdtempSync(path.join(root, '.bynix-build-'))
const source = path.join(root, 'src')
const output = path.join(root, 'dist', 'index.min.cjs')
const generated = path.join(root, 'dist', 'modules')
const modules = ['config', 'download', 'error', 'dirProcess', 'watcher']

async function main() {
try {
for (const name of modules) {
const code = compileSource(fs.readFileSync(path.join(source, `${name}.bs`), 'utf8'))
fs.writeFileSync(path.join(root, 'js', `${name}.js`),
code.endsWith('\n') ? code : code + '\n')
}
for (const name of fs.readdirSync(source, { withFileTypes: true })) {
if (name.isFile() && name.name.endsWith('.bs')) {
fs.writeFileSync(path.join(temporary, name.name.replace(/\.bs$/, '.js')),
compileSource(fs.readFileSync(path.join(source, name.name), 'utf8')))
}
}

fs.rmSync(generated, { recursive: true, force: true })
await build({
entryPoints: modules.map(name => path.join(temporary, `${name}.js`)),
outdir: generated,
platform: 'node',
format: 'cjs',
bundle: true,
target: 'node20',
plugins: [{
name: 'compiler',
setup(bundle) {
bundle.onResolve({ filter: /^\.\.\/scripts\/compile\.cjs$/ }, () => ({
path: path.join(root, 'scripts', 'compile.cjs')
}))
}
}]
})

await build({
entryPoints: [path.join(temporary, 'index.js')],
outfile: output,
platform: 'node',
format: 'cjs',
bundle: true,
minify: true,
target: 'node20'
target: 'node20',
plugins: [{
name: 'build-imports',
setup(bundle) {
bundle.onResolve({ filter: /^\.\.\/scripts\/compile\.cjs$/ }, () => ({
path: path.join(root, 'scripts', 'compile.cjs')
}))
bundle.onResolve({ filter: /^\.\.\/package\.json$/ }, () => ({
path: path.join(root, 'package.json')
}))
}
}]
})
fs.chmodSync(output, 0o755)
await build({
Expand Down
2 changes: 1 addition & 1 deletion src/translate.bs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require('node:fs')
const path = require('node:path')
const { extensions } = require('../js/config.js').loadConfig('./bsc.json', '.bys')
const { extensions } = require('./config.js').loadConfig('./bsc.json', '.bys')
const { compileSource } = require('../scripts/compile.cjs')

func resolveFile(file):
Expand Down
41 changes: 31 additions & 10 deletions tests/cli.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { compileSource } = require('../scripts/compile.cjs')

const root = path.resolve(__dirname, '..')
const binary = path.join(root, 'dist', 'index.min.cjs')
const generated = path.join(root, 'dist', 'modules')

function invoke(args, cwd = root) {
return spawnSync(process.execPath, [binary, ...args], { cwd, encoding: 'utf8' })
Expand All @@ -26,6 +27,10 @@ test('build produces the packaged executable', () => {
})
assert.equal(result.status, 0, result.stderr)
assert.ok(fs.statSync(binary).isFile())
for (const name of ['config', 'download', 'error', 'dirProcess', 'watcher']) {
assert.equal(fs.existsSync(path.join(root, 'js', `${name}.js`)), false)
assert.ok(fs.statSync(path.join(generated, `${name}.js`)).isFile())
}
assert.match(fs.readFileSync(binary, 'utf8'), /^#!\/usr\/bin\/env node/)
assert.equal(invoke(['--version']).status, 0)
})
Expand Down Expand Up @@ -231,18 +236,34 @@ test('conflicting legacy commands fail without changing files', context => {
assert.ok(fs.existsSync(path.join(directory, 'safe.bys')))
})

test('generated modules match their BynixScript sources', () => {
test('generated modules expose their source implementations', () => {
const exports = {
config: ['loadConfig'], download: ['https', 'getDownloads'], error: ['stackParsing'],
dirProcess: ['readAndProcessFilesInDirectory'], watcher: ['watching']
}
for (const [name, expected] of Object.entries(exports)) {
assert.deepEqual(Object.keys(require(path.join(generated, `${name}.js`))), expected)
}
})

test('package contains the CLI, browser, and generated modules without js duplicates', () => {
const result = spawnSync('npm', ['pack', '--dry-run', '--ignore-scripts', '--json'], {
cwd: root, encoding: 'utf8'
})
assert.equal(result.status, 0, result.stderr)
const files = new Set(JSON.parse(result.stdout)[0].files.map(file => file.path))
for (const file of ['dist/index.min.cjs', 'dist/browser.js',
...['config', 'download', 'error', 'dirProcess', 'watcher'].map(name => `dist/modules/${name}.js`)]) {
assert.ok(files.has(file), `${file} missing from package`)
}
for (const name of ['config', 'download', 'error', 'dirProcess', 'watcher']) {
const source = fs.readFileSync(path.join(root, 'src', `${name}.bs`), 'utf8')
const code = compileSource(source)
assert.equal(fs.readFileSync(path.join(root, 'js', `${name}.js`), 'utf8'),
code.endsWith('\n') ? code : code + '\n')
assert.equal(files.has(`js/${name}.js`), false)
}
})

test('configuration wrappers preserve separate defaults and public exports', context => {
const directory = fixture(context)
const { loadConfig } = require('../js/config.js')
const { loadConfig } = require('../dist/modules/config.js')
const legacy = require('../js/bsconfig.js')
const current = require('../js/bsc.js')
assert.equal(legacy.extensions.primary, '.bs')
Expand All @@ -265,7 +286,7 @@ test('configuration wrappers preserve separate defaults and public exports', con
})

test('generated error formatter preserves its public behavior', () => {
const { stackParsing } = require('../js/error.js')
const { stackParsing } = require('../dist/modules/error.js')
assert.equal(stackParsing('test.bys', 'missing', '', null, 'Error'), 'missing')
assert.equal(stackParsing('test.bys', 'failed in bst.js', '', 'code', 'Error'),
'Error: failed in test.bys')
Expand All @@ -275,7 +296,7 @@ test('generated error formatter preserves its public behavior', () => {

test('generated download utility keeps its https export and reports counts', () => {
const { EventEmitter } = require('node:events')
const { https, getDownloads } = require('../js/download.js')
const { https, getDownloads } = require('../dist/modules/download.js')
const originalGet = https.get
const originalLog = console.log
const messages = []
Expand All @@ -300,7 +321,7 @@ test('generated download utility keeps its https export and reports counts', ()
test('directory processor does not run on import and compiles file contents', async context => {
const directory = fixture(context)
fs.writeFileSync(path.join(directory, 'example.bs'), 'globalThis.bynixDirectoryTest = "print(1)"\n# print("unsafe")\n')
const modulePath = path.join(root, 'js', 'dirProcess.js')
const modulePath = path.join(generated, 'dirProcess.js')
const importOnly = spawnSync(process.execPath, ['-e', `require(${JSON.stringify(modulePath)})`], {
cwd: directory, encoding: 'utf8'
})
Expand All @@ -319,7 +340,7 @@ test('directory processor does not run on import and compiles file contents', as
test('watcher compiles with the shared compiler and removes generated output', async context => {
const source = fixture(context)
const output = fixture(context)
const { watching } = require('../js/watcher.js')
const { watching } = require('../dist/modules/watcher.js')
const watcher = watching(source, output)
context.after(() => watcher.close())
await new Promise((resolve, reject) => {
Expand Down
Loading