Skip to content

hay-kot/flint

Repository files navigation


Flint

Customizable FrontMatter linter for your static site generator
Config Reference »

Report Bug · Request Feature

Flint is a customizable linter for frontmatter that can can be tailored to your projects needs. It uses a configuration file to define rule sets that can be applied conditionally to files based on their path.

  • Supported frontmatter formats:
    • YAML
    • JSON (Partial)
    • TOML (Partial)
Format Linting Line / Col
YAML
JSON
TOML

This library is still experimental.

Example Output

Features

  • Powerful glob matching support
  • Customizable rule-sets
  • Customizable error messages
  • Report errors when no front matter is detected
  • Powerful builtin checks
    • Required fields
    • Regex matching
    • Enums Sets
    • Date Format
    • Field Length
    • Disallowed Fields
    • Asset Existence
    • Field types (coming soon!)

Installation

Go Install

go install github.com/hay-kot/flint@latest

Homebrew

brew tap hay-kot/flint-tap
brew install hay-kot/flint-tap/flint

Usage

flint does nothing out of the box, you must initialize a configuration file in the root directory where you'll call flint. This is usually the root of your project.

Configuration

The configuration has two areas (1) the rules and (2) the content. The rules is where you define a Key/Value pair of rules where the key is the ID of the rule and the value is the checks to be performed. The content is where you define the content to be linted and which rules to apply to it. You can write your configuration in YAML, JSON, or TOML, though we recommend YAML is it's the most readable.

rules:
  FM001:
    level: error
    description: "required post fields are missing"
    required:
      - "title"
      - "date"

content:
  - name: Blog Posts
    paths:
      - content/**/*.{md,html}
    rules:
      - FM001

Note: If the configuration file cannot be found, flint will attempt to look for a glob match for a toml, json, or yaml file in the current directory, or the parent directory of the config path passed in. If you have multiple files that may match the glob, the first one found will be used. This may lead to unexpected results if you have multiple configuration files in your project. We recommend you use the --config flag to specify the path to your configuration file explicitly if you're using multiple configuration files.

Rules

The key is the ID of the rule. This is used to identify the rule in the output. We recommend using either FM001 and up or define your own rule id using a common prefix and number scheme.

The value represents the configuration for the rule set being created. Flint comes with a set of built in rules that can be applied to keys within your front matter. Custom rules cannot be defined at this time. Note that if multiple checks are defined for a rule, they will all be applied to the front matter.

Properties

  • level - The level of the rule. This can be error, warning, or info. This is used to determine the exit code of the program.
  • description - A description of the rule. This is used in the output to describe the rule. Keep it short and sweet.

Built-in Rules

required

This rule checks to see if the keys defined in the array are present in the front matter. It's values is a list of strings

rules:
  FM002:
    level: warning
    description: "author is missing"
    required:
      - "author.name"
      - "author.email"
disallowed

This rule checks to see if a key is defined in the front matter and if it is, will result in an error. Useful for checking for keys that should not be present. It's values is a list of strings

rules:
  FM003:
    level: error
    description: "disallowed key"
    disallowed:
      - "disallowed_key"
match

This rules checks to see if the regular expressions defined in the array match the values of the fields defined in the array. You can provide multiple regular expressions and field, just keep in mind that every regex will be applied to each field.

Supported types are string and []string

  FM003:
    level: error
    description: "slug is not valid url"
    match:
      re:
        - "^[a-z0-9]+(?:-[a-z0-9]+)*$"
      fields:
        - "meta.slug"
        - "slug"
enum

checks to see if the string or string array are defined in the values.

Supported types are string and []string

  FM004:
    level: error
    description: "category not in list"
    enum:
      values:
        - "Go"
        - "Python"
      fields:
        - "category"
        - "post.category"
date

checks to see if the date is in the correct format. The format is defined using the Go Time package string format.

If the format property not defined it will default to all parsable formats defined in the Go Time package.

Supported types are string

  FM005:
    level: error
    description: "date is not in correct format"
    date:
      format:
        - "2006-01-02"
      fields:
        - "date"
length

Checks to see if the field meets a min/max length

Supported types are string and []string

  FM006:
    level: error
    description: "must be between 2 and 5"
    length:
      min: 2
      max: 5
      fields:
        - "keywords"
        - "categories"
        - "tags"
assets

Checks to see if the filepath defined in the field exists in a relative path to the sources defined in the assets section. This is useful for checking to see if an image exists in a directory.

Supported types are string and []string

  FM008:
    level: error
    description: "assets required"
    assets:
      sources:
        - "content/"
        - "static/"
        - "public/"
      fields:
        - image
        - images

Content

The content is an array of objects that define the content to be linted and the rules to apply to it. You can use a robust glob pattern to define the paths to be linted. See doublestar for more details on supported patterns

content:
  - name: Blog Posts
    paths:
      - content/**/*.{md,html}
    rules:
      - FM001
      - FM002
      - FM003

Recipes

Blog Requirements

rules:
  FM001:
    level: error
    description: "blog post requirements"
    required:
      - "title"
      - "slug"
      - "description"
      - "date"
      - "keywords"
    date:
      format:
        - "2006-01-02"
      fields:
        - "date"
    length:
      min: 2
      max: 5
      fields:
        - "keywords"
        - "categories"
        - "tags"
    match:
      re:
        - "^[a-z0-9]+(?:-[a-z0-9]+)*$"
      fields:
        - "slug"

Ignore Files that start with an underscore

content:
  - name: Blog Posts
    paths:
      - content/blog/**/[!_]*.md
    rules:
      - FM001
      - FM002
      - FM003

Regular Expressions

Description Regex
Slug ^[a-z0-9]+(?:-[a-z0-9]+)*$