summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--Makefile5
-rw-r--r--README4
-rw-r--r--crocc.go25
-rw-r--r--frontmatter.go39
-rw-r--r--frontmatter_test.go117
-rw-r--r--go.mod1
-rw-r--r--go.sum2
8 files changed, 189 insertions, 6 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ebe7dde..dc914ce 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -26,7 +26,7 @@ jobs:
- name: Building project
run: make
- name: Testing project
- run: go test
+ run: make test
- name: Downloading CI dependencies
run: |
go install golang.org/x/tools/cmd/goimports@latest
diff --git a/Makefile b/Makefile
index 206bf7c..107566a 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,10 @@ LDFLAGS := -ldflags "-w -s -X main.version=$(VERSION) -X main.date=$(DATE)"
$(BINARY): *.go
go build $(LDFLAGS) -o $(BINARY)
+test: *.go
+ go test -v ./...
+
clean:
rm -f $(BINARY)
-.PHONY: clean
+.PHONY: clean test
diff --git a/README b/README
index c2155f1..6a4af29 100644
--- a/README
+++ b/README
@@ -90,8 +90,8 @@ Example
---
title: Hello World
description: This is a simple example of a Markdown document.
- publication_time: 2013-01-01
- last_update_time: 2013-01-01
+ publication_time: 2020-01-01T00:00:00Z
+ last_update_time: 2020-01-01T03:00:00Z
keywords: [example, hello, world]
author: John Doe
hide: true
diff --git a/crocc.go b/crocc.go
index 59f1c7d..c4b6d2e 100644
--- a/crocc.go
+++ b/crocc.go
@@ -7,6 +7,7 @@ package main /* import "go.nc0.fr/crocc" */
import (
"flag"
+ "fmt"
"log"
"runtime"
)
@@ -45,14 +46,34 @@ func init() {
}
}
+// versionFormat returns a string containing the build information.
+func versionFormat() string {
+ return fmt.Sprintf("crocc version %s %s/%s %s date %s",
+ version, runtime.GOOS, runtime.GOARCH, runtime.Compiler, date)
+}
+
func main() {
flag.Parse()
log.SetFlags(0)
if *printVersion {
- log.Printf("crocc version %s %s/%s %s date %s",
- version, runtime.GOOS, runtime.GOARCH, runtime.Compiler, date)
+ log.Print(versionFormat())
return
}
+
+ inputdir := flag.Arg(0)
+ if inputdir == "" {
+ log.Fatalln("no input directory specified")
+ }
+
+ if *verbose {
+ log.Printf(`Version: %s
+Input directory: %s
+Output directory: %s
+Site URL: %s
+Generate sitemap: %t
+Generate hidden pages: %t`, versionFormat(), inputdir, *outputdir, *url,
+ *sitemap, *generateHidden)
+ }
}
diff --git a/frontmatter.go b/frontmatter.go
new file mode 100644
index 0000000..03237b5
--- /dev/null
+++ b/frontmatter.go
@@ -0,0 +1,39 @@
+// Copyright (c) 2023 Nicolas Paul All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "time"
+
+ "github.com/adrg/frontmatter"
+)
+
+// FrontMatter is the front matter of a Markdown document.
+type FrontMatter struct {
+ Title string `yaml:"title"`
+ Description string `yaml:"description"`
+ PublicationTime time.Time `yaml:"publication_time"`
+ LastUpdateTime time.Time `yaml:"last_update_time"`
+ Keywords []string `yaml:"keywords"`
+ Author string `yaml:"author"`
+ Hide bool `yaml:"hide"`
+}
+
+// ParseFrontMatter parses the front matter of a Markdown document.
+// It returns a FrontMatter struct and the Markdown document without the
+// front matter.
+func ParseFrontMatter(r []byte) (FrontMatter, []byte, error) {
+ var fm FrontMatter
+
+ reader := bytes.NewReader(r)
+
+ rest, err := frontmatter.MustParse(reader, &fm)
+ if err != nil {
+ return FrontMatter{}, nil, err
+ }
+
+ return fm, rest, nil
+}
diff --git a/frontmatter_test.go b/frontmatter_test.go
new file mode 100644
index 0000000..98d8164
--- /dev/null
+++ b/frontmatter_test.go
@@ -0,0 +1,117 @@
+// Copyright (c) 2023 Nicolas Paul All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "strconv"
+ "testing"
+ "time"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestParseFrontMatter(t *testing.T) {
+ tests := []struct {
+ input []byte
+ want FrontMatter
+ rest string
+ }{
+ {
+ input: []byte(`---
+title: "Test"
+description: "Test"
+publication_time: 2020-01-01T00:00:00Z
+last_update_time: 2020-01-01T00:00:00Z
+keywords: ["test"]
+author: "Test"
+hide: false
+---
+# Test`),
+ want: FrontMatter{
+ Title: "Test",
+ Description: "Test",
+ PublicationTime: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
+ LastUpdateTime: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
+ Keywords: []string{"test"},
+ Author: "Test",
+ Hide: false,
+ },
+ rest: "# Test",
+ },
+ {
+ input: []byte(`---
+title: "Test"
+description: "Test"
+publication_time: 2020-01-01T00:00:00Z
+keywords: ["test", "test2", "test3"]
+---
+# Test`),
+ want: FrontMatter{
+ Title: "Test",
+ Description: "Test",
+ PublicationTime: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
+ Keywords: []string{"test", "test2", "test3"},
+ },
+ rest: "# Test",
+ },
+ }
+
+ for _, tt := range tests {
+ fm, rest, err := ParseFrontMatter(tt.input)
+
+ if err != nil {
+ t.Fatalf("ParseFrontMatter(%v) got error %v", tt.input, err)
+ }
+
+ if !cmp.Equal(fm, tt.want) {
+ t.Fatalf("ParseFrontMatter(%v) got %v want %v", tt.input, fm, tt.want)
+ }
+
+ if string(rest) != tt.rest {
+ t.Fatalf("ParseFrontMatter(%v) got %v want %v", tt.input, rest, tt.rest)
+ }
+ }
+}
+
+func FuzzParseFrontMatter(f *testing.F) {
+ // Do not fuzz *_time fields as time.Time is not supported by f.Fuzz().
+ f.Fuzz(func(t *testing.T, title string, description string, keyword1 string, keyword2 string, keyword3 string, author string, hide bool, text string) {
+ input := []byte(`---
+title: "` + title + `"
+description: "` + description + `"
+publication_time: 2020-01-01T00:00:00Z
+last_update_time: 2020-01-01T00:00:00Z
+keywords: ["` + keyword1 + `", "` + keyword2 + `", "` + keyword2 + `"]
+author: "` + author + `"
+hide: ` + strconv.FormatBool(hide) + `
+---
+` + text)
+
+ fm, rest, err := ParseFrontMatter(input)
+
+ if err != nil {
+ t.Fatalf("ParseFrontMatter(%v) got error %v", input, err)
+ }
+
+ if string(rest) != text {
+ t.Fatalf("ParseFrontMatter(%v) got %v want %v", input, rest, text)
+ }
+
+ result := FrontMatter{
+ Title: title,
+ Description: description,
+ Keywords: []string{keyword1, keyword2, keyword3},
+ PublicationTime: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
+ LastUpdateTime: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
+ Author: author,
+ Hide: hide,
+ }
+
+ if !cmp.Equal(fm, result) {
+ t.Fatalf("ParseFrontMatter(%v) got %v want %v", input, fm, result)
+ }
+
+ })
+}
diff --git a/go.mod b/go.mod
index 3ef18e1..6a4e205 100644
--- a/go.mod
+++ b/go.mod
@@ -6,5 +6,6 @@ require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/adrg/frontmatter v0.2.0 // indirect
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a // indirect
+ github.com/google/go-cmp v0.5.9 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)
diff --git a/go.sum b/go.sum
index 7d177c8..5fd0e7b 100644
--- a/go.sum
+++ b/go.sum
@@ -4,6 +4,8 @@ github.com/adrg/frontmatter v0.2.0 h1:/DgnNe82o03riBd1S+ZDjd43wAmC6W35q67NHeLkPd
github.com/adrg/frontmatter v0.2.0/go.mod h1:93rQCj3z3ZlwyxxpQioRKC1wDLto4aXHrbqIsnH9wmE=
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a h1:AWZzzFrqyjYlRloN6edwTLTUbKxf5flLXNuTBDm3Ews=
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=