Skip to content

Commit

Permalink
Structured output proof of concept
Browse files Browse the repository at this point in the history
This introduces an 'event' api where events can be 'emitted' by
commands, which goes through the following pipeline:
 - a set of callbacks are registered with each command (similar to
   script hooks) by name
 - when an event is emitted, one of these names must be provided
 - the data is fed to the registered callback, which returns a `Report`
   which describes how to log and serialize the data
 - this report is taken by the event api and depending on whether the
   structured output flag is set will either
    - serialize the data to json (with a very basic hand rolled encoder)
      and write it to stdout
    - log it with the given `Logger`

The basic structure is as such:

	command.new {
	   name = "my-cool-command",
	   description = ":D",
	   exec = function(): integer
	      event.emit("cool_event", { adjective = "cool" })
	      event.emit("cool_event", { adjective = "neat" })
	      return 0
	   end,
	   events = {
	      cool_event = function(params: {string:any}): event.Report
	         return {
	            log_format = "This is from a %(adjective) event happening",
	            parameters = { adjective = params.adjective },
	         },
	      end,
	   },
	}

Which with unstructured output will produce

	$ cyan my-cool-command
	     Info This is from a cool event happening
	     Info This is from a neat event happening

But with structured output will produce

	$ cyan --structured-output my-cool-command
	{"event":"cool_event","data":{"adjective":"cool"}}
	{"event":"cool_event","data":{"adjective":"neat"}}

This commit adds a little bit of this as a proof of concept to the
current build command, but not for everything that `build` can log.
But running

	$ cyan build --update-all --structured-output --no-script

will produce nicely structured output, and some data massaging with jq
is easy enough. The following will produce an array of files that were
written by build

	$ cyan build --update-all --structured-output --no-script | jq -n '[inputs | select(.event == "wrote_file") | .data.file]'
  • Loading branch information
euclidianAce committed Feb 9, 2023
1 parent d1e9d17 commit 14f4fc4
Show file tree
Hide file tree
Showing 11 changed files with 500 additions and 14 deletions.
4 changes: 4 additions & 0 deletions build/cyan/cli.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions build/cyan/command.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 41 additions & 7 deletions build/cyan/commands/build.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

181 changes: 181 additions & 0 deletions build/cyan/event.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions build/cyan/eventtypes.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions cyan-dev-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ build = {
["cyan.commands.run"] = "build/cyan/commands/run.lua",
["cyan.commands.warnings"] = "build/cyan/commands/warnings.lua",
["cyan.config"] = "build/cyan/config.lua",
["cyan.event"] = "build/cyan/event.lua",
["cyan.eventtypes"] = "build/cyan/eventtypes.lua",
["cyan.fs.init"] = "build/cyan/fs/init.lua",
["cyan.fs.path"] = "build/cyan/fs/path.lua",
["cyan.graph"] = "build/cyan/graph.lua",
Expand All @@ -51,6 +53,8 @@ build = {
["cyan.commands.run"] = "src/cyan/commands/run.tl",
["cyan.commands.warnings"] = "src/cyan/commands/warnings.tl",
["cyan.config"] = "src/cyan/config.tl",
["cyan.event"] = "src/cyan/event.tl",
["cyan.eventtypes"] = "src/cyan/eventtypes.tl",
["cyan.fs.init"] = "src/cyan/fs/init.tl",
["cyan.fs.path"] = "src/cyan/fs/path.tl",
["cyan.graph"] = "src/cyan/graph.tl",
Expand Down
4 changes: 4 additions & 0 deletions src/cyan/cli.tl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
local argparse <const> = require("argparse")
local tl <const> = require("tl")

local event <const> = require("cyan.event")
local command <const> = require("cyan.command")
local common <const> = require("cyan.tlcommon")
local config <const> = require("cyan.config")
Expand All @@ -19,6 +20,9 @@ local keys <const>, from <const>, sort <const>, ivalues <const>
local parser <const> = argparse("cyan", "The Teal build system")
parser:add_help(false)

parser:flag("--structured-output", "Make all command output structured json rather than human readable")
:action(function() event.set_structured(true) end)

parser:option("-l --preload", "Execute the equivalent of require('modulename') before processing Teal files.")
:argname("<modulename>")
:count("*")
Expand Down
3 changes: 3 additions & 0 deletions src/cyan/command.tl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local config <const> = require("cyan.config")
local fs <const> = require("cyan.fs")
local log <const> = require("cyan.log")
local util <const> = require("cyan.util")
local type eventtypes = require("cyan.eventtypes")

local merge_list <const>, sort <const>, from <const>, keys <const>, contains <const>
= util.tab.merge_list, util.tab.sort_in_place, util.tab.from, util.tab.keys, util.tab.contains
Expand All @@ -21,6 +22,7 @@ local record Args
gen_compat: tl.CompatMode
gen_target: tl.TargetMode
quiet: boolean
structured_output: boolean
global_env_def: string
verbosity: log.Verbosity

Expand Down Expand Up @@ -50,6 +52,7 @@ local record Command
argparse: function(argparse.Command)
script_hooks: {string}
exec: CommandFn
events: {string:eventtypes.Handler}
end
local command <const> = {
running: Command = nil,
Expand Down
Loading

0 comments on commit 14f4fc4

Please sign in to comment.