Skip to content

Commit 7ac4ac5

Browse files
committed
Version 1.1.0
Minor version adding more json builtins and an improved built-in system. This change adds some json builtins and also completely refactors the built-in system to make it more efficient. It also adds some quality of life improvements to the C++ API. The C API remains stable, but the C++ API exposes additional methods to make handling outputs of queries a bit easier. **New Features** - `json.filter`, `json.patch`, and `json.remove` are now available - All built-ins are now accounted for in the built-in system, and those which are not supported are explicitly marked as such. - There is now an `Output` class, which is returned from the new `query_output` method on `Interpreter`. It provides methods which are similar to those available in the C API for inspecting the output of a query. - There are now `try_get_double`, `try_get_string`, and `try_get_bool` methods which will attempt to get raw C++ types from Node objects. - The `whitelist` and `blacklist` methods in `BuiltInsDef` provide fine-grained control over which built-ins are allowed to be loaded. - The `stmt_limit` method on `Interpreter` provides a time-out mechanism (defined as number of statements which the VM is allowed to execute) **Improvements** - The `Interpreter` object can now be created at almost no cost. A large portion of its construction cost was the creation of the `BuiltIns` lookup structure, which now is defined statically in-code. - The test driver can now run all the tests in the OPA test suite and will skip those which use a built-in that is not available in the current implementation. This means we do not have to cherry-pick tests anymore, and will pick up new tests more cleanly. - New methods for creating scalar nodes have been added (`number`, `boolean`, `string`, `null`) and the existing `scalar` methods have been deprecated. **Breaking Changes** - The `get_string` method, which previously returned the raw string of the Trieste node, now tries to get a string from a `JSONString` node and strips it of its quotes (in line with the other `get_*` methods). The previous functionality is available via `get_raw_string`. **Bug Fixes** - Fuzzer bug with `SomeDecl` in a `NotExpr` - An issue with built-ins not being written to binary bundles - A unification bug with variables in comprehensions that had the same name as their module - `regopy` now performs some additional checks to ensure it is loading the correct shared library on all platforms - Ubuntu 22.04 builds are now working again and the image has been added back to the workflow - macos/x86_64 image has been added back to the workflow, and shared library builds (for the Python and dotnet wrappers) - Unification bug with masking scopes and variables with comprehensions and every Signed-off-by: Matthew A Johnson <matjoh@microsoft.com>
1 parent 2ae3d56 commit 7ac4ac5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+10900
-3700
lines changed

CHANGELOG

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,55 @@
11
# Changelog
22

3+
## 2025-10-31 - Version 1.1.0
4+
Minor version adding more json builtins and an improved built-in system.
5+
6+
This change adds some json builtins and also completely refactors the built-in
7+
system to make it more efficient. It also adds some quality of life improvements
8+
to the C++ API. The C API remains stable, but the C++ API exposes additional
9+
methods to make handling outputs of queries a bit easier.
10+
11+
**New Features**
12+
- `json.filter`, `json.patch`, and `json.remove` are now available
13+
- All built-ins are now accounted for in the built-in system, and those which
14+
are not supported are explicitly marked as such.
15+
- There is now an `Output` class, which is returned from the new `query_output`
16+
method on `Interpreter`. It provides methods which are similar to those available
17+
in the C API for inspecting the output of a query.
18+
- There are now `try_get_double`, `try_get_string`, and `try_get_bool` methods
19+
which will attempt to get raw C++ types from Node objects.
20+
- The `whitelist` and `blacklist` methods in `BuiltInsDef` provide fine-grained
21+
control over which built-ins are allowed to be loaded.
22+
- The `stmt_limit` method on `Interpreter` provides a time-out mechanism (defined
23+
as number of statements which the VM is allowed to execute)
24+
25+
**Improvements**
26+
- The `Interpreter` object can now be created at almost no cost. A large portion
27+
of its construction cost was the creation of the `BuiltIns` lookup structure,
28+
which now is defined statically in-code.
29+
- The test driver can now run all the tests in the OPA test suite and will skip
30+
those which use a built-in that is not available in the current implementation.
31+
This means we do not have to cherry-pick tests anymore, and will pick up
32+
new tests more cleanly.
33+
- New methods for creating scalar nodes have been added (`number`, `boolean`,
34+
`string`, `null`) and the existing `scalar` methods have been deprecated.
35+
36+
**Breaking Changes**
37+
- The `get_string` method, which previously returned the raw string of the Trieste
38+
node, now tries to get a string from a `JSONString` node and strips it of its
39+
quotes (in line with the other `get_*` methods). The previous functionality is
40+
available via `get_raw_string`.
41+
42+
**Bug Fixes**
43+
- Fuzzer bug with `SomeDecl` in a `NotExpr`
44+
- An issue with built-ins not being written to binary bundles
45+
- A unification bug with variables in comprehensions that had the same name as their module
46+
- `regopy` now performs some additional checks to ensure it is loading the correct
47+
shared library on all platforms
48+
- Ubuntu 22.04 builds are now working again and the image has been added back to the workflow
49+
- macos/x86_64 image has been added back to the workflow, and shared library builds
50+
(for the Python and dotnet wrappers)
51+
- Unification bug with masking scopes and variables with comprehensions and every
52+
353
## 2025-10-12 - Version 1.0.0
454
Major version adding VM-based execution of bundles.
555

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ FetchContent_Declare(
9999
FetchContent_Declare(
100100
trieste
101101
GIT_REPOSITORY https://github.com/microsoft/trieste
102-
GIT_TAG 67273a5e13b640dd8a9d0eb6a6a3953b543787f0
102+
GIT_TAG main
103103
)
104104

105105
FetchContent_MakeAvailable(cmake_utils)
@@ -242,7 +242,7 @@ if (REGOCPP_COPY_EXAMPLES)
242242
endif()
243243

244244
if (REGOCPP_BUILD_TESTS)
245-
install(TARGETS rego_test rego_test_c_api RUNTIME)
245+
install(TARGETS rego_test rego_test_c_api rego_test_cpp_api RUNTIME)
246246
install(FILES tests/regocpp.yaml tests/bigint.yaml tests/bugs.yaml tests/bad.json DESTINATION tests)
247247
install(DIRECTORY tests/aci DESTINATION tests)
248248
install(DIRECTORY tests/cts DESTINATION tests)

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.0
1+
1.1.0

examples/c/example.c

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int print_error(regoInterpreter* rego)
3838
return REGO_ERROR;
3939
}
4040

41-
buf = malloc(size);
41+
buf = (char*)malloc(size);
4242
err = regoError(rego, buf, size);
4343
if (err == REGO_OK)
4444
{
@@ -57,12 +57,13 @@ int main(void)
5757
regoEnum err;
5858
int rc = EXIT_SUCCESS;
5959
regoOutput* output = NULL;
60+
regoNode* node = NULL;
6061
regoBundle* bundle = NULL;
6162
regoInput* input = NULL;
6263
regoInterpreter* rego = regoNew();
6364
regoSize size = 0;
6465
char* buf = NULL;
65-
const char* bundle_dir = "bundle";
66+
const char* bundle_dir = "example_bundle";
6667
const char* bundle_path = "example.rbb";
6768

6869
err = regoAddModuleFile(rego, "examples/objects.rego");
@@ -101,6 +102,52 @@ int main(void)
101102
goto error;
102103
}
103104

105+
node = regoOutputBinding(output, "x");
106+
if (node == NULL)
107+
{
108+
goto error;
109+
}
110+
111+
size = regoNodeJSONSize(node);
112+
if (size == 0)
113+
{
114+
goto error;
115+
}
116+
117+
buf = (char*)malloc(size);
118+
err = regoNodeJSON(node, buf, size);
119+
if (err != REGO_OK)
120+
{
121+
goto error;
122+
}
123+
124+
printf("x = %s\n", buf);
125+
free(buf);
126+
buf = NULL;
127+
128+
node = regoNodeGet(node, 1); // index
129+
if (node == NULL)
130+
{
131+
goto error;
132+
}
133+
134+
size = regoNodeValueSize(node);
135+
if (size == 0)
136+
{
137+
goto error;
138+
}
139+
140+
buf = (char*)malloc(size);
141+
err = regoNodeValue(node, buf, size);
142+
if (err != REGO_OK)
143+
{
144+
goto error;
145+
}
146+
147+
printf("x[1] = `%s`\n", buf);
148+
free(buf);
149+
buf = NULL;
150+
104151
regoFreeOutput(output);
105152
output = NULL;
106153

@@ -132,6 +179,9 @@ int main(void)
132179
goto error;
133180
}
134181

182+
regoFreeBundle(bundle);
183+
bundle = NULL;
184+
135185
bundle = regoBundleLoad(rego, bundle_dir);
136186

137187
if (bundle == NULL || !regoBundleOk(bundle))
@@ -146,6 +196,9 @@ int main(void)
146196
goto error;
147197
}
148198

199+
regoFreeBundle(bundle);
200+
bundle = NULL;
201+
149202
bundle = regoBundleLoadBinary(rego, bundle_path);
150203

151204
if (bundle == NULL || !regoBundleOk(bundle))
@@ -214,11 +267,26 @@ int main(void)
214267
rc = EXIT_FAILURE;
215268

216269
exit:
270+
if (buf != NULL)
271+
{
272+
free(buf);
273+
}
274+
217275
if (output != NULL)
218276
{
219277
regoFreeOutput(output);
220278
}
221279

280+
if (input != NULL)
281+
{
282+
regoFreeInput(input);
283+
}
284+
285+
if (bundle != NULL)
286+
{
287+
regoFreeBundle(bundle);
288+
}
289+
222290
if (rego != NULL)
223291
{
224292
regoFree(rego);

examples/cpp/custom_builtin.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ int main()
3838
{
3939
Interpreter rego;
4040
rego.builtins()->register_builtin(
41-
bi::BuiltInDef::create(Location("myadd"), add_decl, add));
41+
BuiltInDef::create(Location("myadd"), add_decl, add));
4242
logging::Output() << rego.query("myadd(2, 3)");
4343
}

examples/cpp/example.cc

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,23 @@ f := e["dev"])");
5252
"c": 30.0,
5353
"d": true
5454
})");
55-
std::cout << rego.query("[data.one, input.b, data.objects.sites[1]] = x")
56-
<< std::endl;
55+
56+
auto output =
57+
rego.query_output("[data.one, input.a, data.objects.sites[1]] = x");
58+
std::cout << output.json() << std::endl;
59+
60+
// we can get the value of bindings using the `binding` method on output
61+
auto x = output.binding("x");
62+
// as Rego integer can be arbitrary precision,
63+
// rego-cpp exposes an arbitrary precision integer type
64+
// called BigInt.
65+
rego::BigInt x_1 = rego::try_get_int(x->at(1)).value();
66+
std::cout << "x[1] = " << x_1 << std::endl;
67+
// we can get values from objects using try_get_item
68+
rego::Node x_2 = x->at(2);
69+
std::string x_2_val =
70+
rego::try_get_string(rego::try_get_item(x->at(2), "name").value()).value();
71+
std::cout << "x[2][\"name\"] = " << x_2_val << std::endl;
5772

5873
// if we need to reuse a policy, we can build a bundle and save it for re-use
5974
rego.set_query("[data.one, input.b, data.objects.sites[1]] = x");
@@ -80,10 +95,10 @@ f := e["dev"])");
8095

8196
// we can also assemble the input term manually
8297
rego::Node input = rego::object({
83-
rego::object_item(rego::scalar("a"), rego::scalar(rego::BigInt(10L))),
84-
rego::object_item(rego::scalar("b"), rego::scalar("20")),
85-
rego::object_item(rego::scalar("c"), rego::scalar(30.0)),
86-
rego::object_item(rego::scalar("d"), rego::scalar(true)),
98+
rego::object_item(rego::string("a"), rego::number(10)),
99+
rego::object_item(rego::string("b"), rego::string("20")),
100+
rego::object_item(rego::string("c"), rego::number(30.0)),
101+
rego::object_item(rego::string("d"), rego::boolean(true)),
87102
});
88103

89104
rego.set_input(input);

examples/dotnet/MyPolicy/MyPolicy.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Rego" Version="1.0.0" />
11+
<PackageReference Include="Rego" Version="1.1.0" />
1212
</ItemGroup>
1313

1414
</Project>

examples/dotnet/example/example.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
<Nullable>enable</Nullable>
77
</PropertyGroup>
88
<ItemGroup>
9-
<PackageReference Include="Rego" Version="1.0.0" />
9+
<PackageReference Include="Rego" Version="1.1.0" />
1010
</ItemGroup>
1111
</Project>

examples/rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ edition = "2021"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9-
regorust = { version = "1.0.0" }
9+
regorust = { version = "1.1.0" }
1010
clap = { version = "4.0", features = ["derive"] }

0 commit comments

Comments
 (0)