fileloader

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 7, 2025 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package fileloader defines the main function for a component loader with only a constant footprint at runtime. This package makes it easy for a provider of component subsystem packages to also provide a standalone tool that loads just those descriptors from a hard-coded footprint - usually for demonstration purposes.

For example, if github.com/example/my-system is a component package, exposing one or more component descriptors, all that is needed to define a standalone demonstration tool is a file, github.com/example/my-system/cmd/demo/main.go, containing:

// The demo command runs a demonstration deployment of the new subsystem.
Package main

import (
	"github.com/example/my-system"
	"github.com/danielorbach/go-component/fileloader"
	"github.com/danielorbach/go-component/loader"
)

const footprint = `...`

func main() {
	loader.ParseFlags(newsubsystem.ComponentA, newsubsystem.ComponentB, ...)
	fileloader.Load(footprint, fileloader.FormatYAML)
}

Index

Examples

Constants

View Source
const Stdin = "-"

Stdin is a special value for the footprint argument, indicating that the footprint should be read from stdin.

Variables

This section is empty.

Functions

func Load

func Load(footprint []byte, format FormatFlag)

Load loads the components described by the footprint, using the specified format to decode it.

Example
// Component is an imported descriptor for the purpose of this example.
var Component = &component.Descriptor{
	Name: "example",
	Bootstrap: func(l *component.L, _ component.Linker, _ any) error {
		l.Logf("Hello world!")
		return nil
	},
	OptionsType: nil,
}

// sometimes the footprint is embedded in the binary, and we can use the
// fileloader.Load function to load it directly from memory.
const Footprint = `{
	  "Name": "Example Footprint",
	  "Metadata": "This footprint is serialized into bytes and then unmarshalled into loader.Footprint.",
	  "Identifier": "00000000-abcd-0000-abcd-000000000000",
	  "Locations": null,
	  "Components": {
		"example": {
		  "Location": "",
		  "Options": null,
		  "Aspects": null,
		  "Interests": null
		}
	  }
	}`

// in which case, we must parse the commandline flags ourselves before attempting
// to load the footprint. fortunately, this is easy to do:
loader.ParseFlags(Component)
// then we can call fileloader.Load with the footprint as a byte slice, and the
// format of the footprint (JSON, YAML, etc.) - in this case, JSON.
fileloader.Load([]byte(Footprint), fileloader.FormatJSON)

func Main

func Main(d ...*component.Descriptor)

Main parses the commandline and loads the components described by the footprint.

Example
// Component is an imported descriptor for the purpose of this example.
var Component = &component.Descriptor{
	Name: "example",
	Bootstrap: func(l *component.L, _ component.Linker, _ any) error {
		l.Logf("Hello world!")
		return nil
	},
	OptionsType: nil,
}

// simply call fileloader.Main with the component descriptors of choice, and it
// shall parse the commandline and load the components described by the footprint
// provided as the first positional argument.
fileloader.Main(Component)

func UnmarshalFootprintJSON

func UnmarshalFootprintJSON(data []byte) (loader.Footprint, error)

Types

type ComponentJSON

type ComponentJSON struct {
	Location  string            // IGNORED
	Options   json.RawMessage   // unmarshal into an appropriate Options type
	Aspects   map[string]string // map[aspect]topic
	Interests map[string]string // map[interest]topic
}

type FootprintJSON

type FootprintJSON struct {
	Name       string // human-readable name (does not need to be unique)
	Metadata   string // human-readable description/summary/notes/comments
	Solution   string // attribute this footprint to a solution
	Identifier uuid.UUID
	Revision   int
	Locations  []string // IGNORED
	Components map[string]ComponentJSON
}

type FootprintYAML

type FootprintYAML struct {
	Name       string // human-readable name (does not need to be unique)
	Metadata   string // human-readable description/summary/notes/comments
	Solution   string // attribute this footprint to a solution
	Identifier uuid.UUID
	Revision   int
	Locations  []string // IGNORED
	Components map[string]struct {
		Location  string
		Options   yaml.Node         // unmarshal into an appropriate Options type
		Aspects   map[string]string // map[aspect]topic
		Interests map[string]string // map[interest]topic
	}
}

type FormatFlag

type FormatFlag string

FormatFlag is a flag.Value that specifies the format of the footprint, and thus the appropriate loader to use.

const (
	// FormatAuto indicates that the footprint format should be inferred; currently
	// from the file extension.
	FormatAuto FormatFlag = "auto"

	// FormatYAML indicates that the footprint is in YAML format.
	FormatYAML FormatFlag = "yaml"
	// FormatJSON indicates that the footprint is in JSON format.
	FormatJSON FormatFlag = "json"
)

func (*FormatFlag) Set

func (f *FormatFlag) Set(s string) error

func (*FormatFlag) String

func (f *FormatFlag) String() string

type JSONLoader

type JSONLoader []byte

A JSONLoader implements component.Procedure loading its json-encoded blob of a loader.Footprint.

Example
package main

import (
	"github.com/MakeNowJust/heredoc"

	"github.com/danielorbach/go-component/fileloader"
)

func main() {
	var json = heredoc.Doc(`
	{
		"name": "Static ping-pong-probe",
		"metadata": "This is a static footprint loading three components: ping, pong, and probe.\n",
		"identifier": "0abcdef0-b00b-0000-b00b-000000000000",
		"locations": null,
		"components": {
			"ping": {
				"location": null,
				"options": {
					"data": "Hello, world"
				},
				"aspects": {
					"ping": "ping-topic"
				},
				"interests": null
			},
			"pong": {
				"location": "",
				"aspects": {
					"pong": "pong-topic"
				},
				"interests": {
					"ping": "ping-topic"
				}
			},
			"probe": {
				"aspects": null,
				"interests": {
					"pong": "pong-topic"
				},
				"options": {
					"timeout": "2100ms"
				}
			}
		}
	}
	`)
	fileloader.Load([]byte(json), fileloader.FormatJSON)
}

func (JSONLoader) Exec

func (x JSONLoader) Exec(l *component.L)

type YAMLLoader

type YAMLLoader []byte

A YAMLLoader implements component.Procedure loading its yaml-encoded blob of a loader.Footprint.

Example
package main

import (
	"github.com/MakeNowJust/heredoc"

	"github.com/danielorbach/go-component/fileloader"
)

func main() {
	var yaml = heredoc.Doc(`
		name: Static ping-pong-probe
		metadata: |
		  This is a static footprint loading three components: ping, pong, and probe.
		identifier: "0abcdef0-b00b-0000-b00b-000000000000"
		
		locations: ~ # a tilde (~) character is an alias for null
		
		components:
		  ping:
			location: null # null is a defined literal of YAML (https://yaml.org/type/null.html)
			options:
			  data: !!binary "SGVsbG8sIHdvcmxkIQ=="
			aspects:
			  ping: "ping-topic"
			interests: # omitting value equals to a null value
		
		  pong:
			location: "" # an empty string is the null value of a string variable in Go
			# options: # we can omit fields as-well
			aspects:
			  pong: "pong-topic"
			interests:
			  ping: "ping-topic"
		
		  probe:
			aspects:
			interests:
			  pong: "pong-topic"
			options:
			  timeout: 2100ms
	`)
	fileloader.Load([]byte(yaml), fileloader.FormatYAML)
}

func (YAMLLoader) Exec

func (x YAMLLoader) Exec(l *component.L)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL