eleconf

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Nov 14, 2025 License: MIT Imports: 24 Imported by: 1

README

Eleconf

Tool for applying configuration to changes to the Elephant repository.

Enforces configuration for:

* Schema versions
* Meta type configuration
* Document statuses
* Document workflows

Configuration

Eleconf uses HCL as its configuration language.

See example configuration files in the examples/tt folder.

Schema sets

An organisations schemas are often split into several files for readability, but versioned together. Therefore schemas are configured as schema sets.

Schemas can either be loaded from a git repository, or over http(s).

Example schema set block:

schema_set "core" {
  version      = "v1.0.5-pre1"
  repository   = "https://github.com/ttab/revisorschemas.git"

  schemas = [
    "core",
    "core-planning",
    "core-metadoc",
  ]
}

As we specify a repository here the version must be a valid git tag. And the schemas files themselves are assumed to be located in the root of the repository.

If the schemas are to be loaded over http we can instead provide an URL template like so:

url_template = "https://raw.githubusercontent.com/ttab/revisorschemas/refs/tags/{{.Version}}/{{.Name}}.json"
Document types

Document blocks are used to configure document types.

  • meta_doc string: the document type that should be used for meta documents, optional.
  • statuses string slice: all the statuses that are valid for the document type.
  • workflow object: defintion of the workflow for the document, optional.
  • bounded_collection bool: whether the document type is a bounded collection (finite and small number of documents).
  • time_expression object: time expression used to extract timestamps.
  • label_expression object: label expression used to extract labels.
Workflow object
  • step_zero string: the workflow step that a document starts on, and reverts to after a new revision is created after a checkpoint status.
  • checkpoint string: the name of the status to use as a checkpoint step, usually "usable" to signal that something is published.
  • negative_checkpoint string: the checkpoint name to use when the checkpoint status is set with a negative version.
  • steps string slice: the statuses that should be used as steps between checkpoints.
Example
document "core/article" {
  meta_doc = "core/article+meta"

  statuses = [
    "draft",
    "done",
    "approved",
    "withheld",
    "cancelled",
    "usable",
  ]

  workflow = {
    step_zero  = "draft"
    checkpoint = "usable"
    negative_checkpoint = "unpublished"
    steps      = [
      "draft",
      "done",
      "approved",
      "withheld",
      "cancelled",
    ]
  }
}
Metrics

Metric blocks are used to configure metric kinds:

metric "charcount" {
  aggregation = "replace"
}

aggregation can be "replace" or "increment", defaults to "replace".

Usage

All changes to schemas require lockfile update. So the first thing you have to do for a new configuration directory is to run the update command. This will not change anything in the repository, but will check that the referenced schema versions exist and update the lock file.

eleconf update -dir examples/tt

To apply the configuration to a repository installation run apply:

eleconf apply -auth-env stage \
    -customer 000 \
    -endpoint https://repository.stage.tt.se \
    -dir examples/tt

This will compare the current configuration with the one declared in the configuration directory, detail the changes, and ask for confirmation before applying.

Example use:

❯ go run ./cmd/eleconf apply -dir tt

~ schema downgrade tt v1.1.1 => v1.0.5-pre1
 Warning:  downgrading schema
+ status "print_done" for "tt/print-article"
- status "nonsense" for "tt/print-article"
~ update workflow for "core/event":
  &eleconf.DocumentWorkflow{
  	StepZero:           "draft",
  	Checkpoint:         "usable",
  	NegativeCheckpoint: "unpublished",
  	Steps: []string{
+ 		"draft",
  		"done",
  		"cancelled",
  	},
  }


Do you want to apply these changes? [y/n]: y

~ schema downgrade tt v1.1.1 => v1.0.5-pre1
+ status "print_done" for "tt/print-article"
- status "nonsense" for "tt/print-article"
~ update workflow for "core/event"

Configuration has been updated

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LockFilePath

func LockFilePath(dir string) string

Types

type AttachmentConfig

type AttachmentConfig struct {
	Name          string   `hcl:"name,label"`
	Required      bool     `hcl:"required"`
	MatchMimetype []string `hcl:"match_mimetype"`
}

type CacheEntry

type CacheEntry struct {
	URL  string
	Hash string
}

type ChangeOp

type ChangeOp string
const (
	OpAdd    ChangeOp = "+"
	OpUpdate ChangeOp = "~"
	OpRemove ChangeOp = "-"
)

type Clients

type Clients interface {
	GetWorkflows() repository.Workflows
	GetSchemas() repository.Schemas
	GetMetrics() repository.Metrics
}

type Config

type Config struct {
	Documents  []DocumentConfig `hcl:"document,block"`
	SchemaSets []SchemaSet      `hcl:"schema_set,block"`
	Metric     []MetricKind     `hcl:"metric,block"`
}

func ReadConfigFromDirectory

func ReadConfigFromDirectory(path string) (*Config, error)

type ConfigurationChange

type ConfigurationChange interface {
	Describe() (ChangeOp, string)
	Execute(ctx context.Context, c Clients) error
}

func GetChanges

func GetChanges(
	ctx context.Context,
	clients Clients,
	conf *Config,
	schemas []LoadedSchema,
) ([]ConfigurationChange, error)

func GetMetaTypeChanges

func GetMetaTypeChanges(
	ctx context.Context,
	clients Clients,
	conf *Config,
) ([]ConfigurationChange, error)

func GetMetricsChanges

func GetMetricsChanges(
	ctx context.Context,
	clients Clients,
	conf *Config,
) ([]ConfigurationChange, error)

func GetSchemaChanges

func GetSchemaChanges(
	ctx context.Context,
	clients Clients,
	conf *Config,
	loaded []LoadedSchema,
) ([]ConfigurationChange, error)

func GetStatusChanges

func GetStatusChanges(
	ctx context.Context,
	clients Clients,
	conf *Config,
) ([]ConfigurationChange, error)

func GetTypeConfigurationChanges

func GetTypeConfigurationChanges(
	ctx context.Context,
	clients Clients,
	conf *Config,
) ([]ConfigurationChange, error)

func GetWorkflowChanges

func GetWorkflowChanges(
	ctx context.Context,
	clients Clients,
	conf *Config,
) ([]ConfigurationChange, error)

type DocWorkflowUpdate

type DocWorkflowUpdate struct {
	Operation ChangeOp
	Type      string
	Current   *DocumentWorkflow
	Wanted    *DocumentWorkflow
	// contains filtered or unexported fields
}

func (*DocWorkflowUpdate) Describe

func (d *DocWorkflowUpdate) Describe() (ChangeOp, string)

Describe implements ConfigurationChange.

func (*DocWorkflowUpdate) Execute

func (d *DocWorkflowUpdate) Execute(ctx context.Context, c Clients) error

Execute implements ConfigurationChange.

type DocumentConfig

type DocumentConfig struct {
	Type              string             `hcl:"type,label"`
	MetaDocType       string             `hcl:"meta_doc,optional"`
	Statuses          []string           `hcl:"statuses,optional"`
	Workflow          *DocumentWorkflow  `hcl:"workflow,optional"`
	Attachments       []AttachmentConfig `hcl:"attachment,block"`
	BoundedCollection bool               `hcl:"bounded_collection,optional"`
	TimeExpressions   []TimeExpression   `hcl:"time_expression,block"`
	LabelExpressions  []LabelExpression  `hcl:"label_expression,block"`
}

type DocumentWorkflow

type DocumentWorkflow struct {
	StepZero           string   `cty:"step_zero"`
	Checkpoint         string   `cty:"checkpoint"`
	NegativeCheckpoint string   `cty:"negative_checkpoint"`
	Steps              []string `cty:"steps"`
}

type GitSchemaSource

type GitSchemaSource struct {
	// contains filtered or unexported fields
}

func NewGitSchemaSource

func NewGitSchemaSource(
	ctx context.Context, origin string, version string,
) (*GitSchemaSource, error)

func (*GitSchemaSource) LoadSchema

func (g *GitSchemaSource) LoadSchema(ctx context.Context, name string) (LoadedSchema, error)

LoadSchema implements SchemaSource.

type HttpSchemaSource

type HttpSchemaSource struct {
	// contains filtered or unexported fields
}

func NewHttpSchemaSource

func NewHttpSchemaSource(
	cx context.Context,
	urlTemplate string, version string,
) (*HttpSchemaSource, error)

func (*HttpSchemaSource) LoadSchema

func (h *HttpSchemaSource) LoadSchema(
	ctx context.Context, name string,
) (_ LoadedSchema, outErr error)

LoadSchema implements SchemaSource.

type LabelExpression

type LabelExpression struct {
	// Expression is a newsdoc value extraction expression.
	Expression string `hcl:"expression"`
	// Template is the template that turns the extracted values into a
	// label.
	Template string `hcl:"template"`
}

type LoadedSchema

type LoadedSchema struct {
	Lock SchemaLock
	Data []byte
}

func LoadSchemaSet

func LoadSchemaSet(
	ctx context.Context,
	set SchemaSet,
	lockfile *SchemaLockfile,
	init bool,
) (_ []LoadedSchema, outErr error)

type MetricAggregation

type MetricAggregation string
const (
	MetricAggregationReplace   MetricAggregation = "replace"
	MetricAggregationIncrement MetricAggregation = "increment"
)

type MetricKind

type MetricKind struct {
	Kind        string            `hcl:"kind,label"`
	Aggregation MetricAggregation `hcl:"aggregation,optional"`
}

type MetricUpdate

type MetricUpdate struct {
	Operation      ChangeOp
	Kind           string
	OldAggregation MetricAggregation
	Aggregation    MetricAggregation
}

func (*MetricUpdate) Describe

func (m *MetricUpdate) Describe() (ChangeOp, string)

Describe implements ConfigurationChange.

func (*MetricUpdate) Execute

func (m *MetricUpdate) Execute(ctx context.Context, c Clients) error

Execute implements ConfigurationChange.

type SchemaCache

type SchemaCache struct {
	// contains filtered or unexported fields
}

func NewSchemaCache

func NewSchemaCache() (*SchemaCache, error)

func (*SchemaCache) Read

func (sc *SchemaCache) Read(
	assetURL string, logicalURL string, hash string,
) ([]byte, bool, error)

func (*SchemaCache) Store

func (sc *SchemaCache) Store(
	assetURL string, logicalURL string, hash string, data []byte,
) error

type SchemaLock

type SchemaLock struct {
	Name    string `json:"name"`
	URL     string `json:"url,omitempty"`
	Version string `json:"version"`
	Hash    string `json:"hash"`
}

type SchemaLockfile

type SchemaLockfile struct {
	Updated time.Time             `json:"updated"`
	Schemas map[string]SchemaLock `json:"schemas"`
}

func LoadLockFile

func LoadLockFile(fileName string) (*SchemaLockfile, error)

func NewSchemaLockFile

func NewSchemaLockFile(loaded []LoadedSchema) *SchemaLockfile

func (*SchemaLockfile) Check

func (lf *SchemaLockfile) Check(
	name string, loaded LoadedSchema, init bool,
) error

func (*SchemaLockfile) Save

func (lf *SchemaLockfile) Save(fileName string) error

type SchemaSet

type SchemaSet struct {
	Name        string   `hcl:"name,label"`
	Version     string   `hcl:"version"`
	URLTemplate string   `hcl:"url_template,optional"`
	Repository  string   `hcl:"repository,optional"`
	Schemas     []string `hcl:"schemas"`
}

type SchemaSource

type SchemaSource interface {
	LoadSchema(ctx context.Context, name string) (LoadedSchema, error)
}

type StaticClients

type StaticClients struct {
	Workflows repository.Workflows
	Schemas   repository.Schemas
	Metrics   repository.Metrics
}

func (*StaticClients) GetMetrics

func (c *StaticClients) GetMetrics() repository.Metrics

GetMetrics implements Clients.

func (*StaticClients) GetSchemas

func (c *StaticClients) GetSchemas() repository.Schemas

GetSchemas implements Clients.

func (*StaticClients) GetWorkflows

func (c *StaticClients) GetWorkflows() repository.Workflows

GetWorkflows implements Clients.

type TimeExpression

type TimeExpression struct {
	// Expression is a newsdoc value extraction expression.
	Expression string `hcl:"expression"`
	// Layout is the time/date format to use when parsing. Optional,
	// defaults to RFC3339 or ISO 8601 for values annotated as dates.
	Layout string `hcl:"layout,optional"`
	// Timezone is the timezone the time should be parsed in. Optional, most
	// timestamps should include timezone information, if they don't,
	// parsing will fall back to the default timezone that the repository
	// has been configured with.
	Timezone string `hcl:"timezone,optional"`
}

type TypeConfigSpec

type TypeConfigSpec struct {
	Bounded          bool
	TimeExpressions  []TimeExpression
	LabelExpressions []LabelExpression
}

type TypeConfigurationChange

type TypeConfigurationChange struct {
	Operation ChangeOp
	Type      string
	Current   TypeConfigSpec
	Wanted    TypeConfigSpec
	// contains filtered or unexported fields
}

func (*TypeConfigurationChange) Describe

func (t *TypeConfigurationChange) Describe() (ChangeOp, string)

Describe implements ConfigurationChange.

func (*TypeConfigurationChange) Execute

Execute implements ConfigurationChange.

Directories

Path Synopsis
cmd
eleconf command

Jump to

Keyboard shortcuts

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