Do not cache files that are monitored

- rename repo to goveal
- add working directory option
- remove most CLI switches in favor of config file
This commit is contained in:
Peter 2020-12-06 12:18:42 +01:00
parent d56271ef50
commit b953310df8
Signed by: prskr
GPG key ID: C1DB5D2E8DB512F9
14 changed files with 119 additions and 68 deletions

6
.gitignore vendored
View file

@ -21,14 +21,10 @@
# CI # CI
bin/ bin/
assets/reveal assets/reveal/
pkged.go pkged.go
# binaries
goveal
!goveal/
# gorelease # gorelease
dist/ dist/

View file

@ -1,5 +1,5 @@
VERSION = $(shell git describe --dirty --tags --always) VERSION = $(shell git describe --dirty --tags --always)
REPO = github.com/baez90/go-reveal-slides REPO = github.com/baez90/goveal
BUILD_PATH = $(REPO)/cmd/goveal BUILD_PATH = $(REPO)/cmd/goveal
PKGS = $(shell go list ./... | grep -v /vendor/) PKGS = $(shell go list ./... | grep -v /vendor/)
TEST_PKGS = $(shell find . -type f -name "*_test.go" -printf '%h\n' | sort -u) TEST_PKGS = $(shell find . -type f -name "*_test.go" -printf '%h\n' | sort -u)

View file

@ -1,6 +1,6 @@
# Goveal # Goveal
[![CircleCI](https://circleci.com/gh/baez90/go-reveal-slides.svg?style=svg)](https://circleci.com/gh/baez90/go-reveal-slides) [![Actions Status](https://github.com/baez90/goveal/workflows/Go/badge.svg)](https://github.com/baez90/goveal/actions)
Goveal is very small an very simple tool that reads Markdown from a given file, renders it into a HTML template and serves it as local HTTP server. Goveal is very small an very simple tool that reads Markdown from a given file, renders it into a HTML template and serves it as local HTTP server.
Right now Goveal uses Reveal.js 4.0.2 to create presentations and therefore also includes all features of Reveal.js 4.0.2. Right now Goveal uses Reveal.js 4.0.2 to create presentations and therefore also includes all features of Reveal.js 4.0.2.

View file

@ -6,7 +6,7 @@ vars:
BINARY_NAME: goveal BINARY_NAME: goveal
OUT_DIR: ./out OUT_DIR: ./out
GO_BUILD_ARGS: -ldflags="-w -s" GO_BUILD_ARGS: -ldflags="-w -s"
CMD_PACKAGE: github.com/baez90/go-reveal-slides/cmd/goveal CMD_PACKAGE: github.com/baez90/goveal/cmd/goveal
emv: emv:
CGO_ENABLED: 0 CGO_ENABLED: 0

View file

@ -90,7 +90,7 @@
{{ if .Reveal.FilesToMonitor }} {{ if .Reveal.FilesToMonitor }}
{{ range $idx, $file := .Reveal.FilesToMonitor }} {{ range $idx, $file := .Reveal.FilesToMonitor }}
subscribeForUpdates("/{{ trimPrefix "/" $file }}") subscribeForUpdates("/{{ $file }}")
{{ end }} {{ end }}
{{ end }} {{ end }}

View file

@ -15,8 +15,8 @@
package main package main
import ( import (
_ "github.com/baez90/go-reveal-slides" _ "github.com/baez90/goveal"
"github.com/baez90/go-reveal-slides/internal/app/cmd" "github.com/baez90/goveal/internal/app/cmd"
) )
func main() { func main() {

View file

@ -1,9 +1,9 @@
theme: night theme: night
code-theme: monokai codeTheme: monokai
horizontal-separator: === horizontalSeparator: ===
vertical-separator: --- verticalSeparator: ---
transition: fade transition: fade
stylesheets: stylesheets:
- examples/custom.css - custom.css
filesToMonitor: filesToMonitor:
- examples/**/*.css - ./**/*.css

4
go.mod
View file

@ -1,4 +1,4 @@
module github.com/baez90/go-reveal-slides module github.com/baez90/goveal
go 1.15 go 1.15
@ -11,7 +11,7 @@ require (
github.com/gobuffalo/here v0.6.2 // indirect github.com/gobuffalo/here v0.6.2 // indirect
github.com/google/uuid v1.1.2 // indirect github.com/google/uuid v1.1.2 // indirect
github.com/huandu/xstrings v1.3.2 // indirect github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.11 // indirect github.com/imdario/mergo v0.3.11
github.com/markbates/pkger v0.17.1 github.com/markbates/pkger v0.17.1
github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0

View file

@ -17,8 +17,9 @@ package cmd
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"github.com/baez90/go-reveal-slides/internal/app/rendering" "github.com/baez90/goveal/internal/app/rendering"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
"github.com/mitchellh/go-homedir" "github.com/mitchellh/go-homedir"
@ -27,21 +28,10 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
const (
defaultTheme string = "white"
)
var ( var (
cfgFile string cfgFile string
theme string workingDir string
codeTheme string rootCmd = &cobra.Command{
transition string
navigationMode string
horizontalSeparator string
verticalSeparator string
slideNumberVisibility string
slideNumberFormat string
rootCmd = &cobra.Command{
Use: "goveal", Use: "goveal",
Short: "goveal is a small reveal.js server", Short: "goveal is a small reveal.js server",
Long: `goveal is a single static binary to host your reveal.js based markdown presentation. Long: `goveal is a single static binary to host your reveal.js based markdown presentation.
@ -61,18 +51,18 @@ func Execute() {
} }
func init() { func init() {
cobra.OnInitialize(initConfig)
cobra.OnInitialize(initLogging) cobra.OnInitialize(initLogging)
cobra.OnInitialize(initConfig)
var err error
workingDir, err = os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
rootCmd.PersistentFlags().StringVar(&theme, "theme", defaultTheme, "reveal.js theme to use")
rootCmd.PersistentFlags().StringVar(&codeTheme, "code-theme", "monokai", "name of the code theme to use for highlighting")
rootCmd.PersistentFlags().StringVar(&transition, "transition", "none", "transition effect to use")
rootCmd.PersistentFlags().StringVar(&navigationMode, "navigationMode", "default", "determine the navigation mode to use ['default', 'linear', 'grid']")
rootCmd.PersistentFlags().StringVar(&horizontalSeparator, "horizontal-separator", "===", "horizontal separator in slides")
rootCmd.PersistentFlags().StringVar(&verticalSeparator, "vertical-separator", "---", "vertical separator in slides")
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.go-reveal-slides.yaml)") rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.go-reveal-slides.yaml)")
rootCmd.PersistentFlags().StringVar(&slideNumberVisibility, "slide-number-visibility", "all", "where should slide numbers be visible ['all', 'speaker', 'print']") rootCmd.PersistentFlags().StringVar(&workingDir, "working-dir", workingDir, "working directory to use")
rootCmd.PersistentFlags().StringVar(&slideNumberFormat, "slide-number-format", "h.v", "Format of the slide number ['h.v', 'h/v', 'c', 'c/t']")
} }
func initLogging() { func initLogging() {
@ -83,6 +73,24 @@ func initLogging() {
// initConfig reads in config file and ENV variables if set. // initConfig reads in config file and ENV variables if set.
func initConfig() { func initConfig() {
var err error
if workingDir, err = filepath.Abs(workingDir); err != nil {
log.Warnf("Failed to determine absolute path for working dir %s: %v", workingDir, err)
return
}
var cwd string
if cwd, err = os.Getwd(); err != nil {
log.Warnf("Failed to determine current working directory")
return
}
if cwd != workingDir {
if err = os.Chdir(workingDir); err != nil {
log.Warnf("Failed to change working directory to %s", workingDir)
}
}
if cfgFile != "" { if cfgFile != "" {
// Use config file from the flag. // Use config file from the flag.
viper.SetConfigFile(cfgFile) viper.SetConfigFile(cfgFile)
@ -95,14 +103,9 @@ func initConfig() {
viper.AddConfigPath(home) viper.AddConfigPath(home)
} }
cwd, err := os.Getwd() viper.AddConfigPath(workingDir)
if err != nil {
log.Infof("Failed to determine current working directory: %v", err)
} else {
viper.AddConfigPath(cwd)
}
viper.SetConfigName("goveal") viper.SetConfigName("goveal")
viper.SetConfigType("yaml")
} }
viper.AutomaticEnv() // read in environment variables that match viper.AutomaticEnv() // read in environment variables that match
@ -119,10 +122,6 @@ func initConfig() {
}) })
} }
if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil { params.WorkingDirectory = workingDir
log.Errorf("Failed to bind flags to viper")
}
params.Load() params.Load()
} }

View file

@ -21,7 +21,7 @@ import (
"os/exec" "os/exec"
"runtime" "runtime"
"github.com/baez90/go-reveal-slides/internal/app/server" "github.com/baez90/goveal/internal/app/server"
"github.com/spf13/cobra" "github.com/spf13/cobra"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"

View file

@ -16,25 +16,45 @@ package rendering
import ( import (
"github.com/bmatcuk/doublestar/v2" "github.com/bmatcuk/doublestar/v2"
"github.com/imdario/mergo"
"github.com/spf13/viper" "github.com/spf13/viper"
"path"
"path/filepath"
)
var (
defaultParams = RevealParams{
Theme: "white",
CodeTheme: "vs",
Transition: "None",
NavigationMode: "default",
HorizontalSeparator: "===",
VerticalSeparator: "---",
SlideNumberVisibility: "all",
SlideNumberFormat: "h.v",
StyleSheets: make([]string, 0),
FilesToMonitor: make([]string, 0),
}
) )
type RevealParams struct { type RevealParams struct {
Theme string `mapstructure:"theme"` Theme string `mapstructure:"theme"`
CodeTheme string `mapstructure:"code-theme"` CodeTheme string `mapstructure:"codeTheme"`
Transition string `mapstructure:"transition"` Transition string `mapstructure:"transition"`
NavigationMode string `mapstructure:"navigationMode"` NavigationMode string `mapstructure:"navigationMode"`
HorizontalSeparator string `mapstructure:"horizontal-separator"` HorizontalSeparator string `mapstructure:"horizontalSeparator"`
VerticalSeparator string `mapstructure:"vertical-separator"` VerticalSeparator string `mapstructure:"verticalSeparator"`
SlideNumberVisibility string `mapstructure:"slide-number-visibility"` SlideNumberVisibility string `mapstructure:"slideNumberVisibility"`
SlideNumberFormat string `mapstructure:"slide-number-format"` SlideNumberFormat string `mapstructure:"slideNumberFormat"`
StyleSheets []string `mapstructure:"stylesheets"` StyleSheets []string `mapstructure:"stylesheets"`
FilesToMonitor []string `mapstructure:"filesToMonitor"` FilesToMonitor []string `mapstructure:"filesToMonitor"`
WorkingDirectory string `mapstructure:"working-dir"`
} }
func (params *RevealParams) Load() { func (params *RevealParams) Load() error {
_ = viper.Unmarshal(params) _ = viper.Unmarshal(params)
expandGlobs(params) expandGlobs(params)
return mergo.Merge(params, &defaultParams)
} }
func expandGlobs(params *RevealParams) { func expandGlobs(params *RevealParams) {
@ -43,10 +63,24 @@ func expandGlobs(params *RevealParams) {
for _, f := range params.FilesToMonitor { for _, f := range params.FilesToMonitor {
var err error var err error
f, err = filepath.Abs(f)
if err != nil {
continue
}
var matches []string var matches []string
if matches, err = doublestar.Glob(f); err != nil { if matches, err = doublestar.Glob(f); err != nil {
continue continue
} }
for idx := range matches {
if relative, err := filepath.Rel(params.WorkingDirectory, matches[idx]); err != nil {
continue
} else {
matches[idx] = path.Join("/", relative)
}
}
allFiles = append(allFiles, matches...) allFiles = append(allFiles, matches...)
} }
params.FilesToMonitor = allFiles params.FilesToMonitor = allFiles

View file

@ -2,6 +2,7 @@ package routing
import ( import (
"net/http" "net/http"
"strings"
"time" "time"
) )
@ -23,8 +24,21 @@ var etagHeaders = []string{
"If-Unmodified-Since", "If-Unmodified-Since",
} }
func NoCache(h http.Handler) http.Handler { func NoCache(h http.Handler, pathsToDisableCache []string) http.Handler {
pathLookup := make(map[string]bool)
for idx := range pathsToDisableCache {
pathLookup[strings.ToLower(pathsToDisableCache[idx])] = true
}
fn := func(w http.ResponseWriter, r *http.Request) { fn := func(w http.ResponseWriter, r *http.Request) {
if _, shouldBeHandled := pathLookup[strings.ToLower(r.URL.Path)]; !shouldBeHandled {
h.ServeHTTP(w, r)
return
}
// Delete any ETag headers that may have been set // Delete any ETag headers that may have been set
for _, v := range etagHeaders { for _, v := range etagHeaders {
if r.Header.Get(v) != "" { if r.Header.Get(v) != "" {

View file

@ -79,6 +79,7 @@ func (h hashHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request
Hash: encodedHash, Hash: encodedHash,
} }
writer.Header().Set("Content-Type", "application/json")
encoder := json.NewEncoder(writer) encoder := json.NewEncoder(writer)
if err = encoder.Encode(resp); err != nil { if err = encoder.Encode(resp); err != nil {
writer.WriteHeader(500) writer.WriteHeader(500)

View file

@ -5,11 +5,15 @@ import (
"net" "net"
"net/http" "net/http"
"github.com/baez90/go-reveal-slides/internal/app/rendering" "github.com/baez90/goveal/internal/app/rendering"
"github.com/baez90/go-reveal-slides/internal/app/routing" "github.com/baez90/goveal/internal/app/routing"
"github.com/markbates/pkger" "github.com/markbates/pkger"
) )
const (
markdownFilePath = "/content.md"
)
type Config struct { type Config struct {
Host string Host string
Port uint16 Port uint16
@ -31,6 +35,9 @@ func (srv HTTPServer) ListenAddress() string {
} }
func NewHTTPServer(config Config) (srv *HTTPServer, err error) { func NewHTTPServer(config Config) (srv *HTTPServer, err error) {
noCacheFiles := append(config.RevealParams.FilesToMonitor, markdownFilePath)
router := &routing.RegexpRouter{} router := &routing.RegexpRouter{}
var tmplRenderer rendering.RevealRenderer var tmplRenderer rendering.RevealRenderer
if tmplRenderer, err = rendering.NewRevealRenderer(config.RevealParams); err != nil { if tmplRenderer, err = rendering.NewRevealRenderer(config.RevealParams); err != nil {
@ -50,20 +57,20 @@ func NewHTTPServer(config Config) (srv *HTTPServer, err error) {
fs := routing.NewLayeredFileSystem(pkger.Dir("/assets/reveal"), pkger.Dir("/assets/web"), http.Dir("."), mdFS) fs := routing.NewLayeredFileSystem(pkger.Dir("/assets/reveal"), pkger.Dir("/assets/web"), http.Dir("."), mdFS)
//language=regexp //language=regexp
if err = router.AddRule(`^(?i)/hash/(md5|sha1|sha2)/.*`, routing.NoCache(NewHashHandler(fs))); err != nil { if err = router.AddRule(`^(?i)/hash/(md5|sha1|sha2)/.*`, NewHashHandler(fs)); err != nil {
return return
} }
if err = router.AddRule("^/.*\\.md$", routing.NoCache(http.FileServer(mdFS))); err != nil { if err = router.AddRule("^/.*\\.md$", http.FileServer(mdFS)); err != nil {
return return
} }
if err = router.AddRule("/.+", routing.NoCache(http.FileServer(fs))); err != nil { if err = router.AddRule("/.+", http.FileServer(fs)); err != nil {
return return
} }
hostPort := fmt.Sprintf("%s:%d", config.Host, config.Port) hostPort := fmt.Sprintf("%s:%d", config.Host, config.Port)
srv = &HTTPServer{ srv = &HTTPServer{
handler: router, handler: routing.NoCache(router, noCacheFiles),
} }
if srv.listener, err = net.Listen("tcp", hostPort); err != nil { if srv.listener, err = net.Listen("tcp", hostPort); err != nil {