Reference

Command line

Every osl command, its usage line and its flags, with an example of each, plus the environment variables the compiler reads.

osl is one program that runs, builds, tests, formats and inspects OSL code. This page lists every command and flag in OSL 9.3.0. Run osl with no arguments (or osl help) for the short summary, and osl version for the installed version.

Terminal
osl <command> [options]

Most commands have no --help: given the wrong arguments they print their usage line, and that is the line shown under each command below. Only bench and lsp accept -h.

CommandWhat it does
runCompile a program and run it
compileBuild a native executable
testRun test blocks and .test.osl files
opalManage projects and packages
fmtFormat source files
fixApply automatic fixes
transpilePrint the Go code a program compiles to
asmPrint the Go assembly a program compiles to
astPrint the syntax tree as JSON
lspRun the language server, or check a file
benchProfile a program
packagePrint the source of a standard package
cacheInspect or clear the build cache
setup, update, uninstall, versionInstall, update and remove OSL

Exit codes#

CodeMeaning
0Success
1The command failed: a compile error, a failed test, a file that could not be read
2Wrong arguments or an unknown command

osl run is different: it returns the exit status of the program it ran. When the program is killed by a signal, run returns 128 plus the signal number, as a shell does.

Options that work everywhere#

FlagEffect
--all-warningsPrint every warning, including pedantic ones. Accepted by every command.
-v, --verboseShow the time each compiler stage takes. Accepted by the build commands, fix, lsp check and update.
--no-cacheSkip the compiler's caches for this command (see cache). Accepted by run, compile, transpile and asm.

Without --all-warnings, the build commands print at most 20 warnings and count the rest. See Diagnostics for what each warning means.

run#

Compiles a program to a temporary executable, runs it, and deletes it. The program's working directory is the folder of the source file.

Terminal
osl run <file.osl> [--no-cache] [-v|--verbose] [-- program args]
FlagEffect
--no-cacheRebuild everything instead of reusing cached results.
-v, --verbosePrint the timing of each stage.
--Everything after it goes to the program, readable with process.args().

test blocks are left out of the program.

Terminal
osl run hello.osl
osl run server.osl -- --port 8080

compile#

Builds a native executable you can copy to another machine of the same operating system and architecture. It needs no OSL installed to run.

Terminal
osl compile <file.osl> [-o <output>] [--no-cache] [--no-write] [--optimise]
            [-v|--verbose] [-- program args]
FlagEffect
-o <output>Name or path of the executable. Without it, the file name without .osl, next to the source.
--no-writeCheck that the program compiles, and write nothing. Fast, and a good CI check.
--optimise, --optimizeProfile-guided build: runs the program under the bench harness, collects a CPU profile, then rebuilds so the Go toolchain can optimise what the program really does.
--no-cacheRebuild everything.
-v, --verbosePrint the timing of each stage.
--Arguments for the program. With --optimise, they are passed on every profiling run.
Terminal
osl compile todo.osl -o todo
osl compile todo.osl --no-write
osl compile server.osl --optimise -- --self-test

test#

Finds and runs the tests under the paths you give (the current folder when you give none). It takes no flags. Testing covers the test blocks, the output and the exit codes.

Terminal
osl test [path ...]
Terminal
osl test
osl test src/
osl test src/pricing.osl

opal#

Opal is the package manager. osl opal <command> and the opal program run the same code. Opal lists every subcommand.

Terminal
osl opal <command> [options]
Terminal
osl opal init
osl opal add someone/some-package

fmt#

Rewrites source files in the canonical style: two-space indentation, tight call parentheses, a blank line between declarations. It leaves a file untouched when it does not parse, and never changes what a program means. A directory is searched recursively. It prints the path of every file it checked.

Terminal
osl fmt <file-or-directory> [...]
Terminal
osl fmt src/
osl fmt main.osl lib/

fix#

Applies the fixes the editor offers as quick fixes, and rewrites old syntax the compiler no longer accepts (old type declarations, reserved names used as variables, old lambdas and string escapes, and the functions that became methods, such as sqrt(x) and keys(o)). It repeats until nothing more changes, up to 8 rounds, and prints the files it changed.

Terminal
osl fix <file-or-directory> [...] [-v|--verbose]
FlagEffect
-v, --verboseLog one line for every file checked.
Terminal
osl fix .
osl fix main.osl -v

transpile#

Prints the Go program that a file compiles to. Useful to see what the compiler does, or to report a bug.

Terminal
osl transpile <file.osl> [--no-cache] [--explain-ownership] [-v|--verbose] [-o <file>]
FlagEffect
-o <file>, --output, --outWrite the Go source to a file instead of standard output. Runtime files the program needs are written next to it.
--explain-ownershipPrint, on standard error, why the compiler copies or shares values. This turns the cache off for the run.
--no-cacheSkip the cache.
-v, --verbosePrint the timing of each stage.

Only the functions and methods a program reaches are included, so the output stays small.

Terminal
osl transpile main.osl
osl transpile main.osl -o out/main.go

asm#

Prints the Go assembly the program compiles to. Each instruction names the OSL line it came from, so you can see how a statement was lowered. The output is large: write it to a file.

Terminal
osl asm <file.osl> [-o <file>] [--no-cache] [-v|--verbose]
FlagEffect
-o <file>Write the assembly to a file instead of standard output.
--no-cacheSkip the cache.
-v, --verbosePrint the timing of each stage.
Terminal
osl asm hot.osl -o hot.s

ast#

Prints the parsed syntax tree of one file as JSON. It parses only: it does not type check.

Terminal
osl ast <file.osl>
Terminal
osl ast main.osl > main.ast.json

lsp#

Starts the language server on standard input and output, for editors. With check, it prints a file's diagnostics, and those of every file it imports, and exits with status 1 if any is an error. Editor support has the details.

Terminal
osl lsp [check <file> [-v|--verbose]]
FormEffect
osl lspRun the language server.
osl lsp check <file>Print the diagnostics for a file, or No diagnostics.
osl lsp check <file> -vThe same, with per-file progress.
osl lsp --versionPrint the version.
Terminal
osl lsp check src/main.osl

bench#

Runs a program repeatedly and reports where it spends time and memory. The program's own log output is discarded while it runs.

Terminal
osl bench <file.osl> [--time 1s] [--runs N] [--top N] [--profile cpu.pprof] [-- program args]
FlagDefaultEffect
--time <duration>, -t1sHow long to keep running the program, such as 500ms or 5s.
--runs <n>, -nby timeRun exactly this many times instead. Use 1 for programs with side effects.
--top <n>15How many hot functions and lines to list.
--profile <file>noneAlso save the CPU profile, for Go's pprof tool.
--Arguments for the program, passed on every run.

The report has four parts:

  • CPU self time splits samples between generated OSL and runtime code, the Go runtime, reflection, and system calls.
  • Hot generated functions lists functions by cumulative cost.
  • Hot OSL source lines lists your own lines by self time.
  • Hot allocations comes from one extra run with allocation profiling on, and lists allocation sites by bytes and object count.
Terminal
osl bench sort.osl --time 3s --top 10
osl bench fetch.osl --runs 1 -- https://example.com

package#

Prints the source of a standard package, with the header that lists what it needs. With no name, it lists the packages. For a family such as encodings, it lists the members.

Terminal
osl package [name]
Terminal
osl package
osl package fs
osl package std:json

cache#

The compiler stores compiled programs, module snapshots and generated workspaces so the second build of anything is fast. The cache lives in the user cache folder, under osl.

Terminal
osl cache status
osl cache clean
SubcommandEffect
statusPrint the location, the schema version, the size and the number of artifacts of each kind.
cleanDelete the cache. The next build is slow while Go compiles OSL's runtime again.

Installation commands#

Terminal
osl setup
osl update [-v|--verbose]
osl uninstall
osl version
CommandEffect
setupInstall the running binary as both osl and opal, and create Opal's command folder. This is the last step when building from source.
updateDownload the installer and install the newest release. -v shows its progress.
uninstallRemove the osl and opal binaries with sudo rm. Packages installed globally with Opal are kept. On Windows it tells you to delete them by hand.
versionPrint the version, also available as osl -v and osl --version.

Environment variables#

VariableEffect
OSL_CACHE_DIRUse this folder for the cache instead of the user cache folder.
OSL_CACHE_DISABLE=1Turn the persistent cache off.
OSL_TEST_JOBSHow many test files osl test runs at once. Default: the number of CPUs, at most 8.
OSL_INSTALL_DIRThe folder osl setup installs into.
NO_COLORPrint diagnostics without colour. Colour is also off when TERM=dumb.
OPAL_HOMEWhere Opal keeps globally installed packages and commands. Default ~/.opal. See Opal.