{"id":13757438,"url":"https://github.com/fugue/fregot","last_synced_at":"2025-12-25T14:26:27.965Z","repository":{"id":38711684,"uuid":"169977572","full_name":"fugue/fregot","owner":"fugue","description":"Fugue Rego Toolkit","archived":false,"fork":false,"pushed_at":"2022-06-30T13:38:28.000Z","size":2372,"stargazers_count":234,"open_issues_count":10,"forks_count":11,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-05-10T05:34:08.668Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fugue.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null}},"created_at":"2019-02-10T12:48:49.000Z","updated_at":"2025-04-20T09:02:43.000Z","dependencies_parsed_at":"2022-07-16T10:01:13.427Z","dependency_job_id":null,"html_url":"https://github.com/fugue/fregot","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/fugue/fregot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fugue%2Ffregot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fugue%2Ffregot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fugue%2Ffregot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fugue%2Ffregot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fugue","download_url":"https://codeload.github.com/fugue/fregot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fugue%2Ffregot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28031124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-25T02:00:05.988Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T12:00:38.266Z","updated_at":"2025-12-25T14:26:27.920Z","avatar_url":"https://github.com/fugue.png","language":"Haskell","funding_links":[],"categories":["Other Awesome Lists","Haskell","Tools and Utilities"],"sub_categories":["Open Policy Agent (OPA)","Serverless Blogs and Articles","Testing Blogs and Articles"],"readme":"fregot\n======\n\n`fregot` (**F**ugue **Rego** **T**oolkit) is a set of tools for working with the\n[Rego] policy language, which is part of the Open Policy Agent (OPA) policy\nengine.  `fregot` allows you to easily evaluate expressions, debug code, test\npolicies, and more.\n\n[![Demo: debugging with fregot](examples/break_example/break_example.gif)](https://asciinema.org/a/AfmqS0xB2g5ZuORW4siesYFRY?size=medium)\n\n[(Check out the text-based demo on asciinema so you can copy/paste commands.)](https://asciinema.org/a/AfmqS0xB2g5ZuORW4siesYFRY?size=medium)\n\n`fregot` can be seen an alternative REPL to [OPA]'s built-in interpreter.  The\ngoals are a little different -- whereas the OPA agent provides general-purpose\ncomponents and functionality that are particularly useful with Kubernetes,\n`fregot` was developed internally at [Fugue] as a lightweight set of tools to\nenhance the Rego development experience.  It aims to provide:\n\n -  Just the Rego language implementation rather than the full OPA agent\n -  Useful tools to debug Rego queries and modules\n -  Enhanced error messages\n -  Ease of extending and experimenting with different language features\n\nYou can use `fregot` to validate just about any kind of JSON or YAML against Rego\npolicy. For an example of using `fregot` to test a Terraform plan prior to\ndeployment, see the [Example Use Case](#example-use-case).\n\nWe are also actively working on improving the static analyzer to prevent many\nkinds of bugs.\n\nTable of Contents\n--------------------\n\n- [Installation](#installation)\n\t- [Binary - macOS](#binary---macos)\n\t- [Binary - Linux](#binary---linux)\n\t- [From source - any platform](#from-source---any-platform)\n\t\t- [Using stack](#using-stack)\n\t\t- [Using Cabal](#using-cabal)\n- [Usage](#usage)\n\t- [fregot repl](#fregot-repl)\n\t- [fregot test](#fregot-test)\n\t- [fregot bundle](#fregot-bundle)\n\t- [fregot eval](#fregot-eval)\n\t- [fregot capabilities](#fregot-capabilities)\n\t- [Global options](#global-options)\n- [REPL](#repl)\n\t- [The open package](#the-open-package)\n\t- [Debugging](#debugging)\n\t\t- [Step 1: Set breakpoint](#step-1-set-breakpoint)\n\t\t- [Step 2: Activate breakpoint](#step-2-activate-breakpoint)\n\t\t- [Step 3: Execute other debugging commands](#step-3-execute-other-debugging-commands)\n- [REPL Usage](#repl-usage)\n\t- [:break](#break)\n\t- [:help](#help)\n\t- [:input](#input)\n\t- [:open](#open)\n\t- [:quit](#quit)\n\t- [:load](#load)\n\t- [:reload](#reload)\n\t- [:continue](#continue)\n\t- [:step](#step)\n\t- [:next](#next)\n\t- [:rewind](#rewind)\n\t- [:test](#test)\n\t- [:type](#type)\n\t- [:where](#where)\n\t- [:watch](#watch)\n- [Example Use Case](#example-use-case)\n- [macOS Installation Error Message](#macos-installation-error-message)\n- [Additional Reading](#additional-reading)\n\nInstallation\n------------\n\nfregot works on all major platforms. Pre-built binaries are available for [macOS](#binary---macos) and [Linux](#binary---linux). All platforms, including Windows, support installing from [source](#from-source---any-platform).\n\n### Binary - macOS\n\n1. Navigate to [Releases] and download the **fregot-{version}-darwin-i386.zip** binary for the latest release.\n\n  - Chrome users: If you see a message that the file \"is not commonly downloaded\n  and may be dangerous,\" select the arrow icon to the right and select \"Keep.\"\n  `fregot` is not dangerous.\n  \n  ![Chrome warning message](extra/readme-install-chrome.png)\n\n2. Unzip the downloaded file.\n3. `cd` into the `fregot-{version}-darwin-i386` directory you just unzipped.\n4. Move the `fregot` binary to a location in your `$PATH`, such as `/usr/local/bin`:\n\n       mv fregot /usr/local/bin\n       \n5. Run `fregot`:\n\n       fregot\n\n\nIf you get an error message that the application cannot be opened, see [these instructions](#macos-installation-error-message).\n\n### Binary - Linux\n\n1. Navigate to [Releases] and download the **fregot-{version}-linux-x86_64.tar.gz** binary for the latest release.\n2. Unzip the downloaded file.\n3. `cd` into the `fregot-{version}-linux-x86_64` directory you just unzipped.\n4. Move the `fregot` binary to a location in your `$PATH`, such as \n`/usr/local/bin`:\n\n        sudo mv fregot /usr/local/bin\n\n5. Run `fregot`:\n\n        fregot\n\n### From source - any platform\n\nInstallation through source is done using standard Haskell tooling -- [Cabal]\nand [stack] both work well.\n\n#### Using stack\n\n1.  Install [stack] for your platform.\n2.  Clone this repository and `cd` into it.\n3.  Run `stack install`.\n4.  Make sure `$HOME/.local/bin` is in your `$PATH`.\n\n#### Using Cabal\n\n1.  Install [Cabal] for your platform.\n2.  Clone this repository and `cd` into it.\n3.  Run `cabal install`.\n4.  Make sure `$HOME/.cabal/bin` is in your `$PATH`.\n\nUsage\n-----\n\n    fregot v0.13.0\n\n    Usage: fregot COMMAND\n\n    Available options:\n      -h,--help                Show this help text\n      --dump TAG               Dump debug information\n      --format FORMAT          Format for error messages and diagnostics\n\n    Available commands:\n      repl                     Run fregot repl\n      test                     Run tests in .rego files\n      bundle                   Bundle .rego files\n      eval                     Evaluate a rego expression\n      capabilities             Print the capabilities document\n\n`fregot` understands a number of subcommands and [global options](#global-options).  See details\nand examples below.\n\n### fregot repl\n\n`fregot repl [PATHS] [--input PATH] [--watch]`: Start a REPL. Optionally, use\nthe `--input [PATH]` flag to specify [input](#input) and the `--watch` flag to\nenable [watching files](#watch). See [working with the REPL](#repl) for details\nand examples.\n\n### fregot test\n\n`fregot test [PATHS]`: Run tests.  `fregot` will recursively look for Rego files\nin the given paths and run any rule starting with `test_`.\n\n    Usage: fregot test PATHS\n      Run tests in .rego files\n\n    Available options:\n      PATHS                    Rego files or directories to test\n\n_Tip: You can run this command yourself from the root of this repo!_\n\nThis command runs all rules starting with `test_` in `ami_id.rego`:\n\n    fregot test examples/ami_id/ami_id.rego\n\nYou'll see a count of passed, failed, and errored tests:\n\n    passed: 2, failed: 0, errored: 0\n\nTake a look at `examples/ami_id/ami_id.rego` to see test examples.\n\n_Tip: You can also test Rego files from within the [REPL](#repl) using the\n`:test` command. See [`:test`](#test) for details._\n\n### fregot bundle\n\n`fregot bundle [PATHS]`: Compile a number of Rego files into a single bundle\nthat can be loaded faster than individual files.  Experimental.  Note that we\ncurrently use a different bundle format from [OPA].\n\n    Usage: fregot bundle (-o|--output BUNDLE) PATHS\n      Bundle .rego files\n\n    Available options:\n      -o,--output BUNDLE       Path of output file\n      PATHS                    Rego files or directories to bundle\n\n### fregot eval\n\n`fregot eval [--input PATH] EXPRESSION [PATHS]`: Evaluate a Rego expression in a\npolicy file using a JSON file as input.\n\n    Usage: fregot eval [-i|--input PATH] EXPRESSION [PATHS]\n      Evaluate a rego expression\n\n    Available options:\n      -i,--input PATH          Input filepath\n      EXPRESSION               Rego expression to evaluate\n      PATHS                    Rego files or directories to load\n\n_Tip: You can run this command yourself from the root of this repo!_\n\nThis command evaluates the `data.fregot.examples.ami_id.allow` expression from\n`ami_id.rego` using the input file `repl_input.json`:\n\n    fregot eval \\\n        --input examples/ami_id/repl_input.json \\\n        'data.fregot.examples.ami_id.allow' \\\n        examples/ami_id/ami_id.rego\n\nYou'll see the value of the expression in the output:\n\n    [true]\n\nNote that the expression argument should be formatted as `data.package.rule`\naccording to the package and rule name in the Rego file.\n\n### fregot capabilities\n\n`fregot capabilities`: Print the capabilities document. This document lists all\nsupported built-in functions with their arguments and types:\n\n    {\n      \"builtins\": [\n        {\n          \"decl\": {\n            \"args\": [\n              {\n                \"type\": \"number\"\n              }\n            ],\n            \"result\": {\n              \"type\": \"number\"\n            },\n            \"type\": \"function\"\n          },\n          \"name\": \"abs\"\n        },\n        (etc.)\n\n### Global options\n\n`fregot` supports the following global options:\n\n- `-h,--help` shows `fregot` help text\n- `--dump TAG` is used to dump debug information\n- `--format FORMAT` sets the format for error messages and diagnostics; values:\n`text` or `json`\n- `-v,--verbosity VALUE` determines how verbose `fregot` output is; values: `0`\n(quiet) or `1` (default)\n\nREPL\n----\n\n    F u g u e   R E G O   T o o l k i t\n    fregot v0.13.0 repl - use :help for usage info\n    repl% :help\n    Enter an expression to evaluate it.\n    Enter a rule to add it to the current package.\n\n    Other commands:\n      :break     Set or remove a breakpoint\n      :help      show this info\n      :input     set the input document\n      :open      open a different package, e.g. `:open foo`\n      :quit      exit the repl\n      :load      load a rego file, e.g. `:load foo.rego`\n      :reload    reload modified rego files\n      :continue  continue running the debugged program\n      :step      step (into) the next rule in the debugged program\n      :next      step (over) the next rule in the debugged program\n      :rewind    go back to the previous debug suspension\n      :test      run tests in the current package\n      :type      print the type of a term\n      :where     print your location\n      :watch     evaluate input after file changes\n\n    Shortcuts are supported for commands, e.g., `:l` for `:load`.\n\nThe REPL is currently the most important part of `fregot`.  After loading the\nfiles passed on the command line, you end up on an interactive prompt.\n\nThere are three ways to interact with the REPL:\n\n 1. Entering a rule adds the rule to the currently open package, e.g.:\n\n        repl% numbers = {4, 8, 15, 16, 23, 42}\n        Rule numbers added\n\n 2. Entering a query evaluates that query, e.g.:\n\n        repl% numbers[n]; n % 2 == 0; n\n        = 4\n        | n = 4\n        = 16\n        | n = 16\n        = 8\n        | n = 8\n        = 42\n        | n = 42\n\n 3. There are number of special commands that start with `:`.  Entering [`:help`](#help)\n    shows you the full list of commands.\n\n        repl% :quit\n\nSee [REPL Usage](#repl-usage) for details and examples for each command.\n\n### The open package\n\nThe REPL has the concept of an open package, indicated by the prompt.  Initially\nthis is `repl`, but you can change this using [`:open`](#open).  For example,\nwe can add a rule to the package `foo` and change back to `repl`:\n\n    repl% :open foo\n    Warning: package foo contains no rules\n    foo% a = 1\n    Rule a added\n    foo% :open repl\n    repl% data.foo.a\n    = 1\n\nA typical workflow is to have an editor open as well as a `fregot repl`.  You\ncan then load the file using [`:load`](#load), which automatically opens the\npackage:\n\n    repl% :load policy.rego\n    Loading policy.rego...\n    Loaded package policy\n    policy%\n\nOnce you make changes to the file, just reload it using [`:reload`](#reload),\nwhich reloads all modified Rego files.  If the file includes any rules starting\nwith `test_`, you can assess your changes using [`:test`](#test), like so:\n\n    policy% :reload\n    Reloaded policy.rego\n    policy% :test\n    passed: 1, failed: 0, errored: 0\n\n### Debugging\n\nDebugging generally follows these steps:\n\n 1. Set one or more breakpoints with [`:break`](#break)\n 2. Evaluate an expression that activates the breakpoint\n 3. Use other debugging commands to [step into](#step), [step over](#next),\n    [rewind](#rewind), [print location](#where), or [continue to the next\n    breakpoint](#continue)\n\n#### Step 1: Set breakpoint\n\nYou can start debugging by setting a breakpoint with [`:break`](#break) and then\nevaluating something.\n\nTo set a breakpoint, use the `:break` command. The command below sets a\nbreakpoint on the rule `deny` in the currently loaded package,\n`fregot.examples.demo`:\n\n    fregot.examples.demo% :break deny\n    Set breakpoint at fregot.examples.demo.deny\n\nYou can use the `:break` command\nwith either names, or a position in a file (line number).  For example:\n\n    :break foo            # `foo` in the current package\n    :break repl.foo       # `foo` in the package repl\n    :break data.repl.foo  # Same as above\n    :break foo.rego:9     # Line 9 of `foo.rego`\n\nOnce at least one breakpoint is set, you can use `:break` without arguments to\ndisplay the list. You'll see output like this:\n\n    fregot.examples.demo.test_allow\n    examples/demo/demo.rego:9\n    fregot.examples.demo.deny\n\nYou can also use `:break` on an existing breakpoint to remove it again:\n\n    fregot.examples.demo% :break deny\n    Removed breakpoint at fregot.examples.demo.deny\n\n#### Step 2: Activate breakpoint\n\nNext, evaluate an expression that activates the breakpoint.  If the `repl`\npackage is already loaded and the breakpoint is set on `foo`, we can just\nevaluate `foo`:\n\n    %repl foo\n\n#### Step 3: Execute other debugging commands\n\nOnce the breakpoint is activated, you end up in a _debugging context_.  From\nhere, you can do a number of things:\n\n -  Enter a query to evaluate in the _current context_: meaning that you can\n    print and evaluate local variables that are in scope.\n -  Use [`:continue`](#continue) to continue to the next breakpoint.\n -  Use [`:step`](#step) and [`:next`](#next) to step into and over the next query,\n    respectively.\n -  Use [`:rewind`](#rewind) to go _back_ to the last step.\n -  Use [`:where`](#where) to see your current location.\n -  Use [`:quit`](#quit) to exit debugging mode. Use `:quit` again to exit the REPL.\n\n#### Debugging notes\n\n -  By default, `fregot` turns off optimizations when debugging.  This allows\n    you to more naturally follow what the code is doing.  However, this may get\n    in your way when trying to debug complex queries that take too long to\n    execute without optimizations.\n\n    To explicitly turn on optimizations (even while debugging), use\n    `fregot repl -O`.\n\nREPL Usage\n----------\n\n### :break\n\n`:break [location]` sets a breakpoint.  For example, the command below sets a\nbreakpoint at the `allow` rule in the package `fregot.examples.ami_id`:\n\n    repl% :break fregot.examples.ami_id.allow\n    Set breakpoint at fregot.examples.ami_id.allow\n\nTo enter debugging mode, make sure you've loaded the package with [`:load`](#load), and\nactivate the breakpoint by entering the rule name:\n\n    fregot.examples.ami_id% allow\n\nThe REPL displays the code at the breakpoint, along with the line number:\n\n    fregot.examples.ami_id% allow\n    23|     count(unapproved_amis) == 0\n            ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe REPL prompt then includes the word `debug`, allowing you to enter [other\ndebugging commands](#step-3-execute-other-debugging-commands):\n\n    fregot.examples.ami_id(debug)%\n\nEntering `:break` by itself displays a list of breakpoints:\n\n    repl% :break\n\nYou'll see output like this:\n\n    fregot.examples.ami_id.allow\n    examples/ami_id/ami_id.rego:9\n\nSee [Step 1: Set breakpoint](#step-1-set-breakpoint) for more info.\n\n#### Evaluating local variables\n\nOnce you've loaded a file, activated a breakpoint, and entered debugging mode,\nyou can evaluate queries in the current context -- including printing and\nevaluating local variables.\n\nFor example, if you look at\n[break_example.rego](./examples/break_example/break_example.rego), you'll see\nthat `function_a` has the local variable `a`:\n\n    function_a {\n      a = \"Welcome to function a!\"\n      true\n    }\n\nIf you load the Rego file and try to evaluate `a` without setting a breakpoint\nfirst, you'll get an error message that the variable is not in scope:\n\n    fregot.examples.break_example% a\n\n    fregot (compile error):\n      \"a\" (line 1, column 1):\n      unknown variable:\n\n        1| a\n           ^\n\n      Undefined variable: a\n\nHowever, if you set a breakpoint at `function_a`, activate it, and\n[`:step`](#step) into it, you can see the value of `a`:\n\n    fregot.examples.break_example% :break function_a\n    Set breakpoint at fregot.examples.break_example.function_a\n\n    fregot.examples.break_example% function_a\n\n    4|   a = \"Welcome to function a!\"\n         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n    fregot.examples.break_example(debug)% :step\n\n    5|   true\n         ^^^^\n\n    fregot.examples.break_example(debug)% a\n    = \"Welcome to function a!\"\n\n### :help\n\n**Shortcut** `:h`\n\n`:help` displays help text for the REPL. See [REPL](#repl) for more information.\n\n### :input\n\nWhile in the REPL, you can directly change the input document by using the\n`:input` command to specify the path of your input document. Input can be\nJSON or YAML.\n\nFor example, if you want to load the input in `example.json`, you would do this:\n\n    repl% :input example.json\n\nThe command returns no output unless there is an error.\n\nAfter you've set the input, you can enter `input` without colon or argument to\nprint the input document to the screen:\n\n    repl% input\n    = {\"user\": \"alice\"}\n\nTwo things to note:\n\n -  The home directory shortcut `~` is not currently supported, so use the\n    absolute path instead; e.g., `/Users/alice/input.json`\n\n -  If you change the input document, make sure to update it by issuing the\n    [`:reload`](#reload) command. (Or, if you've enabled [`--watch`](#watch) mode,\n    the REPL will reload the changes automatically!)\n\nYou can also set the input when you start the REPL with the `--input PATH` flag:\n\n    fregot repl examples/ami_id/ami_id.rego --input input.json\n\n### :open\n\n**Shortcut** `:o`\n\nBy default, you start in the `repl` package when you run `fregot repl`.  `:open`\nallows you to switch between packages in files you've [loaded](#load). For\nexample, you can switch to `fregot.examples.ami_id` like so:\n\n    repl% :open fregot.examples.ami_id\n\nThe REPL prompt changes to the name of the package you just loaded:\n\n    fregot.examples.ami_id%\n\nTo change to another package (or return to the `repl` package), you can run\n`:open [PACKAGE]`.\n\nFor more information, see [The open package](#the-open-package).\n\n### :quit\n\n**Shortcut** `:q`\n\n`:quit` exits debugging mode if you're in debugging mode, and exits the REPL if\nyou're not:\n\n    repl(debug)% :quit\n    \n    repl% :quit\n\n### :load\n\n**Shortcut** `:l`\n\n`:load [PATH]` loads a Rego file and automatically opens the package. For\nexample:\n\n    repl% :load examples/ami_id/ami_id.rego\n\nYou'll see output like this:\n\n    Loaded package fregot.examples.ami_id\n\nOnce the file is loaded, you can debug it with [other commands](#repl-usage).\nYou can also enter rules or expressions to evaluate them.  For example, this\ncommand returns the value of the rule `allow` in the loaded Rego file:\n\n    fregot.examples.ami_id% allow\n\nYou'll see output like this:\n\n    = true\n\nTip: You can skip the `:load` step by specifying the Rego file paths when you\nstart the REPL:\n\n    fregot repl my_policy_1.rego my_policy_2.rego\n\nDirectories are searched recursively. This command opens all the Rego files in\nthe `examples` folder:\n\n    fregot repl examples\n\n_Note: If you change the Rego file after you've loaded it, you'll need to\n[`:reload`](#reload) it. However, if you've enabled [`--watch`](#watch) mode,\nthe REPL automatically reloads your changes._\n\n### :reload\n\n**Shortcut** `:r`\n\n`:reload` checks for modified Rego files and reloads them.  If you make changes\nto a loaded file, you can `:reload` it to update it in the REPL.\n\n    fregot.examples.ami_id% :reload\n\nYou'll see output like this:\n\n    Reloaded input.json\n    Reloaded examples/ami_id/ami_id.rego\n\nFor automatic reloading, see [`--watch`](#watch).\n\nNote that reloading when debugging is not possible as it would modify the code\ncurrently running.\n\n### :continue\n\n`:continue` continues to the next breakpoint:\n\n    fregot.examples.ami_id(debug)% :continue\n\nThe REPL displays the code at the next breakpoint, along with the line number.\n\nIn the following example, we set a breakpoint at `test_step` and at\n`function_a` (see\n[break_example.rego](./examples/break_example/break_example.rego)), activate the\n`test_step` breakpoint, then use the `:continue` command:\n\n    fregot.examples.break_example% :break test_step\n    Set breakpoint at fregot.examples.break_example.test_step\n    fregot.examples.break_example% :break function_a\n    Set breakpoint at fregot.examples.break_example.function_a\n    fregot.examples.break_example% test_step\n    14|   function_a\n          ^^^^^^^^^^\n    fregot.examples.break_example(debug)% :continue\n    4|   a = \"Welcome to function a!\"\n         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf there are no more breakpoints, the program finishes running and you'll see\nthe validation results and `(debug) finished`:\n\n    (debug) = true\n    (debug) finished\n\n### :step\n\n**Shortcut** `:s`\n\n`:step` steps _into_ the next rule in the debugged program:\n\n    fregot.examples.break_example(debug)% :step\n\nThe REPL displays the next query, along with the line number.\n\nIn the following example, we activate the breakpoint `test_step`, then use the\n`:step` command once to step into `function_a`, and a second time to step into\nthe next query in `function_a`:\n\n    fregot.examples.break_example% test_step\n    14|   function_a\n          ^^^^^^^^^^\n    fregot.examples.break_example(debug)% :step\n    4|   a = \"Welcome to function a!\"\n         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    fregot.examples.break_example(debug)% :step\n    5|   true\n         ^^^^\n\nIf there are no more queries, you'll see the results of the validation and the\noutput `(debug) finished`:\n\n    (debug) = true\n    (debug) finished\n\n### :next\n\n**Shortcut** `:n`\n\n`:next` steps _over_ the next rule in the debugged program:\n\n    fregot.examples.break_example% :next\n\nThe REPL skips to the next complete rule and displays the line number.\n\nIn the following example, we activate the breakpoint `test_step`, then use the\n`:next` command to jump to the next rule, `function_b`:\n\n    fregot.examples.break_example% test_step\n    14|   function_a\n          ^^^^^^^^^^\n    fregot.examples.break_example(debug)% :next\n    15|   function_b\n          ^^^^^^^^^^\n\n### :rewind\n\n`:rewind` goes back to the previous debug suspension -- it \"rewinds\" back to the\nmost recent [`:step`](#step) or [`:next`](#next) command.\n\nIn the following example, we `:step` into `function_a`, `:step` into the next\nquery, and then `:rewind` back to `function_a` (the previous query):\n\n    fregot.examples.break_example(debug)% :step\n    4|   a = \"Welcome to function a!\"\n         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    fregot.examples.break_example(debug)% :step\n    5|   true\n         ^^^^\n    fregot.examples.break_example(debug)% :rewind\n    4|   a = \"Welcome to function a!\"\n         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe history that you can rewind is currently limited to 10 steps.\n\n### :test\n\n**Shortcut** `:t`\n\n`:test` runs tests in the current package.  This is similar to the\n[`fregot test`](#fregot-test) command, but is scoped to a package rather than\nrecursive directories.\n\nFor a more detailed example, check out\n[ami_id.rego](./examples/ami_id/ami_id.rego) and compare it to\n[test_ami_id.rego](./examples/ami_id/test_ami_id.rego).  `:test` only runs the\ntwo tests in `ami_id.rego`:\n\n    fregot.examples.ami_id% :test\n    passed: 2, failed: 0, errored: 0\n\nOn the other hand, `fregot test` searches recursively through the given\ndirectory and includes the 2 tests in `ami_id.rego` _and_ the 8 tests from\n`test_ami_id.rego` for a total of 10 tests:\n\n    fregot test examples/ami_id/\n    passed: 10, failed: 0, errored: 0\n\n### :type\n\n`:type` prints the type of a term in the loaded package:\n\n    fregot.examples.ami_id% :type allow\n    allow : boolean\n\n    fregot.examples.ami_id% :type approved_amis\n    approved_amis : set{string}\n\n### :where\n\n`:where` prints your location in debugging mode using a stack trace:\n\n    fregot.examples.ami_id(debug)% :where\n    23|     count(unapproved_amis) == 0\n            ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n    Stack trace:\n      rule fregot.examples.ami_id.allow at allow:1:1\n\nThis comes in handy when you are stepping into and over rules and want to\ndouble-check your location in the code.\n\n### :watch\n\n**To enable `--watch` mode, you must launch the REPL with `fregot repl \n--watch`. This also allows you to use the `:watch [expression]` command.**\n\nWhen you launch the REPL with `fregot repl --watch`, the REPL monitors loaded\npackage and input files for changes and live-reloads them. You can also use the\n`:watch data.package.rule` command to monitor an expression, and `fregot` will\nautomatically print an updated evaluation when loaded files are changed.\n\nHere's an example. Start the REPL with the `--watch` flag:\n\n    fregot repl --watch\n\nLoad the Rego and input files:\n\n    repl% :load examples/ami_id/ami_id.rego\n    Loading examples/ami_id/ami_id.rego...\n    Loaded package fregot.examples.ami_id\n    fregot.examples.ami_id% :input examples/ami_id/repl_input.json\n\nNow you can make changes to the Rego and/or input files and `fregot`\nautomatically reloads them:\n\n    fregot.examples.ami_id%\n    Reloaded examples/ami_id/ami_id.rego\n    fregot.examples.ami_id%\n    Reloaded examples/ami_id/repl_input.json\n\nThis allows you to evaluate expressions as you like, and they'll automatically\nbe up-to-date.\n\nUse `:watch data.package.rule` to monitor a particular expression:\n\n    fregot.examples.ami_id% :watch data.fregot.examples.ami_id.allow\n\nYou can then make changes to the Rego and/or input file, and `fregot`\nre-evaluates the expression and prints the evaluation:\n\n    fregot.examples.ami_id%\n    Reloaded ami_id.rego\n    = false\n\n    fregot.examples.ami_id%\n    Reloaded repl_input.json\n    = true\n\nExample Use Case\n----------------\n\nYou can use fregot to determine whether a Terraform plan complies with a Rego\npolicy.  Incorporate `fregot` into your CI/CD pipeline to prevent noncompliant\ninfrastructure from being deployed.\n\nSee [examples/ami_id/ami_id.rego](./examples/ami_id/ami_id.rego) for details.\n\nmacOS Installation Error Message\n--------------------------------\n\nOn some versions of macOS, you might see an error message that \"fregot cannot\nbe opened because the developer cannot be verified.\" You can safely run\n`fregot` by taking the following steps:\n\n1. Select \"Cancel\" to dismiss the error message.\n2. In macOS, access System Preferences \u003e Security \u0026 Privacy.\n3. Select the General tab and click the \"Allow Anyway\" button.\n4. Run `fregot` again:\n\n       fregot\n\n5. macOS will ask you to confirm that you want to open it. Select \"Open.\"\n\nYou can now execute `fregot` commands.\n\nAdditional Reading\n------------------\n\nWant to learn more? Check out these resources:\n\n -  [Rego]: OPA's query language for writing policies\n -  [OPA]: the Open Policy Agent\n -  [Policy Reference](https://www.openpolicyagent.org/docs/latest/policy-reference/):\n    a detailed reference for everything you ever wanted to know about Rego\n -  [Policy Cheatsheet](https://www.openpolicyagent.org/docs/latest/policy-cheatsheet/):\n    a quick reference for Rego types, functions, and more\n -  [Rego and Terraform example](https://www.openpolicyagent.org/docs/latest/terraform/):\n    a policy that checks Terraform plans for compliance prior to deployment\n -  [Rego and Kubernetes example](https://www.openpolicyagent.org/docs/latest/kubernetes-introduction/): a tutorial on admission control for Kubernetes using Rego policy\n -  [De Morgan's laws](https://en.wikipedia.org/wiki/De_Morgan%27s_laws):\n    a deep dive into transformation rules useful for writing Rego logic.\n\n[Releases]: https://github.com/fugue/fregot/releases\n[Cabal]: https://www.haskell.org/cabal/\n[Fugue]: https://www.fugue.co/\n[OPA]: https://www.openpolicyagent.org/\n[Rego]: https://www.openpolicyagent.org/docs/latest/policy-language/\n[stack]: https://docs.haskellstack.org/en/stable/README/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffugue%2Ffregot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffugue%2Ffregot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffugue%2Ffregot/lists"}