Graph-based Declarative Configuration Language

Overview

Virgo Configuration Language

Most configuration problems reduce to graphs, e.g. Dockerfiles and Makefiles

But there are no graph-based configuration languages. So virgo is an attempt to make a programming language that optimizes for natural graph readability, editability, and representation.

Imagine dot language, but focused on config instead of presentation.

Virgo Logo

Virgo is a graph-based configuration language. It has two main features: edge definitions and vertex definitions. The Virgo configuration file then parses into an adjacency list. You can clearly achieve similar results from adding additional conventions and restrictions on YAML or JSON. Much like YAML optimized for human readability, Virgo optimizes for natural graph readability, editability, and representation.

Go

This repository contains a reference implementation written in Go, with yacc and lex definitions.

Python

There is a python implementation maintained at jwg4/pyvirgo which can also be found on PyPi.

// config.vgo

a -> b, c, d -> e <- f, g

Virgo Example

Example

test parser = `goyacc parser.y` lexer = `golex lex.l` clean = `rm lex.yy.go parser.go || true` "test" = `go test-v` "src files" = `go build ./...` ">
// config.vgo

clean -> parser, lexer -> "src files" -> test

parser = `goyacc parser.y`
lexer  = `golex lex.l`
clean  = `rm lex.yy.go parser.go || true`
"test"   = `go test-v`
"src files"  = `go build ./...`

How to parse and topologically sort the graph with the Go library.

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/pkg/errors"
	"matt-rickard.com/virgo/pkg/virgo"
)

func main() {
	if err := run("config.go"); err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}

func run(fname string) error {
	f, err := ioutil.ReadFile(fname)
	if err != nil {
		return errors.Wrap(err, "reading file")
	}
	g, err := virgo.Parse(f)
	if err != nil {
		return errors.Wrap(err, "parsing virgo file")
	}

	nodes, err := virgo.TopSort(g)
	if err != nil {
		return errors.Wrap(err, "topological sort")
	}

	out := []string{}
	for _, n := range nodes {
		out = append(out, g.Vertices[n]...)
	}
	fmt.Println(strings.Join(out, "\n"))
	return nil
}

How to parse and topologically sort the graph with the Virgo CLI tool

$ virgo run build.vgo

Or topologically sort from a specific vertex

$ virgo run build.vgo:lexer

Virgo is Open for Proposals

I use virgo in a variety of ways for my own projects. That being said, I'm open to significant language change and feature proposals. Please open up a detailed issue and I'll do my best to respond. I'm also open to taking on more full time maintainers.

Language Reference

  • Newline delimited
  • Line contiuations can be created with a |
  • Single-line comments start with a //
  • Multi-line block comments start with a /* and end with a */

Edge Statement

a -> b, c -> d, e <- f <- g
a -> h
b -> h, i
  • Valid edge operators are right edge ->, left edge <-, and undirected edge --
  • Multiple edge definitions can be strung together per line
  • Multiple endpoints can be specified with a comma , on either side of the edge operator

Vertex Statement

vertex_definition_1 = `
    anything
    can
    go
    ${here}
`
  • Vertices do not require a definition
  • Vertex definitions lines start with the vertex name, followed by an equal sign = followed by a start backtick `, definition, and then end backtick `` `.
  • Vertex definitions are multiline by default and start and end with a backtick `` `
  • Vertex definitions valid characters are [a-zA-Z_:0-9] but cannot start with a digit
Comments
  • Vertices with no edges

    Vertices with no edges

    Hi,

    Very cool package. I was wondering if it's possible to support the following graph:

    a -> b
    c
    d
    

    where the vertices may have no edges. In terms of a DAG, this would help me define things where c and d have no parents so they can be run in parallel.

    I guess an even simpler case is supporting a single vertex as a graph

    a
    

    I could create a cycle, but then I can't do a topological sort.

    Thanks!

    opened by terrykong 1
  • add node without edge to grammar

    add node without edge to grammar

    fixes #6

    TODO: Topological sort returns an order list, but doesn't include "depth", i.e. what groups can be ran in parallel. I have this code in a branch but it needs to be cleaned up

    opened by r2d4 0
  • Topological sort should return depth and support multiple roots

    Topological sort should return depth and support multiple roots

    • Vertices should be type Vertex interface{} instead of string
    • Sort should return [][]Vertex instead of []string, grouping tasks that can be done in parallel together. This would support multiple roots
    opened by r2d4 0
  • Performance test files

    Performance test files

    Hi,

    I would like some official performance test files of Virgo graphs for testing the relative speed of various implementations. I am working on a JavaScript implementation I expect to be much faster than the Go implementation, whose speedups are designed to be portable to other languages.

    opened by CrazyPython 1
  • Python implementation

    Python implementation

    Hi, I saw your announcement about this language on Twitter.

    I thought it seemed extremely useful, so I created a Python implementation. It's at https://github.com/jwg4/pyvirgo, and on pypi at https://pypi.org/project/pyvirgo/0.2.0/

    If you would mention this package on your README in case it's helpful to anyone that would be great!

    The implementation is rudimentary, but can parse the examples given in your README. I will follow this work and update my package if the spec is extended. I consulted your repo to figure out some details which weren't clear from the README, but haven't used any of your code, which I note is GPL3 (mine is MIT). I currently have 8 test files at https://github.com/jwg4/pyvirgo/tree/main/test/files, some of them taken from your project, some of them new but which I believe to be valid based on your docs.

    Thanks for this project, let me know if I you have any feedback on mine.

    opened by jwg4 1
  • Vertex statement: Many languages use

    Vertex statement: Many languages use "`" as syntax

    Many languages, such as Bash and JS, use "`" as valid syntax.

    Furthermore, while implementing the spec, I noticed it doesn't say escaping "`" is required.

    I propose changing the character to "@", a character very rarely used in programming languages.

    Alternatively, we could use:

    • An end token
    clean = 
    rm -rf build
    end clean
    
    • Here strings
    • Indentation
    opened by CrazyPython 2
Releases(0.0.1)
Owner
Matt Rickard
Matt Rickard
✨Clean and minimalistic environment configuration reader for Golang

Clean Env Minimalistic configuration reader Overview This is a simple configuration reading tool. It just does the following: reads and parses configu

Ilya Kaznacheev 791 Nov 25, 2022
12 factor configuration as a typesafe struct in as little as two function calls

Config Manage your application config as a typesafe struct in as little as two function calls. type MyConfig struct { DatabaseUrl string `config:"DAT

Jeremy Loy 319 Nov 27, 2022
JSON or YAML configuration wrapper with convenient access methods.

Config Package config provides convenient access methods to configuration stored as JSON or YAML. This is a fork of the original version. This version

Oleg Lebedev 259 Nov 17, 2022
Configure is a Go package that gives you easy configuration of your project through redundancy

Configure Configure is a Go package that gives you easy configuration of your project through redundancy. It has an API inspired by negroni and the fl

Harrison Shoebridge 57 Sep 26, 2022
An opinionated configuration loading framework for Containerized and Cloud-Native applications.

Opinionated configuration loading framework for Containerized and 12-Factor compliant applications. Read configurations from Environment Variables, an

Sherif Abdel-Naby 82 Oct 30, 2022
Load configuration in cascade from multiple backends into a struct

Confita is a library that loads configuration from multiple backends and stores it in a struct. Supported backends Environment variables JSON files Ya

Heetch 455 Nov 26, 2022
Small library to read your configuration from environment variables

envconfig envconfig is a library which allows you to parse your configuration from environment variables and fill an arbitrary struct. See the example

Vincent Rischmann 229 Nov 3, 2022
A minimalist Go configuration library

fig fig is a tiny library for loading an application's config file and its environment into a Go struct. Individual fields can have default values def

null 243 Nov 11, 2022
go-up! A simple configuration library with recursive placeholders resolution and no magic.

go-up! A simple configuration library with placeholders resolution and no magic. go-up provides a simple way to configure an application from multiple

Francesco 38 Sep 26, 2022
goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configuration file.

goconfig goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configur

Go Sidekick 1 Sep 26, 2022
Go configuration made easy!

gofigure Go configuration made easy! Just define a struct and call Gofigure Supports strings, ints/uints/floats, slices and nested structs Supports en

Ian Kent 65 Sep 26, 2022
Harvest configuration, watch and notify subscriber

Harvester Harvester is a configuration library which helps setting up and monitoring configuration values in order to dynamically reconfigure your app

Beat Labs 122 Nov 16, 2022
go implementation of lightbend's HOCON configuration library https://github.com/lightbend/config

HOCON (Human-Optimized Config Object Notation) Configuration library for working with the Lightbend's HOCON format. HOCON is a human-friendly JSON sup

Gürkan Kaymak 53 Nov 17, 2022
🛠 A configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP

config A small configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP. Example func main() {

Josh Betz 214 Oct 15, 2022
Golang library for managing configuration data from environment variables

envconfig import "github.com/kelseyhightower/envconfig" Documentation See godoc Usage Set some environment variables: export MYAPP_DEBUG=false export

Kelsey Hightower 4.3k Nov 22, 2022
Light weight, extensible configuration management library for Go. Built in support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.

koanf (pronounced conf; a play on the Japanese Koan) is a library for reading configuration from different sources in different formats in Go applicat

Kailash Nadh 1.3k Nov 22, 2022
A golang package for parsing ini-style configuration files

Mini Mini is a simple ini configuration file parser. The ini syntax supported includes: The standard name=value Comments on new lines starting with #

Stephen Asbury 32 Sep 26, 2022
A dead simple configuration manager for Go applications

Store Store is a dead simple configuration manager for Go applications. I didn't like existing configuration management solutions like globalconf, tac

Ian P Badtrousers 264 Nov 13, 2022
Go configuration with fangs

Viper v2 feedback Viper is heading towards v2 and we would love to hear what you would like to see in it. Share your thoughts here: https://forms.gle/

Steve Francia 21.3k Nov 25, 2022