Current section

Files

Jump to
garnet_tool src garnet_tool.gleam
Raw

src/garnet_tool.gleam

import argv
import esgleam
import filepath
import garnet_tool/internal
import gleam/io
import gleam/string
import gleam_community/ansi
import shellout
import simplifile
const help_message = "garnet - Compile gleam to single binary, via Deno and Bun.
Usage: garnet `target_module` `outname` `runtime`
target_module(require): Module name of compile target module.
outname(require): Name of output binary.
runtime(default: deno): Runtime of when use make single binary.
"
pub fn main() {
let _ = case argv.load().arguments {
[modname, outname, runtime] -> {
let _ = compile(modname, outname, runtime)
shellout.exit(0)
}
[modname, outname] -> {
let _ = compile(modname, outname, "deno")
shellout.exit(0)
}
_ -> {
io.println(help_message)
shellout.exit(1)
}
}
}
fn deploy_glue(modname: String) {
// mkdir `./dist`
let dir_name = "dist"
let dir = simplifile.verify_is_directory(dir_name)
let code = internal.generate_glue(modname)
// simplifile.copy_file("./src/glue.js", "./dist/glue.js")
simplifile.write("./dist/glue.js", code)
}
fn bundle(target: String) {
let _ =
esgleam.new("./dist")
|> esgleam.entry(
[target, ".gleam"]
|> string.concat,
)
|> esgleam.bundle
}
/// Compile module to single binary.
///
/// ```gleam
/// compile("example", "out", "deno")
/// ```
pub fn compile(modname: String, outfile: String, runtime: String) {
let _ = simplifile.delete(outfile)
let pwd = case simplifile.current_directory() {
Ok(path) -> path
Error(_) -> {
io.println(
"Cant get current directory."
|> ansi.red,
)
shellout.exit(1)
""
}
}
// Compile and bundle.
case bundle(modname) {
Error(_) -> shellout.exit(1)
_ -> Nil
}
deploy_glue(modname)
// Generate single binary.
let result = case runtime {
"bun" -> compile_bun(outfile, pwd)
"deno" -> compile_deno(outfile, pwd)
_ -> Error("Missing target runtime")
}
case result {
Ok(_) ->
io.println(
"Compile success!"
|> ansi.cyan,
)
Error(_) ->
io.println(
"Compile faied."
|> ansi.red,
)
}
}
fn compile_deno(outfile: String, pwd: String) -> Result(String, String) {
io.println(
"===== Build on Deno ====="
|> ansi.cyan,
)
case
shellout.command(
run: "deno",
with: ["compile", "-o", outfile, "-A", "./dist/glue.js"],
in: pwd,
opt: [shellout.LetBeStdout],
)
{
Ok(val) -> Ok(val)
Error(val) -> {
Error("Compile failed.")
}
}
}
fn compile_bun(outfile: String, pwd: String) -> Result(String, String) {
let target_path = filepath.join("/dist/", "glue.js")
io.println(
"===== Build on Bun ====="
|> ansi.cyan,
)
case
shellout.command(
run: "bun",
with: ["build", target_path, "--compile", "--outfile", outfile],
in: pwd,
opt: [shellout.LetBeStdout],
)
{
Ok(val) -> Ok(val)
Error(_) -> Error("Compile failed.")
}
}