Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 1 addition & 3 deletions build/coffee-esm.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import { readFile } from 'fs/promises';
import { pathToFileURL, fileURLToPath } from 'url';

import CoffeeScript, { compile } from "coffeescript";
// Handle cjs .coffee files
CoffeeScript.register()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's nice to keep this registration in case others want to use this as a CoffeeScript ESM handler. So I lean toward keeping it, but it's also OK to remove it and leave this for a CoffeeScript issue (actually jashkenas/coffeescript#5447).

import { compile } from "coffeescript";

const baseURL = pathToFileURL(process.cwd() + '/').href;
const extensionsRegex = /\.coffee$/;
Expand Down
22 changes: 13 additions & 9 deletions build/esbuild.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,25 @@ esbuild.build({
}).catch -> process.exit 1

esbuild.build({
entryPoints: ['source/config.coffee']
bundle: false
entryPoints: ['source/config.mts']
bundle: true
sourcemap
minify
watch
platform: 'node'
format: 'cjs'
outfile: 'dist/config.js'
plugins: [
resolveExtensions
coffeeScriptPlugin
bare: true
inlineMap: sourcemap
heraPlugin
]
# To get proper extension resolution for non-bundled files, we need to use
# a plugin hack: https://github.com/evanw/esbuild/issues/622#issuecomment-769462611
# set bundle: true, then rewrite .coffee -> .js and mark as external
plugins: [{
name: 'rewrite-coffee',
setup: (build) ->
build.onResolve { filter: /\.coffee$/ }, (args) ->
if (args.importer)
path: args.path.replace(/\.coffee$/, ".js")
external: true
}]
}).catch -> process.exit 1

for esm in [false, true]
Expand Down
2 changes: 1 addition & 1 deletion build/hera-esm.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function resolve(specifier, context, defaultResolve) {

export async function load(url, context, next) {
if (extensionsRegex.test(url)) {
return next(url.replace(extensionsRegex, ".cjs"), {
return next(url, {
format: "commonjs"
});
}
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@
"extension": [
".civet",
".coffee",
".hera",
".js",
".mjs",
".mts",
".ts"
],
"include": [
Expand Down
43 changes: 0 additions & 43 deletions source/config.coffee

This file was deleted.

72 changes: 72 additions & 0 deletions source/config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import path from "path";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason for the move from CoffeeScript? I preferred that version, and it's more consistent with the rest of the code (e.g. main.coffee). Ah, I see, but we want to move toward full typechecking, so this makes sense.

import fs from "fs/promises";
import { compile } from "./main.coffee";

const findInDir = async function (dirPath: string): Promise<string | undefined> {
const dir = await fs.opendir(dirPath);
for await (const entry of dir) {
if (
entry.isDirectory() &&
entry.name === ".config"
) {
// scan for ./civet.json as well as ./.config/civet.json
const found = await findInDir(
path.join(dirPath, entry.name)
);
if (found) {
return found;
}
}
if (entry.isFile()) {
const name = entry.name.replace(/^\./, ""); // allow both .civetconfig.civet and civetconfig.civet
if ([
"🐈.json",
"🐈.civet",
"civetconfig.json",
"civetconfig.civet",
].includes(name)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name in ['config.civet', 'civet.json', 'civetconfig.civet', 'civetconfig.json'] has a more efficient compilation in CoffeeScript than this. But I guess we could do even better with a Set (hoisted to global scope).

return path.join(dirPath, entry.name);
}
}
}
return
};

export var findConfig = async function (startDir: string) {
let curr = startDir,
parent = path.dirname(curr);

while (curr !== parent) {
// root directory (/, C:, etc.)
const configPath = await findInDir(curr);
if (configPath) {
return configPath;
}
curr = parent;
parent = path.dirname(curr);
}
return;
};

export var loadConfig = async function (path: string) {
const config = await fs.readFile(path, "utf8");
if (path.endsWith(".json")) {
return JSON.parse(config);
} else {
const js = compile(config, { js: true });
let exports;

try {
exports = await import(`data:text/javascript,${js}`);
} catch (e) {
console.error("Error loading config file", path, e);
}

if (typeof exports.default !== "object" || exports.default === null) {
throw new Error(
"civet config file must export an object"
);
}
return exports.default;
}
};
13 changes: 13 additions & 0 deletions test/infra/config.civet
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
assert from assert
{ findConfig, loadConfig } from ../../source/config.mts

describe "loading config", ->
it "should load from civetconfig.json", ->
path := await findConfig("test/infra/config/")
config := await loadConfig(path)

assert config.coffeeCompat

it "should load specified custom files", ->
customConfig := await loadConfig("test/infra/config/customconfig.civet")
assert.equal customConfig.someConfig, "heyy"
3 changes: 3 additions & 0 deletions test/infra/config/civetconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"coffeeCompat": true
}
3 changes: 3 additions & 0 deletions test/infra/config/customconfig.civet
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
someConfig: "heyy"
}