Sabre v0.4.0
Installing Sabre
Upgrading Sabre
sabre upgradeEnvironment Files
With this release of Sabre, your program will have the capability to load environment files and read/write environment variables of the running process. To use this feature, the --env file flag has been implemented:
# Automatically find a potential ".env" file in you current working directory.
sabre run --env ./script.sabre
# Manually specify a desired environment file (any number of files can be loaded).
sabre run --env .env ./script.sabreTo then read these environment variables at runtime, the sabre:env crate can be used:
import "sabre:env" as Env;
let my_var = Env.get("MY_VAR");
Debug.println("MY_VAR: {0}".fmt(my_var));Note:
Format Flags
Previously the sabre format command used a default configuration when called. Specialized formatting could only be requested through the use of the VSC extension for Sabre. This has now be fixed so that unless specified, files to be formatted will use their parent _crate.jsonc formatting options.
# This will look for a "_crate.jsonc" file in each directory upwards from "script.sabre"
sabre format ./script.sabre
# Otherwise you can manually specify an alternative configuration to the used
sabre format --config ./configs/format.jsonc ./script.sabreTesting Features
Sabre's test runner now has more feature flags and options implemented for improved support.
Bailout After failures
The --bailout flag can be used to abort running tests after a given number of tests fail. By default, Sabre runs all tests and reports all failures, however running testing in a CI it can be preferrable to exit early to reduce usage.
# Exit after exactly 1 failure
sabre test --bailout
# Exit after a given number of failures
sabre test --bailout nnRandomize Execution Order
To run tests in a randomized order, the --randomize or --seed flags can be use. This helps detect tests that rely upon shared state or a particular execution order.
# This will full randomize the execution order and print the "seed" used
sabre test --randomizeTo then reproduce randomization results, the --seed flag can be used. This can be useful to always produce the same randomized test execution order, or run tests in the same order as a previous --randomize run.
# Reproduce a specific randomized run
sabre test --seed 123456Note:
The --seed flag automatically sets the --randomize flag, so only one ever needs to be specified.
Reporting Improvements
Sabre aims to support a variety of reporting formats, both built-in and custom. These can be specified with the --reporter option:
# Explicitly setting a desired reporter
sabre test --reporter textNote:
Currently on the text reporter has been implemented. More to come in the future for other reporter formats.
Additionally, test results can be piped to a desired output using the --outfile option:
# Pipe output to a desired location
sabre test --outfile report.txtBuffer Builtin
To improve performance and simplify the representation of filesystem outputs, the Buffer built has been created. Synonymous with the Buffer object in Node JS, it is a fixed-length sequence of bytes. The reasoning for adding this builtin is to directly map internal buffers from the filesystem or other sources to Sabre. This will help developers by creating a lossless representation of various internal and external buffers. For now it has been created alongside the the sabre:fs crate to directly map to file contents.
// We can simply encode some arbitrary text.
let buffer = Buffer.encode("Hello, World!");
// Then decode it at a later point with an optional encoding.
let text = Buffer.decode(buffer);
// This will then print "Hello, World!" to the console.
Debug.println(text);Filesystem Crate
The sabre:fs crate has had some simple methods implemented to start exposing low-level filesystem operations. This includes the following:
// Get the filesystem crate.
import "sabre:fs" as FS;
// Create a temporary file that can be automictically disposed.
use temporary = FS.temp_file();
// This generates a randomly named temporary file.
Debug.println("Path:", temporary.path());
// We can then verify that the entry exists on the system.
Debug.println("Entry exists:", FS.exists_entry(temporary.path()));
// Or more explicitly that is a file that exists on the system.
Debug.println("File exists:", FS.exists_file(temporary.path()));
// Prepare a desired set of content for the temporary file.
let input = "Content for my temporary file";
// Let's write some arbitrary content to the file.
FS.write_text(temporary.path(), input);
// Or we can write raw buffers directly.
FS.write_file(temporary.path(), Buffer.encode(input));
// Read the buffer of a file is then just as simple.
Debug.println("Buffer:", FS.read_file(temporary.path()));
// Or read the decoded buffer of a file as well.
Debug.println("Value: '{0}'".fmt(FS.read_text(temporary.path())));
// If the file was manually created without resource disposal, it can also be removed manually.
FS.remove_entry(temporary.path());Deference Policy
To further improve the use of explicit resource manager, the ::defer execution policy has been created. This allows creating a Disposable value from a given callback that can be executed at the end of a scope. This is useful for running one-off cleanup handlers or other end-of-scope routines.
// This callback cleans up constructed resources.
let cleanup = fn (value: Any) {
Debug.println("Cleanup Called!");
Debug.println("Input Argument:", value);
};
// Call our callback with the execution policy attached.
use scoped: Disposable = cleanup::defer(42);
// After the scope ends, our bound callback will be called.
Debug.println("Program Running!");Upcoming Work
This release of Sabre started laying further foundations for ongoing builtin crate support, whilst also continuing to maintain correctness and improve developer experience. Following this, the core goals outlined from the previous progress reports still applies. This being to continue to improve developer features to then expand the builtin crates. Keep tuned to the next available progress report for more information!
Bug Fixes
Package / crates
- Moved: Removed the
sabre:codeccrate as it is currently unnecessary.
Package / vscode
- Fixed: The settings open command now correctly opens the user-settings for Sabre.
Package / website
- Added: There is now a
https://sabre.rroessler.io/rss.xmlRSS feed endpoint.
Toolkit / sabre bundle
- Fixed: Removed unnecessary copies of the base binary to be bundled improving bundling speed.
Toolkit / sabre format
- Added: Implemented the
--configoption for defining a common manifest for formatting configuration. - Moved: Removed the
--jsonflag for formatting since it requires diffing of two strings to implement.
Toolkit / sabre run
- Added: Implemented the
--envoption for defining embeddable environment variables. - Fixed: Improved reading speed of files by eliminating an erroneous copy into internal storage.
- Added: Prepared foundations for the
Bufferbuiltin type to be used for fixed-length contiguous sequences of bytes. - Fixed: Commit 2ad55c4 introduced a
nullptrstack reference for jitted functions. This has been reverted. - Fixed: Class members immutability was previously inverted and has now been corrected to match the type-system.
- Added: Implemented the
List.swapmethod for swapping two values by indices in aListvalue. - Added: The internal
Object::Instancevalue now expects keys to be assigned to each field reference value. This will allow for serialization and reflection ofObjectvalues.
Toolkit / sabre serve
- Fixed: Changed LSP analysis to refresh the entire project on changes. Currently a minor bug where partial refreshing does not work.
Toolkit / sabre test
- Added: Implemented the
--seedoption can be used to define a randomization seed for testing. - Added: Implemented the
--randomizeflag can be used to shuffle test ordering for all tests. - Added: Implemented the
--outfileoption for defining a file to pipe testing reports to. - Added: Implemented the
--reporteroption, however only thetextreporter is currently implemented. - Added: Implemented the
--bailoutoption for setting a threshold of test failures to bail at.
Crate / sabre:env
- Added: Prepared the
envcrate for managing the process environment. - Added: Implemented the
getfunction for getting environment variables. - Added: Implemented the
setfunction for setting environment variables. - Added: Implemented the
dropfunction for deleting environment variables.
Crate / sabre:fs
- Moved: Renamed the
fsyscrate tofsfor upcoming work with the builtin crates. - Added: Implemented the
read_filemethod for reading files to aBuffervalue. - Added: Implemented the
read_textmethod for reading files to aStringvalue. - Added: Implemented the
write_filemethod for writing files with aBuffervalue. - Added: Implemented the
write_textmethod for writing files with aStringvalue. - Added: Implemented the
remove_entrymethod for removing entries from the filesystem. - Added: Implemented the
temp_filemethod for generating temporary files. - Added: Implemented the
exists_filemethod for checking a file entry exists. - Added: Implemented the
exists_entrymethod for checking a any filesystem entry exists.
Crate / sabre:os
- Added: Prepared a stub crate for the
oscrate for operating system interface methods.