jm

Odin for scripts: small packages and a runner, on core: only
Log | Files | Refs | README

hello.odin (2340B)


      1 #!/usr/bin/env odin-run
      2 // A script that touches every package. Run it as ./hello.odin once odin-run
      3 // is installed, or with `just example`.
      4 package main
      5 
      6 import "core:fmt"
      7 import "core:log"
      8 import "core:time"
      9 
     10 import "jm:http"
     11 import "jm:path"
     12 import "jm:prelude"
     13 import "jm:sh"
     14 import "jm:sqlite3"
     15 import "jm:timefmt"
     16 
     17 must :: prelude.must
     18 die  :: prelude.die
     19 
     20 main :: proc() {
     21 	context = prelude.init()
     22 	log.infof("started at %s", timefmt.local(time.now(), "%H:%M:%S %Z", context.temp_allocator))
     23 
     24 	// Shell: a string through the platform shell, or argv without quoting.
     25 	shell := "cmd" when ODIN_OS == .Windows else "sh"
     26 	shell_path := must(sh.which(shell))
     27 	fmt.println("shell:", shell_path)
     28 	fmt.println("echo:", must(sh.out("echo hello from the shell")))
     29 	r := sh.exec({shell_path, "-c" if ODIN_OS != .Windows else "/C", "exit 2"})
     30 	if !r.ok {
     31 		log.warnf("expected failure: %s", sh.error(r, context.temp_allocator))
     32 	}
     33 
     34 	// Files: a scratch tree, written and read back.
     35 	scratch := must(path.temp_dir("hello-"))
     36 	defer path.remove_all(scratch)
     37 	note := path.join(scratch, "notes", "today.txt")
     38 	must(
     39 		path.write(
     40 			note,
     41 			fmt.tprintf("written %s\n", timefmt.iso(time.now(), context.temp_allocator)),
     42 		),
     43 	)
     44 	for line in must(path.read_lines(note)) {
     45 		fmt.println("note:", line)
     46 	}
     47 	fmt.println("files:", len(must(path.walk(scratch))))
     48 
     49 	// SQLite: a database in the scratch tree, written and read back.
     50 	db := must(sqlite3.open(path.join(scratch, "hello.db")))
     51 	defer sqlite3.close(&db)
     52 	must(sqlite3.exec(db, `CREATE TABLE note(at TEXT, body TEXT)`))
     53 	must(
     54 		sqlite3.exec_args(
     55 			db,
     56 			`INSERT INTO note VALUES (?, ?)`,
     57 			timefmt.iso(time.now(), context.temp_allocator),
     58 			"it isn't interpolated",
     59 		),
     60 	)
     61 	rows := must(sqlite3.query(db, `SELECT at, body FROM note`))
     62 	defer sqlite3.finish(&rows)
     63 	for sqlite3.next(&rows) {
     64 		fmt.println("note:", sqlite3.text(rows, 0), sqlite3.text(rows, 1))
     65 	}
     66 	fmt.println("sqlite:", sqlite3.version())
     67 
     68 	// HTTP: skipped without HELLO_URL so the example runs offline.
     69 	if url := prelude.env("HELLO_URL"); url != "" {
     70 		res := must(http.get(url, {timeout = 10 * time.Second}))
     71 		fmt.printf("GET %s -> %d, %d bytes\n", url, res.status, len(res.body))
     72 	}
     73 
     74 	if len(prelude.args()) > 0 && prelude.args()[0] == "die" {
     75 		die("asked to die")
     76 	}
     77 	fmt.println("log:", prelude.log_path())
     78 }