Skip to content

Commit

Permalink
Updated to use viper for configs, swapped logrus to zerolog for logging
Browse files Browse the repository at this point in the history
  • Loading branch information
endigma committed May 10, 2021
1 parent 76d3ac0 commit c51b0fb
Show file tree
Hide file tree
Showing 12 changed files with 418 additions and 145 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.vscode/
config.toml
bin/
tmp/
assets/public/
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ FROM gcr.io/distroless/base
COPY ./assets/ /assets
COPY --from=build-env /go/bin/holden /

CMD ["/holden", "/config.toml"]
CMD ["/holden"]
LABEL org.opencontainers.image.source=https://github.com/endigma/holden
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ documentation (and coincidentally live demo) can be found on [my website](https:

# to-do
- support for a custom header
- convert to using viper for configs
- gracefully handle outdated configs
- fix table scroll

# maintainers
Expand Down
6 changes: 2 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ services:
container_name: holden
image: ghcr.io/endigma/holden
build: .
environment:
DOCKER: "TRUE"
volumes:
- ./ignore/config.toml:/config.toml
- ./md:/docroot
- ./docs:/docs
- ./example.toml:/config.toml
ports:
- "11011:11011"
14 changes: 9 additions & 5 deletions docs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ dynamic markdown documentation written in go

## running

in order to run holden you have to pass a config file through the command line, or put a `config.toml` file where the binary is located. to use the shipped config run:
```
./holden example.toml
```
holden will run out of the box and create a config next to the binary

holden also looks for configs in:
- ~/.holden/
- /etc/holden
- ./

with the filename `config.toml`.

## features

Expand All @@ -35,7 +39,7 @@ if you want to host your documentation elsewhere, try integrating [fennec](https

## configuration

for configuration instruction refer to the comments in the example config file in `example.toml`
for configuration instructions refer to the comments in the example config file in `example.toml`

## scripting

Expand Down
6 changes: 2 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ require (
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/fatih/color v1.10.0 // indirect
github.com/gomarkdown/markdown v0.0.0-20210208175418-bda154fe17d8 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/kyokomi/emoji v2.2.4+incompatible // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/naoina/toml v0.1.1
github.com/rivo/uniseg v0.2.0 // indirect
github.com/sirupsen/logrus v1.8.1
github.com/rs/zerolog v1.21.0
github.com/spf13/viper v1.7.1
github.com/yuin/goldmark v1.3.2
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
github.com/yuin/goldmark-meta v1.0.0
Expand Down
303 changes: 294 additions & 9 deletions go.sum

Large diffs are not rendered by default.

35 changes: 18 additions & 17 deletions handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,37 @@ import (
"text/template"

termmd "github.com/MichaelMure/go-term-markdown"
log "github.com/sirupsen/logrus"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"

"gitcat.ca/endigma/holden/structure"
"gitcat.ca/endigma/holden/utils"
)

// Handler is the main response handler for requests
func Handler(rw http.ResponseWriter, req *http.Request) {
if structure.Conf.General.Debug {

if viper.GetBool("general.debug") {
utils.DebugReq(req)
}

newPath := strings.TrimPrefix(req.URL.Path, structure.Conf.General.Prefix)
newPath := strings.TrimPrefix(req.URL.Path, viper.GetString("general.prefix"))

log.Debugf("Request for markdown file on %s", structure.Conf.General.Root+newPath)
log.Debug().Msgf("Request for markdown file on %s", viper.GetString("general.docroot")+newPath)

var path string
if strings.HasSuffix(newPath, "/") {
log.Debug("Detected trailing / on %s, checking for index", newPath)
log.Debug().Msgf("Detected trailing / on %s, checking for index", newPath)
path = newPath + "_index.md"
} else if strings.HasSuffix(newPath, ".md") {
log.Debug("Detected trailing .md on %s, sending raw markdown", newPath)
if utils.FileExists(structure.Conf.General.Root + newPath) {
sourcefile, err := os.Open(structure.Conf.General.Root + newPath)
log.Debug().Msgf("Detected trailing .md on %s, sending raw markdown", newPath)
if utils.FileExists(viper.GetString("general.docroot") + newPath) {
sourcefile, err := os.Open(viper.GetString("general.docroot") + newPath)
utils.CheckErr(err)
defer sourcefile.Close()

source, err := ioutil.ReadAll(sourcefile)

if structure.Conf.General.FancyCurl && !utils.IsInArr("true", req.Header.Values("RawPlease")) {
if viper.GetBool("general.fancycurl") && !utils.IsInArr("true", req.Header.Values("RawPlease")) {
if strings.HasPrefix(req.UserAgent(), "curl") {
rw.Write(termmd.Render(string(source), 80, 4))
} else {
Expand All @@ -55,21 +56,21 @@ func Handler(rw http.ResponseWriter, req *http.Request) {
path = newPath + ".md"
}

page := render(structure.Conf.General.Root + path)
page := render(viper.GetString("general.docroot") + path)

if utils.FileExists(structure.Conf.General.Root + "/_sidebar.md") {
log.Debug("_sidebar found")
page.SidebarContents = render(structure.Conf.General.Root + "/_sidebar.md").Contents
if utils.FileExists(viper.GetString("general.docroot") + "/_sidebar.md") {
log.Debug().Msg("_sidebar found")
page.SidebarContents = render(viper.GetString("general.docroot") + "/_sidebar.md").Contents
} else {
sidebarContent := renderSidebar(enumerateDir(structure.Conf.General.Root), "/")
sidebarContent := renderSidebar(enumerateDir(viper.GetString("general.docroot")), "/")
if sidebarContent == "" {
page.DisplaySidebar = false
}
page.SidebarContents = fmt.Sprintf("<h3><a class='home' href='%s/'><i class='fas fa-home'></i><span>%s</span></a></h3><ul>", structure.Conf.General.Prefix, structure.Conf.Website.SiteName) + sidebarContent + "</ul>"
page.SidebarContents = fmt.Sprintf("<h3><a class='home' href='%s/'><i class='fas fa-home'></i><span>%s</span></a></h3><ul>", viper.GetString("general.prefix"), viper.GetString("website.sitename")) + sidebarContent + "</ul>"
}

page.Raw = path

tmpl := template.Must(template.ParseFiles(structure.Conf.General.WorkDir + "assets/page.html"))
tmpl := template.Must(template.ParseFiles(viper.GetString("workdir") + "assets/page.html"))
tmpl.Execute(rw, page)
}
41 changes: 21 additions & 20 deletions handler/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"sort"
"strings"

log "github.com/sirupsen/logrus"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"

"gitcat.ca/endigma/holden/structure"
"gitcat.ca/endigma/holden/utils"
Expand All @@ -26,12 +27,12 @@ var metareader goldmark.Markdown

func render(reqPath string) structure.Page {
if !utils.FileExists(reqPath) {
log.Errorf("No file found at: %s", reqPath)
if utils.FileExists(structure.Conf.General.Root + "/_404.md") {
return render(structure.Conf.General.Root + "/_404.md")
log.Error().Msgf("No file found at: %s", reqPath)
if utils.FileExists(viper.GetString("general.docroot") + "/_404.md") {
return render(viper.GetString("general.docroot") + "/_404.md")
} else {
return structure.Page{
Prefix: structure.Conf.General.Prefix,
Prefix: viper.GetString("general.prefix"),
Raw: "_404",
Contents: "<p>404</p>",
SidebarContents: "You shouldn't be seeing this!",
Expand All @@ -54,12 +55,12 @@ func render(reqPath string) structure.Page {
}

var page structure.Page = structure.Page{
Prefix: structure.Conf.General.Prefix,
Prefix: viper.GetString("general.prefix"),
Contents: buf.String(),
Meta: meta.Get(context),
SidebarContents: "You shouldn't be seeing this!",
DisplayBackToTop: structure.Conf.Website.DisplayBackToTop,
DisplaySidebar: structure.Conf.Website.DisplaySidebar,
DisplayBackToTop: viper.GetBool("website.backtotop"),
DisplaySidebar: viper.GetBool("website.sidebar"),
}

return page
Expand All @@ -70,7 +71,7 @@ func renderSidebar(dirInfo structure.Directory, prefix string) string {
if len(dirInfo.Directories) > 0 {
for _, directory := range dirInfo.Directories {
if utils.IsInArr("_index.md", directory.Files) {
sidebarContent.WriteString("<li class=\"folder\"><i class='fas fa-folder-plus'></i> <a href=\"" + structure.Conf.General.Prefix + "/" + directory.Name + "/" + "\">" + directory.Name + "</a></li>")
sidebarContent.WriteString("<li class=\"folder\"><i class='fas fa-folder-plus'></i> <a href=\"" + viper.GetString("general.prefix") + "/" + directory.Name + "/" + "\">" + directory.Name + "</a></li>")
} else {
sidebarContent.WriteString("<li class=\"folder\"><i class='fas fa-folder'></i> " + directory.Name + "</li>")
}
Expand All @@ -80,21 +81,21 @@ func renderSidebar(dirInfo structure.Directory, prefix string) string {
if len(dirInfo.Files) > 0 {
for _, file := range dirInfo.Files {
if !strings.HasPrefix(file, "_") {
filecontent, err := os.ReadFile(structure.Conf.General.Root + prefix + file)
filecontent, err := os.ReadFile(viper.GetString("general.docroot") + prefix + file)
utils.CheckErr(err)

context := parser.NewContext()
if err := metareader.Convert(filecontent, ioutil.Discard, parser.WithContext(context)); err != nil {
log.Panic(err)
log.Panic().Err(err).Msg("Failure in sidebar generation")
}

fileMeta, err := meta.TryGet(context)
utils.CheckErr(err)

if fileMeta["Short"] != nil && fileMeta["Short"].(string) != "" {
sidebarContent.WriteString("<li class=\"file\"><i class='fas fa-file-alt'></i> <a href=\"" + structure.Conf.General.Prefix + prefix + strings.TrimSuffix(file, ".md") + "\">" + fileMeta["Short"].(string) + "</a></li>")
sidebarContent.WriteString("<li class=\"file\"><i class='fas fa-file-alt'></i> <a href=\"" + viper.GetString("general.prefix") + prefix + strings.TrimSuffix(file, ".md") + "\">" + fileMeta["Short"].(string) + "</a></li>")
} else {
sidebarContent.WriteString("<li class=\"file\"><i class='fas fa-file-alt'></i> <a href=\"" + structure.Conf.General.Prefix + prefix + strings.TrimSuffix(file, ".md") + "\">" + strings.TrimSuffix(file, ".md") + "</a></li>")
sidebarContent.WriteString("<li class=\"file\"><i class='fas fa-file-alt'></i> <a href=\"" + viper.GetString("general.prefix") + prefix + strings.TrimSuffix(file, ".md") + "\">" + strings.TrimSuffix(file, ".md") + "</a></li>")
}
}
}
Expand Down Expand Up @@ -139,19 +140,19 @@ func init() {
extension.Footnote,
meta.Meta,
highlighting.NewHighlighting(
highlighting.WithStyle(structure.Conf.Aesthetic.HighlightStyle),
highlighting.WithStyle(viper.GetString("aesthetic.highlightstyle")),
highlighting.WithFormatOptions(
html.WithLineNumbers(structure.Conf.Aesthetic.LineNumbers),
html.TabWidth(structure.Conf.Aesthetic.TabWidth),
html.LineNumbersInTable(structure.Conf.Aesthetic.LineNumbersInTable),
html.WithClasses(structure.Conf.Aesthetic.UseClasses),
html.LinkableLineNumbers(structure.Conf.General.LinkableLines, "l"),
html.WithLineNumbers(viper.GetBool("aesthetic.linenumbers")),
html.TabWidth(viper.GetInt("aesthetic.tabwidth")),
html.LineNumbersInTable(viper.GetBool("aesthetic.linenumbersintable")),
html.WithClasses(viper.GetBool("aesthetic.tabwidth")),
html.LinkableLineNumbers(viper.GetBool("general.linkablelines"), "l"),
),
),
),
)
metareader = goldmark.New(goldmark.WithExtensions(meta.Meta))
if structure.Conf.General.AllowHtml {
if viper.GetBool("general.allowhtml") {
md.Renderer().AddOptions(goldmarkhtml.WithUnsafe())
}
}
50 changes: 25 additions & 25 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,51 @@ import (
"net/http"
"os"
"path/filepath"
"time"

log "github.com/sirupsen/logrus"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

"github.com/spf13/viper"

"gitcat.ca/endigma/holden/handler"
"gitcat.ca/endigma/holden/structure"
"gitcat.ca/endigma/holden/utils"
)

func init() {
logfmt := new(log.TextFormatter)
logfmt.TimestampFormat = "2006-01-02 15:04:05"
logfmt.FullTimestamp = true
log.SetFormatter(logfmt)
log.SetOutput(os.Stdout)
log.SetLevel(log.InfoLevel)

if structure.Conf.General.Debug {
log.SetLevel(log.DebugLevel)
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}).With().Caller().Logger()
zerolog.SetGlobalLevel(zerolog.InfoLevel)

if viper.GetBool("general.debug") {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}

log.Info("Initialized")
log.Debug("Debugging enabled")
log.Info().Msg("Initialized")
log.Debug().Msg("Debugging enabled")
}

func main() {
log.Infof("Serving markdown files in %s", structure.Conf.General.Root)
log.Info().Msgf("Serving markdown files in %s", viper.GetString("general.docroot"))

if structure.Conf.General.WorkDir == "_binary" {
if viper.GetString("general.workdir") == "_binary" {
ex, err := os.Executable()
utils.CheckErr(err)

structure.Conf.General.WorkDir = filepath.Dir(ex) + "/"
viper.Set("general.workdir", filepath.Dir(ex)+"/")
}

log.Debug(structure.Conf.General.WorkDir)
log.Debug().Msg(viper.GetString("general.workdir"))

fs := http.FileServer(http.Dir(structure.Conf.General.WorkDir + "assets/static"))
http.Handle(structure.Conf.General.Prefix+"/static/", http.StripPrefix(structure.Conf.General.Prefix+"/static/", fs))
fs := http.FileServer(http.Dir(viper.GetString("general.workdir") + "assets/static"))
http.Handle(viper.GetString("general.prefix")+"/static/", http.StripPrefix(viper.GetString("general.prefix")+"/static/", fs))

fs2 := http.FileServer(http.Dir(structure.Conf.General.WorkDir + "assets/public"))
http.Handle(structure.Conf.General.Prefix+"/public/", http.StripPrefix(structure.Conf.General.Prefix+"/public/", fs2))
http.Handle(structure.Conf.General.Prefix+"/favicon.ico", http.StripPrefix(structure.Conf.General.Prefix+"/public/", fs2))
fs2 := http.FileServer(http.Dir(viper.GetString("general.workdir") + "assets/public"))
http.Handle(viper.GetString("general.prefix")+"/public/", http.StripPrefix(viper.GetString("general.prefix")+"/public/", fs2))
http.Handle(viper.GetString("general.prefix")+"/favicon.ico", http.StripPrefix(viper.GetString("general.prefix")+"/public/", fs2))

http.HandleFunc(structure.Conf.General.Prefix+"/", handler.Handler)
http.HandleFunc(viper.GetString("general.prefix")+"/", handler.Handler)

log.Infof("Starting http server on :%s", structure.Conf.General.Port)
log.Fatal(http.ListenAndServe(":"+structure.Conf.General.Port, nil))
log.Info().Msgf("Starting http server on :%s", viper.GetString("general.port"))
log.Fatal().Err(http.ListenAndServe(":"+viper.GetString("general.port"), nil)).Msg("Fatal")
}
Loading

0 comments on commit c51b0fb

Please sign in to comment.