Skip to content

risor-io/risor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Risor logo Risor

CircleCI Apache-2.0 license Go.Dev reference Go Report Card Releases

Risor is a fast and flexible scripting language for Go developers and DevOps.

Its modules integrate the Go standard library, making it easy to use functions that you're already familiar with as a Go developer.

Scripts are compiled to bytecode and then run on a lightweight virtual machine. Risor is written in pure Go.

Documentation

Documentation is available at risor.io.

You might also want to try evaluating Risor scripts from your browser.

Syntax Example

Here's a short example of how Risor feels like a hybrid of Go and Python. This demonstrates using Risor's pipe expressions to apply a series of transformations:

array := ["gophers", "are", "burrowing", "rodents"]

sentence := array | strings.join(" ") | strings.to_upper

print(sentence)

Output:

GOPHERS ARE BURROWING RODENTS

Getting Started

You might want to head over to Getting Started in the documentation. That said, here are tips for both the CLI and the Go library.

Risor CLI and REPL

If you use Homebrew, you can install the Risor CLI as follows:

brew install risor

Having done that, just run risor to start the CLI or risor -h to see usage information.

Execute a code snippet directly using the -c option:

risor -c "time.now()"

Start the REPL by running risor with no options.

Build and Install the CLI from Source

Build the CLI from source as follows:

git clone [email protected]:risor-io/risor.git
cd risor/cmd/risor
go install -tags aws,k8s,vault .

Go Library

Use go get to add Risor as a dependency of your Go program:

go get github.com/risor-io/risor

Here's an example of using the risor.Eval API to evaluate some code:

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/risor-io/risor"
)

func main() {
	ctx := context.Background()
	script := "math.sqrt(input)"
	result, err := risor.Eval(ctx, script, risor.WithGlobal("input", 4))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("The square root of 4 is:", result)
}

Built-in Functions and Modules

30+ built-in functions are included and are documented here.

Modules are included that generally wrap the equivalent Go package. For example, there is direct correspondence between base64, bytes, filepath, json, math, os, rand, regexp, strconv, strings, and time Risor modules and the Go standard library.

Risor modules that are beyond the Go standard library currently include aws, color, cli, jmespath, pgx, playwright, qrcode, uuid, vault, k8s, and more.

Go Interface

It is trivial to embed Risor in your Go program in order to evaluate scripts that have access to arbitrary Go structs and other types.

The simplest way to use Risor is to call the Eval function and provide the script source code. The result is returned as a Risor object:

result, err := risor.Eval(ctx, "math.min([5, 2, 7])")
// result is 2, as an *object.Int

Provide input to the script using Risor options:

result, err := risor.Eval(ctx, "input | strings.to_upper", risor.WithGlobal("input", "hello"))
// result is "HELLO", as an *object.String

Use the same mechanism to inject a struct. You can then access fields or call methods on the struct from the Risor script:

type Example struct {
    Message string
}
example := &Example{"abc"}
result, err := risor.Eval(ctx, "len(ex.Message)", risor.WithGlobal("ex", example))
// result is 3, as an *object.Int

Optional Modules

Risor is designed to have minimal external dependencies in its core libraries. You can choose to opt into various add-on modules if they are of value in your application. The modules are present in this same Git repository, but must be installed with go get as separate dependencies:

Name Path Go Get Command
aws modules/aws go get github.com/risor-io/risor/modules/aws
bcrypt modules/bcrypt go get github.com/risor-io/risor/modules/bcrypt
cli modules/cli go get github.com/risor-io/risor/modules/cli
color modules/color go get github.com/risor-io/risor/modules/color
gha modules/gha go get github.com/risor-io/risor/modules/gha
goquery modules/goquery go get github.com/risor-io/risor/modules/goquery
htmltomarkdown modules/htmltomarkdown go get github.com/risor-io/risor/modules/htmltomarkdown
image modules/image go get github.com/risor-io/risor/modules/image
isatty modules/isatty go get github.com/risor-io/risor/modules/isatty
jmespath modules/jmespath go get github.com/risor-io/risor/modules/jmespath
k8s modules/kubernetes go get github.com/risor-io/risor/modules/kubernetes
pgx modules/pgx go get github.com/risor-io/risor/modules/pgx
playwright modules/playwright go get github.com/risor-io/risor/modules/playwright
qrcode modules/qrcode go get github.com/risor-io/risor/modules/qrcode
s3fs os/s3fs go get github.com/risor-io/risor/os/s3fs
sched modules/sched go get github.com/risor-io/risor/modules/sched
semver modules/semver go get github.com/risor-io/risor/modules/semver
shlex modules/shlex go get github.com/risor-io/risor/modules/shlex
slack modules/slack go get github.com/risor-io/risor/modules/slack
sql modules/sql go get github.com/risor-io/risor/modules/sql
tablewriter modules/tablewriter go get github.com/risor-io/risor/modules/tablewriter
template modules/template go get github.com/risor-io/risor/modules/template
uuid modules/uuid go get github.com/risor-io/risor/modules/uuid
yaml modules/yaml go get github.com/risor-io/risor/modules/yaml
vault modules/vault go get github.com/risor-io/risor/modules/vault

These add-ons are included by default when using the Risor CLI. However, when building Risor into your own program, you'll need to opt-in using go get as described above and then add the modules as globals in Risor scripts as follows:

import (
    "github.com/risor-io/risor"
    "github.com/risor-io/risor/modules/aws"
    "github.com/risor-io/risor/modules/image"
    "github.com/risor-io/risor/modules/pgx"
    "github.com/risor-io/risor/modules/uuid"
)

func main() {
    source := `"nice modules!"`
    result, err := risor.Eval(ctx, source,
        risor.WithGlobals(map[string]any{
            "aws":   aws.Module(),
            "image": image.Module(),
            "pgx":   pgx.Module(),
            "uuid":  uuid.Module(),
        }))
    // ...
}

Syntax Highlighting

A Risor VSCode extension is already available which currently only offers syntax highlighting.

You can also make use of the Risor TextMate grammar.

Benchmarking

There are two Makefile commands that assist with benchmarking and CPU profiling:

make bench
make pprof

Contributing

Risor is intended to be a community project. You can lend a hand in various ways:

  • Please ask questions and share ideas in GitHub discussions
  • Share Risor on any social channels that may appreciate it
  • Open GitHub issue or a pull request for any bugs you find
  • Star the project on GitHub

Contributing New Modules

Adding modules to Risor is a great way to get involved with the project. See this guide for details.

Community Projects

Discuss the Project

Please visit the GitHub discussions page to share thoughts and questions.

There is also a #risor Slack channel on the Gophers Slack.

Credits

Check CREDITS.md.

License

Released under the Apache License, Version 2.0.

Copyright Curtis Myzie / github.com/myzie.