config

package
v0.0.0-...-1eb86f4 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2019 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package config provides types for project configuration and loading config files from disk.

The files are loaded using the Loader, and then can be marshalled into json. The resulting json should be unmarshalled into a *hclpack.Body, which can then be decoded into the Root config.

A typical config file may look something like this:

project "example" {}

resource "aws_lambda_function" "func" {
  source = "./src"          # source code location

  handler = "index.handler" # attributes passed
  memory  = 512             # to resource
}

Source code

If a resource specifies a source attribute, the source files from the directory are compressed into a source archive using the Compressor set on the Loader.

The source attribute is replaced with a source info block:

resource "aws_lambda_function" "func" {
  source ".tar.gz" {   # source extension
    sha = "b5bb9d8..." # sha256 hash of file contents
    md5 = "ERZsvZy..." # md5 hash of source archive
    len = 127          # source archive size in bytes
  }

  handler = "index.handler" # attributes passed
  memory  = 512             # to resource
}

Source() can be used to get a pointer to the source archive when source code is needed.

Except for the source, the entire body of a resource is specific to the resource type, set by the first label.

Example (ClientServer)
package main

import (
	"encoding/json"
	"log"

	"github.com/func/func/config"
	"github.com/hashicorp/hcl2/gohcl"
	"github.com/hashicorp/hcl2/hclpack"
)

var args = []string{"testdata/config"}

func main() {
	// Client

	// Find root, given user input
	project, err := config.FindProject(args[0])
	if err != nil {
		log.Fatal(err)
	}

	// Create a loader
	l := &config.Loader{}

	// Load config files from root
	cfg, diags := l.Load(project.RootDir)
	if diags.HasErrors() {
		log.Fatal(diags)
	}

	// Marshal config to json for transmission
	payload, err := json.Marshal(cfg)
	if err != nil {
		log.Fatal(err)
	}

	// Server

	// Parse payload
	var recv hclpack.Body
	if err := json.Unmarshal(payload, &recv); err != nil {
		log.Fatal(err)
	}

	// Decode config
	var root config.Root
	if err := gohcl.DecodeBody(&recv, nil, &root); err != nil {
		log.Fatal(err)
	}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Loader

type Loader struct {
	Compressor SourceCompressor
	// contains filtered or unexported fields
}

A Loader loads configuration files from .hcl files on disk.

If the Compressor is not set, the source files are not compressed and the source attribute is only removed from the output.

The zero value is ready to load files.

func (*Loader) Load

func (l *Loader) Load(root string) (*hclpack.Body, hcl.Diagnostics)

Load loads all the config files from the given root directory, traversing into sub directories.

If resource blocks are encountered and they contain a source attribute, the source files from resource are collected and processed as described in the package documentation.

If an empty .hcl file is encountered, it is not added.

func (*Loader) Source

func (l *Loader) Source(sha256 string) *bytes.Buffer

Source returns the compressed source for a given digest.

The digests are encoded into the body returned from Load. When source files are needed for a given digest, the list of files can be returned with Source().

The result is only valid if Load() has been executed without error.

func (*Loader) WriteDiagnostics

func (l *Loader) WriteDiagnostics(w io.Writer, diags hcl.Diagnostics)

WriteDiagnostics writes diagnostics as a human readable string to w. It should only be used for diagnostics that originate from files loaded by Loader.

If a TTY is attached, the output will be colorized and wrap at the terminal width. Otherwise, wrap will occur at 78 characters and output won't contain ANSI escape characters.

Example
package main

import (
	"os"

	"github.com/func/func/config"
)

func main() {
	l := &config.Loader{}
	_, diags := l.Load("testdata/invalid") // File contains syntax errors
	l.WriteDiagnostics(os.Stdout, diags)
}
Output:

Error: Missing newline after block definition

  on testdata/invalid/invalid.hcl line 6:
   4: resource "invalid" "syntax" {
   5:   # too many closing braces
   6: } }

A block definition must end with a newline.

type Project

type Project struct {
	// RootDir is the absolute path to the root directory of the project.
	RootDir string `json:"-"`

	// Name is the name of the project. If name is modified, Write() should be
	// called to persist the change to disk.
	Name string `json:"name"`
}

A Project is a func project on disk, loaded from .func/project.

func FindProject

func FindProject(dir string) (*Project, error)

FindProject finds a project on disk. If no project is found, nil is returned.

The project's root directory is determined by the file .func/project existing. If the given dir does not contain a project, parent directories are traversed until a project is found.

func (*Project) Write

func (p *Project) Write() error

Write persists the project to disk.

type Resource

type Resource struct {
	// Name is a unique name (within the same kind) for the resource.
	Name string `hcl:"name,label"`

	// Type specifies what type of resource this is.
	//
	// The type defines how the Config is decoded.
	Type string `hcl:"type"`

	// Config is a configuration body for the resource.
	//
	// The contents will depend on the resource type.
	Config hcl.Body `hcl:",remain"`

	// SourceDigest contains information about the attached source code. The
	// field is nil if the resource has no source.
	Source string `hcl:"source,optional"`
}

Resource is a user specified resource specification.

type Root

type Root struct {
	Resources []Resource `hcl:"resource,block"`
}

A Root is the root structure of a project's configuration, including all resources that are part of the project.

type SourceCompressor

type SourceCompressor interface {
	// Compress compresses the given directory into w. The returned extension
	// is the extension for the file with leading dot (.tar.gz).
	Compress(w io.Writer, dir string) error
}

SourceCompressor is used for compressing the source files on disk to an archive that can be uploaded.

type SourceInfo

type SourceInfo struct {
	Key string // Unique key for source based on content digest.
	MD5 string // Base64 encoded MD5 checksum of compressed source.
	Len int    // Source archive size in Bytes.
}

SourceInfo contains information about the resource source code.

func DecodeSourceString

func DecodeSourceString(str string) (SourceInfo, error)

DecodeSourceString decodes a source string encoded by EncodeToString().

func (SourceInfo) EncodeToString

func (s SourceInfo) EncodeToString() string

EncodeToString encodes the source info to a string.

Jump to

Keyboard shortcuts

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