Skip to content

🕴Generate configs confidently from env, json, yaml

License

Notifications You must be signed in to change notification settings

alvis/preconfig

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Logo

No more copy and paste! No more hundred lines of config!

•   Quick Start   •   Usage   •   Syntax   •   About   •

Highlights

Preconfig relieves your headaches by allowing you to:

  • manage templates in any format: preconfig only takes the input as a plain text, so any format works!
  • import content from other locations: from env, a file, or even within itself.
  • split configs into smaller chunks: txt, json, yaml or other format, all up to you!
  • generate content with nested control syntax: e.g. ${base64encode(${var:data})}

Demo

Quick Start

$ echo '{"name":"preconfig","message":"hello ${var:_}! This is ${self:name}"}' | preconfig -v _=world
> {"name":"preconfig","message":"hello world! This is preconfig"}

Usage

Preconfig provides two ways to generate configs, either through a command-line interface (CLI) or a programatic interface.

Command-Line Interface

Preconfig is shipped with a command-line interface with with the following options:

  --help           Show help                                                               [boolean]
  --version        Show version number                                                     [boolean]
  --output, -o     Path to output file                                                      [string]
  --output-format, -f     Output format                           [string] [choices: "raw", "json", "yaml"]
  --variables, -v  Variables to be used                                                      [array]

Through a globally installed binary, you can transform a json, yaml, or ts/js file simply by either

  • supply a file to the CLI, or
$ preconfig <file> [options]
  • supply the content via stdin
$ echo <something> | preconfig [options]

Examples:

  • Print the transformed content on stdout
$ cat template.cfg | preconfig
  • Print the transformed default export on stdout
$ preconfig template.cfg
  • Transform an input into another format
$ preconfig template.yml -f json
  • Save the transformed file in another format such as config.json (No output on stdout)
$ preconfig template.yml -o config.json
  • Substitute with variables
$ echo '{"ref":"${self:config.env}","config":{"env":"${var:dev}"}}' | preconfig -v env=dev
  • Output a base64 decoded content on stdout
$ echo '${base64decode(${file(path_to_file)})}' | preconfig

Programatic

You can also use preconfig programatically if you need to generate config in your workflow.

To do so, frist install preconfig as a standard package in your project, then start by importing Template to use preconfig to manage your config template,

import { Template } from 'preconfig';

const template = new Template('<plain text template>');

// resolve the template with variable pairs
console.log(await template.resolve({ key: 'value' }));

You can also load a template file and resolve it into another compatible format, for example

import { readFile, writeFile } from 'fs-extra';
import { Template } from 'preconfig';

const template = new Template(await readFile('<path to a template file>'));
await writeFile(
  '<path to output>',
  await template.resolve({ key: 'value' }, { format: '<raw, json or yaml>' }),
);

Variable Syntax

There are several options for you to control how the config is generated.

Preconfig replaces any variables with the syntax ${source, [default]}, where source can be one of those:

  • ${var:path} - a variable supplied either to the CLI or the programatic interface
  • ${env:path} - a variable from the environment
  • ${self:path} - a variable from a different part of the same document
  • ${base64decode(encoded_content)}, ${base64encode(plain_content)} - base64 decode/encode a string from a variable
  • ${file(file):path} - a variable from a file

and default is an optional input for the default content when the source is not available.

NOTE: if the source cannot be found and the default is not set, a missing source exception will be thrown.

PRO TIPS: if you use typescript as a variable source, you can use further enjoy type checking with an interface!

Examples

Referencing supplied variables

$ export ENV=dev
$ preconfig input.yaml --variables key=value
INOUT
env: ${env:ENV}
var: ${var:key}
env: dev
var: value

Variable with a default

INOUT
other: value
var: ${self:non.existent.path, 'default'}
{
  "other": "value"
  "var": "default"
}

Referencing variables from the same file

INOUT
{
  "a": { "b": { "c": "d" } },
  "d": "${self:a.b.c}"
}
{
  "a": { "b": { "c": "d" } },
  "d": "d"
}

NOTE: For a multi-part yaml file, path is prefixed with the index number, e.g.

INOUT
---
name: name
---
ref: ${self:1.name}
---
name: name
---
ref: name

Nested Embedding (PRO)

All variable controls can be nested. For example:

IN

{
  a: 'b',
  b: {
    c: 'd'
  },
  d: ${self:${a}.c}
}

OUT

{
  a: "b",
  b: {
    c: "d"
  },
  d: "d"
}

About

Getting a right config is already hard, managing a number of interrelated configs is even harder. From configs for different environments to sharing settings across applications, there are just enough reasons to hate writing config files manually.

Designed with extensibility and manageability in mind, preconfig is a language agnostic config file transpiler. Under the hood, it builds an abstract syntax tree (AST) of the input, and substitutes any control syntax with the intended output.

This tool is originally designed for my DevOps workflow, which involves heavy reuses of many configuration files. I hate copy and paste settings whenever a deploy template get updated, and I'm pretty sure you feel the same. Therefore, I make this tool available to everyone who has a similar problem as me.

Any suggestion or issue? Check the issues section or open a new issue.

Related Projects

  • spruce: spruce is a general purpose YAML & JSON merging tool.

License

Copyright © 2020, Alvis Tang. Released under the MIT License.

release build codacy grade codacy coverage security dependencies license

About

🕴Generate configs confidently from env, json, yaml

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published