mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-03 19:17:29 -05:00 
			
		
		
		
	
		
			Some checks failed
		
		
	
	Tests / test (./cmd/caddy/caddy, ~1.22.3, macos-14, 0, 1.22, mac) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy, ~1.23.0, macos-14, 0, 1.23, mac) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.22.3, windows-latest, True, 1.22, windows) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy.exe, ~1.23.0, windows-latest, True, 1.23, windows) (push) Waiting to run
				
			Lint / lint (macos-14, mac) (push) Waiting to run
				
			Lint / lint (windows-latest, windows) (push) Waiting to run
				
			Tests / test (./cmd/caddy/caddy, ~1.22.3, ubuntu-latest, 0, 1.22, linux) (push) Failing after 1m34s
				
			Tests / test (./cmd/caddy/caddy, ~1.23.0, ubuntu-latest, 0, 1.23, linux) (push) Failing after 1m25s
				
			Tests / test (s390x on IBM Z) (push) Has been skipped
				
			Tests / goreleaser-check (push) Successful in 24s
				
			Cross-Build / build (~1.22.3, 1.22, aix) (push) Successful in 1m31s
				
			Cross-Build / build (~1.22.3, 1.22, darwin) (push) Successful in 1m32s
				
			Cross-Build / build (~1.22.3, 1.22, dragonfly) (push) Successful in 1m41s
				
			Cross-Build / build (~1.22.3, 1.22, freebsd) (push) Successful in 1m34s
				
			Cross-Build / build (~1.22.3, 1.22, illumos) (push) Successful in 1m31s
				
			Cross-Build / build (~1.22.3, 1.22, linux) (push) Successful in 1m31s
				
			Cross-Build / build (~1.22.3, 1.22, netbsd) (push) Successful in 1m30s
				
			Cross-Build / build (~1.22.3, 1.22, openbsd) (push) Successful in 1m31s
				
			Cross-Build / build (~1.22.3, 1.22, solaris) (push) Successful in 1m32s
				
			Cross-Build / build (~1.22.3, 1.22, windows) (push) Successful in 1m31s
				
			Cross-Build / build (~1.23.0, 1.23, aix) (push) Successful in 1m24s
				
			Cross-Build / build (~1.23.0, 1.23, darwin) (push) Successful in 1m22s
				
			Cross-Build / build (~1.23.0, 1.23, dragonfly) (push) Successful in 1m20s
				
			Cross-Build / build (~1.23.0, 1.23, freebsd) (push) Successful in 1m21s
				
			Cross-Build / build (~1.23.0, 1.23, illumos) (push) Successful in 1m22s
				
			Cross-Build / build (~1.23.0, 1.23, linux) (push) Successful in 1m23s
				
			Cross-Build / build (~1.23.0, 1.23, netbsd) (push) Successful in 1m20s
				
			Cross-Build / build (~1.23.0, 1.23, openbsd) (push) Successful in 1m22s
				
			Cross-Build / build (~1.23.0, 1.23, solaris) (push) Successful in 1m24s
				
			Cross-Build / build (~1.23.0, 1.23, windows) (push) Successful in 1m21s
				
			Lint / lint (ubuntu-latest, linux) (push) Successful in 2m12s
				
			Lint / govulncheck (push) Successful in 1m20s
				
			* chore: Use slices package where possible * More, mostly using ContainsFunc * Even more slice operations
		
			
				
	
	
		
			129 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package templates
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"strings"
 | 
						|
	"unicode"
 | 
						|
 | 
						|
	"github.com/BurntSushi/toml"
 | 
						|
	"gopkg.in/yaml.v3"
 | 
						|
)
 | 
						|
 | 
						|
func extractFrontMatter(input string) (map[string]any, string, error) {
 | 
						|
	// get the bounds of the first non-empty line
 | 
						|
	var firstLineStart, firstLineEnd int
 | 
						|
	lineEmpty := true
 | 
						|
	for i, b := range input {
 | 
						|
		if b == '\n' {
 | 
						|
			firstLineStart = firstLineEnd
 | 
						|
			if firstLineStart > 0 {
 | 
						|
				firstLineStart++ // skip newline character
 | 
						|
			}
 | 
						|
			firstLineEnd = i
 | 
						|
			if !lineEmpty {
 | 
						|
				break
 | 
						|
			}
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		lineEmpty = lineEmpty && unicode.IsSpace(b)
 | 
						|
	}
 | 
						|
	firstLine := input[firstLineStart:firstLineEnd]
 | 
						|
 | 
						|
	// ensure residue windows carriage return byte is removed
 | 
						|
	firstLine = strings.TrimSpace(firstLine)
 | 
						|
 | 
						|
	// see what kind of front matter there is, if any
 | 
						|
	var closingFence []string
 | 
						|
	var fmParser func([]byte) (map[string]any, error)
 | 
						|
	for _, fmType := range supportedFrontMatterTypes {
 | 
						|
		if firstLine == fmType.FenceOpen {
 | 
						|
			closingFence = fmType.FenceClose
 | 
						|
			fmParser = fmType.ParseFunc
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if fmParser == nil {
 | 
						|
		// no recognized front matter; whole document is body
 | 
						|
		return nil, input, nil
 | 
						|
	}
 | 
						|
 | 
						|
	// find end of front matter
 | 
						|
	var fmEndFence string
 | 
						|
	fmEndFenceStart := -1
 | 
						|
	for _, fence := range closingFence {
 | 
						|
		index := strings.Index(input[firstLineEnd:], "\n"+fence)
 | 
						|
		if index >= 0 {
 | 
						|
			fmEndFenceStart = index
 | 
						|
			fmEndFence = fence
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if fmEndFenceStart < 0 {
 | 
						|
		return nil, "", fmt.Errorf("unterminated front matter")
 | 
						|
	}
 | 
						|
	fmEndFenceStart += firstLineEnd + 1 // add 1 to account for newline
 | 
						|
 | 
						|
	// extract and parse front matter
 | 
						|
	frontMatter := input[firstLineEnd:fmEndFenceStart]
 | 
						|
	fm, err := fmParser([]byte(frontMatter))
 | 
						|
	if err != nil {
 | 
						|
		return nil, "", err
 | 
						|
	}
 | 
						|
 | 
						|
	// the rest is the body
 | 
						|
	body := input[fmEndFenceStart+len(fmEndFence):]
 | 
						|
 | 
						|
	return fm, body, nil
 | 
						|
}
 | 
						|
 | 
						|
func yamlFrontMatter(input []byte) (map[string]any, error) {
 | 
						|
	m := make(map[string]any)
 | 
						|
	err := yaml.Unmarshal(input, &m)
 | 
						|
	return m, err
 | 
						|
}
 | 
						|
 | 
						|
func tomlFrontMatter(input []byte) (map[string]any, error) {
 | 
						|
	m := make(map[string]any)
 | 
						|
	err := toml.Unmarshal(input, &m)
 | 
						|
	return m, err
 | 
						|
}
 | 
						|
 | 
						|
func jsonFrontMatter(input []byte) (map[string]any, error) {
 | 
						|
	input = append([]byte{'{'}, input...)
 | 
						|
	input = append(input, '}')
 | 
						|
	m := make(map[string]any)
 | 
						|
	err := json.Unmarshal(input, &m)
 | 
						|
	return m, err
 | 
						|
}
 | 
						|
 | 
						|
type parsedMarkdownDoc struct {
 | 
						|
	Meta map[string]any `json:"meta,omitempty"`
 | 
						|
	Body string         `json:"body,omitempty"`
 | 
						|
}
 | 
						|
 | 
						|
type frontMatterType struct {
 | 
						|
	FenceOpen  string
 | 
						|
	FenceClose []string
 | 
						|
	ParseFunc  func(input []byte) (map[string]any, error)
 | 
						|
}
 | 
						|
 | 
						|
var supportedFrontMatterTypes = []frontMatterType{
 | 
						|
	{
 | 
						|
		FenceOpen:  "---",
 | 
						|
		FenceClose: []string{"---", "..."},
 | 
						|
		ParseFunc:  yamlFrontMatter,
 | 
						|
	},
 | 
						|
	{
 | 
						|
		FenceOpen:  "+++",
 | 
						|
		FenceClose: []string{"+++"},
 | 
						|
		ParseFunc:  tomlFrontMatter,
 | 
						|
	},
 | 
						|
	{
 | 
						|
		FenceOpen:  "{",
 | 
						|
		FenceClose: []string{"}"},
 | 
						|
		ParseFunc:  jsonFrontMatter,
 | 
						|
	},
 | 
						|
}
 |