parent
e10cc57bec
commit
0df151c7e4
@ -1,414 +1,420 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"bytes" |
||||
"flag" |
||||
"fmt" |
||||
"github.com/fsnotify/fsnotify" |
||||
"github.com/yuin/goldmark" |
||||
"io" |
||||
"io/fs" |
||||
"lcthw.dev/go/ssgod/config" |
||||
"log" |
||||
"os" |
||||
"path/filepath" |
||||
"strings" |
||||
"text/template" |
||||
"time" |
||||
_ "embed" |
||||
"bytes" |
||||
_ "embed" |
||||
"flag" |
||||
"fmt" |
||||
"github.com/fsnotify/fsnotify" |
||||
"github.com/yuin/goldmark" |
||||
"io" |
||||
"io/fs" |
||||
"lcthw.dev/go/ssgod/config" |
||||
"log" |
||||
"os" |
||||
"path/filepath" |
||||
"strings" |
||||
"text/template" |
||||
"time" |
||||
) |
||||
|
||||
//go:embed example/.ssgod.json
|
||||
var DEFAULT_CONFIG string |
||||
|
||||
type PageMetaData struct { |
||||
pages []string |
||||
pages []string |
||||
} |
||||
|
||||
func (meta *PageMetaData) AddPage(path string) { |
||||
path = RePrefixPath(path, "/") |
||||
path = filepath.ToSlash(path) |
||||
meta.pages = append(meta.pages, path) |
||||
path = RePrefixPath(path, "/") |
||||
path = filepath.ToSlash(path) |
||||
meta.pages = append(meta.pages, path) |
||||
} |
||||
|
||||
func Fatal(err error, format string, v ...any) { |
||||
err_format := fmt.Sprintf("ERROR: %v; %s", err, format) |
||||
panic(fmt.Sprintf(err_format, v...)) |
||||
err_format := fmt.Sprintf("ERROR: %v; %s", err, format) |
||||
panic(fmt.Sprintf(err_format, v...)) |
||||
} |
||||
|
||||
func Fail(err error, format string, v ...any) error { |
||||
err_format := fmt.Sprintf("ERROR: %v; %s", err, format) |
||||
panic(fmt.Sprintf(err_format, v...)) |
||||
return err |
||||
err_format := fmt.Sprintf("ERROR: %v; %s", err, format) |
||||
panic(fmt.Sprintf(err_format, v...)) |
||||
return err |
||||
} |
||||
|
||||
func RenderTemplate(out io.Writer, embed string, variables any) error { |
||||
layout_path := config.Settings.Layout |
||||
layout_path := config.Settings.Layout |
||||
|
||||
layout_main, err := os.ReadFile(layout_path) |
||||
layout_main, err := os.ReadFile(layout_path) |
||||
|
||||
if err != nil { |
||||
return Fail(err, "can't read your layout file: %s", layout_path) |
||||
} |
||||
if err != nil { |
||||
return Fail(err, "can't read your layout file: %s", layout_path) |
||||
} |
||||
|
||||
tmpl := template.New(layout_path) |
||||
tmpl := template.New(layout_path) |
||||
|
||||
callbacks := template.FuncMap{ |
||||
"embed": func() string { |
||||
tmpl, err = tmpl.Parse(embed) |
||||
if err != nil { Fatal(err, "error in your template") } |
||||
out := bytes.NewBuffer(make([]byte, 0, 100)) |
||||
tmpl.Execute(out, variables) |
||||
return out.String() |
||||
}, |
||||
} |
||||
tmpl.Funcs(callbacks) |
||||
callbacks := template.FuncMap{ |
||||
"embed": func() string { |
||||
tmpl, err = tmpl.Parse(embed) |
||||
if err != nil { |
||||
Fatal(err, "error in your template") |
||||
} |
||||
out := bytes.NewBuffer(make([]byte, 0, 100)) |
||||
tmpl.Execute(out, variables) |
||||
return out.String() |
||||
}, |
||||
} |
||||
tmpl.Funcs(callbacks) |
||||
|
||||
tmpl, err = tmpl.Parse(string(layout_main)) |
||||
if err != nil { |
||||
return Fail(err, "can't parse %s", layout_path) |
||||
} |
||||
tmpl, err = tmpl.Parse(string(layout_main)) |
||||
if err != nil { |
||||
return Fail(err, "can't parse %s", layout_path) |
||||
} |
||||
|
||||
err = tmpl.Execute(out, variables) |
||||
err = tmpl.Execute(out, variables) |
||||
|
||||
return err |
||||
return err |
||||
} |
||||
|
||||
func RenderMetaFiles(meta *PageMetaData) { |
||||
fmt.Println("PAGES: ", meta.pages) |
||||
|
||||
for _, path := range config.Settings.MetaFiles { |
||||
fmt.Println(">>> META >>>>", path) |
||||
|
||||
ext := filepath.Ext(path) |
||||
target_path := RePrefixPath(path, config.Settings.Target) |
||||
|
||||
if ext == ".md" { |
||||
RenderMarkdown(path, target_path, |
||||
map[string]any{"Pages": meta.pages}) |
||||
} else if ext == ".html" { |
||||
RenderHTML(path, target_path, |
||||
map[string]any{"Pages": meta.pages}) |
||||
} |
||||
} |
||||
fmt.Println("PAGES: ", meta.pages) |
||||
|
||||
for _, path := range config.Settings.MetaFiles { |
||||
fmt.Println(">>> META >>>>", path) |
||||
|
||||
ext := filepath.Ext(path) |
||||
target_path := RePrefixPath(path, config.Settings.Target) |
||||
|
||||
if ext == ".md" { |
||||
RenderMarkdown(path, target_path, |
||||
map[string]any{"Pages": meta.pages}) |
||||
} else if ext == ".html" { |
||||
RenderHTML(path, target_path, |
||||
map[string]any{"Pages": meta.pages}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func RenderMarkdown(path string, target_path string, vars map[string]any) error { |
||||
log.Printf("MARKDOWN: %s -> %s", path, target_path) |
||||
log.Printf("MARKDOWN: %s -> %s", path, target_path) |
||||
|
||||
out, err := os.Create(target_path) |
||||
defer out.Close() |
||||
out, err := os.Create(target_path) |
||||
defer out.Close() |
||||
|
||||
if err != nil { |
||||
return Fail(err, "writing file %s", target_path) |
||||
} |
||||
if err != nil { |
||||
return Fail(err, "writing file %s", target_path) |
||||
} |
||||
|
||||
input_data, err := os.ReadFile(path) |
||||
var md_out bytes.Buffer |
||||
input_data, err := os.ReadFile(path) |
||||
var md_out bytes.Buffer |
||||
|
||||
err = goldmark.Convert(input_data, &md_out) |
||||
if err != nil { |
||||
return Fail(err, "failed converting markdown %s", path) |
||||
} |
||||
err = goldmark.Convert(input_data, &md_out) |
||||
if err != nil { |
||||
return Fail(err, "failed converting markdown %s", path) |
||||
} |
||||
|
||||
err = RenderTemplate(out, md_out.String(), vars) |
||||
err = RenderTemplate(out, md_out.String(), vars) |
||||
|
||||
if err != nil { |
||||
return Fail(err, "failed to render template %s->%s", path, target_path) |
||||
} |
||||
if err != nil { |
||||
return Fail(err, "failed to render template %s->%s", path, target_path) |
||||
} |
||||
|
||||
return err |
||||
return err |
||||
} |
||||
|
||||
func RenderHTML(source_path string, target_path string, vars map[string]any) error { |
||||
log.Printf("RENDER: %s -> %s", source_path, target_path) |
||||
log.Printf("RENDER: %s -> %s", source_path, target_path) |
||||
|
||||
out, err := os.Create(target_path) |
||||
defer out.Close() |
||||
out, err := os.Create(target_path) |
||||
defer out.Close() |
||||
|
||||
content, err := os.ReadFile(source_path) |
||||
if err != nil { |
||||
return Fail(err, "cannot open input %s", source_path) |
||||
} |
||||
content, err := os.ReadFile(source_path) |
||||
if err != nil { |
||||
return Fail(err, "cannot open input %s", source_path) |
||||
} |
||||
|
||||
err = RenderTemplate(out, string(content), vars) |
||||
err = RenderTemplate(out, string(content), vars) |
||||
|
||||
if err != nil { |
||||
return Fail(err, "writing file %s", target_path) |
||||
} |
||||
if err != nil { |
||||
return Fail(err, "writing file %s", target_path) |
||||
} |
||||
|
||||
return err |
||||
return err |
||||
} |
||||
|
||||
func MkdirPath(target_path string) error { |
||||
target_dir := filepath.Dir(target_path) |
||||
_, err := os.Stat(target_dir) |
||||
target_dir := filepath.Dir(target_path) |
||||
_, err := os.Stat(target_dir) |
||||
|
||||
if os.IsNotExist(err) { |
||||
log.Println("MAKING: ", target_dir) |
||||
err = os.MkdirAll(target_dir, 0750) |
||||
if os.IsNotExist(err) { |
||||
log.Println("MAKING: ", target_dir) |
||||
err = os.MkdirAll(target_dir, 0750) |
||||
|
||||
if err != nil { |
||||
return Fail(err, "making path to %s", target_dir) |
||||
} |
||||
} |
||||
if err != nil { |
||||
return Fail(err, "making path to %s", target_dir) |
||||
} |
||||
} |
||||
|
||||
return nil |
||||
return nil |
||||
} |
||||
|
||||
func UnfuckedPathSplit(path string) []string { |
||||
path = filepath.ToSlash(path) |
||||
// WARN: have to use strings.Split because fsnotify uses /, even on windows
|
||||
return strings.Split(path, "/")[1:] |
||||
path = filepath.ToSlash(path) |
||||
// WARN: have to use strings.Split because fsnotify uses /, even on windows
|
||||
return strings.Split(path, "/")[1:] |
||||
} |
||||
|
||||
func SplitPathExt(path string) (string, string, bool) { |
||||
split_path := UnfuckedPathSplit(path) |
||||
source_name := strings.Join(split_path, "/") // Render wants / even on windows
|
||||
split_path := UnfuckedPathSplit(path) |
||||
source_name := strings.Join(split_path, "/") // Render wants / even on windows
|
||||
|
||||
ext := filepath.Ext(source_name) |
||||
source_name, found := strings.CutSuffix(source_name, ext) |
||||
return source_name, ext, found |
||||
ext := filepath.Ext(source_name) |
||||
source_name, found := strings.CutSuffix(source_name, ext) |
||||
return source_name, ext, found |
||||
} |
||||
|
||||
func RePrefixPath(path string, new_prefix string) string { |
||||
split_path := UnfuckedPathSplit(path) |
||||
split_path := UnfuckedPathSplit(path) |
||||
|
||||
prefixed_path := append([]string{new_prefix}, split_path...) |
||||
prefixed_path := append([]string{new_prefix}, split_path...) |
||||
|
||||
res := filepath.Join(prefixed_path...) |
||||
return res |
||||
res := filepath.Join(prefixed_path...) |
||||
return res |
||||
} |
||||
|
||||
func SamePath(a string, b string) bool { |
||||
return filepath.ToSlash(a) == filepath.ToSlash(b) |
||||
return filepath.ToSlash(a) == filepath.ToSlash(b) |
||||
} |
||||
|
||||
func ProcessDirEntry(path string, d fs.DirEntry, meta *PageMetaData) error { |
||||
settings := config.Settings |
||||
var err error = nil |
||||
settings := config.Settings |
||||
var err error = nil |
||||
|
||||
if !d.IsDir() && !SamePath(path, config.Settings.Layout) { |
||||
source_name, ext, found := SplitPathExt(path) |
||||
if !d.IsDir() && !SamePath(path, config.Settings.Layout) { |
||||
source_name, ext, found := SplitPathExt(path) |
||||
|
||||
if found && path != settings.Layout { |
||||
target_path := RePrefixPath(path, settings.Target) |
||||
if found && path != settings.Layout { |
||||
target_path := RePrefixPath(path, settings.Target) |
||||
|
||||
err = MkdirPath(target_path) |
||||
if err != nil { |
||||
return Fail(err, "making target path: %s", target_path) |
||||
} |
||||
err = MkdirPath(target_path) |
||||
if err != nil { |
||||
return Fail(err, "making target path: %s", target_path) |
||||
} |
||||
|
||||
// generate a data-testid for all pages based on template name
|
||||
page_id := strings.ReplaceAll(source_name, "/", "-") + "-page" |
||||
// generate a data-testid for all pages based on template name
|
||||
page_id := strings.ReplaceAll(source_name, "/", "-") + "-page" |
||||
|
||||
if ext == ".html" { |
||||
err = RenderHTML(path, target_path, |
||||
map[string]any{"PageId": page_id}) |
||||
if ext == ".html" { |
||||
err = RenderHTML(path, target_path, |
||||
map[string]any{"PageId": page_id}) |
||||
|
||||
if err != nil { |
||||
return Fail(err, "failed to render %s", path) |
||||
} |
||||
if err != nil { |
||||
return Fail(err, "failed to render %s", path) |
||||
} |
||||
|
||||
meta.AddPage(target_path) |
||||
} else if ext == ".md" { |
||||
// need to strip the .md and replace with .html
|
||||
html_name, _ := strings.CutSuffix(target_path, ext) |
||||
html_name = fmt.Sprintf("%s.html", html_name) |
||||
meta.AddPage(target_path) |
||||
} else if ext == ".md" { |
||||
// need to strip the .md and replace with .html
|
||||
html_name, _ := strings.CutSuffix(target_path, ext) |
||||
html_name = fmt.Sprintf("%s.html", html_name) |
||||
|
||||
RenderMarkdown(path, html_name, |
||||
map[string]any{"PageId": page_id}) |
||||
RenderMarkdown(path, html_name, |
||||
map[string]any{"PageId": page_id}) |
||||
|
||||
if err != nil { |
||||
return Fail(err, "failed to render markdown %s", path) |
||||
} |
||||
if err != nil { |
||||
return Fail(err, "failed to render markdown %s", path) |
||||
} |
||||
|
||||
meta.AddPage(html_name) |
||||
} |
||||
} |
||||
} |
||||
meta.AddPage(html_name) |
||||
} |
||||
} |
||||
} |
||||
|
||||
return nil |
||||
return nil |
||||
} |
||||
|
||||
func SyncStaticDir() { |
||||
target := config.Settings.Target |
||||
sync_dir := config.Settings.SyncDir |
||||
if sync_dir == "" { |
||||
return |
||||
} |
||||
|
||||
log.Printf("removing target directory: %s", target) |
||||
|
||||
err := os.RemoveAll(target) |
||||
if err != nil { |
||||
Fatal(err, "can't remove target directory: %s", target) |
||||
} |
||||
|
||||
err = os.MkdirAll(target, 0750) |
||||
if err != nil { |
||||
Fatal(err, "can't recreate target directory: %s", target) |
||||
} |
||||
|
||||
source := os.DirFS(sync_dir) |
||||
|
||||
log.Printf("SYNC %s -> %s", sync_dir, target) |
||||
err = os.CopyFS(target, source) |
||||
if err != nil { |
||||
Fatal(err, "can't sync %s to target directory: %s", sync_dir, target) |
||||
} |
||||
target := config.Settings.Target |
||||
sync_dir := config.Settings.SyncDir |
||||
if sync_dir == "" { |
||||
return |
||||
} |
||||
|
||||
log.Printf("removing target directory: %s", target) |
||||
|
||||
err := os.RemoveAll(target) |
||||
if err != nil { |
||||
Fatal(err, "can't remove target directory: %s", target) |
||||
} |
||||
|
||||
err = os.MkdirAll(target, 0750) |
||||
if err != nil { |
||||
Fatal(err, "can't recreate target directory: %s", target) |
||||
} |
||||
|
||||
source := os.DirFS(sync_dir) |
||||
|
||||
log.Printf("SYNC %s -> %s", sync_dir, target) |
||||
err = os.CopyFS(target, source) |
||||
if err != nil { |
||||
Fatal(err, "can't sync %s to target directory: %s", sync_dir, target) |
||||
} |
||||
} |
||||
|
||||
func RenderPages() { |
||||
meta := new(PageMetaData) |
||||
meta := new(PageMetaData) |
||||
|
||||
err := filepath.WalkDir(config.Settings.Views, |
||||
func(path string, d fs.DirEntry, err error) error { |
||||
if err != nil { return err } |
||||
err := filepath.WalkDir(config.Settings.Views, |
||||
func(path string, d fs.DirEntry, err error) error { |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
err = ProcessDirEntry(path, d, meta) |
||||
if err != nil { return Fail(err, "failed to process %s", path) } |
||||
err = ProcessDirEntry(path, d, meta) |
||||
if err != nil { |
||||
return Fail(err, "failed to process %s", path) |
||||
} |
||||
|
||||
return err |
||||
}) |
||||
return err |
||||
}) |
||||
|
||||
if err != nil { |
||||
Fatal(err, "can't walk content") |
||||
} |
||||
if err != nil { |
||||
Fatal(err, "can't walk content") |
||||
} |
||||
|
||||
RenderMetaFiles(meta) |
||||
RenderMetaFiles(meta) |
||||
} |
||||
|
||||
func WatchMatches(name string) bool { |
||||
is_static := strings.Index(name, config.Settings.SyncDir) == 0 |
||||
return is_static || filepath.Ext(name) == ".html" || filepath.Ext(name) == ".md" |
||||
is_static := strings.Index(name, config.Settings.SyncDir) == 0 |
||||
return is_static || filepath.Ext(name) == ".html" || filepath.Ext(name) == ".md" |
||||
} |
||||
|
||||
func AddWatchDir(watcher *fsnotify.Watcher, name string) error { |
||||
return filepath.WalkDir(name, |
||||
func(path string, d fs.DirEntry, err error) error { |
||||
if err != nil { |
||||
log.Printf("WATCH ERROR! walking=%s path=%s: err=%v", name, path, err) |
||||
return err |
||||
} |
||||
|
||||
if d.IsDir() { |
||||
log.Println("WATCHING: ", path) |
||||
err = watcher.Add(path) |
||||
if err != nil { |
||||
log.Printf("failed to watch %s", path) |
||||
return err |
||||
} |
||||
} |
||||
|
||||
return nil |
||||
}) |
||||
return filepath.WalkDir(name, |
||||
func(path string, d fs.DirEntry, err error) error { |
||||
if err != nil { |
||||
log.Printf("WATCH ERROR! walking=%s path=%s: err=%v", name, path, err) |
||||
return err |
||||
} |
||||
|
||||
if d.IsDir() { |
||||
log.Println("WATCHING: ", path) |
||||
err = watcher.Add(path) |
||||
if err != nil { |
||||
log.Printf("failed to watch %s", path) |
||||
return err |
||||
} |
||||
} |
||||
|
||||
return nil |
||||
}) |
||||
} |
||||
|
||||
func WatchDir() { |
||||
watcher, err := fsnotify.NewWatcher() |
||||
if err != nil { |
||||
Fatal(err, "can't create new watcher") |
||||
} |
||||
|
||||
defer watcher.Close() |
||||
|
||||
wait_time, err := time.ParseDuration(config.Settings.WatchDelay) |
||||
if err != nil { |
||||
Fatal(err, |
||||
"can't parse watch_delay setting: %s", |
||||
config.Settings.WatchDelay) |
||||
} |
||||
|
||||
doit := time.NewTimer(wait_time) |
||||
doit.Stop() |
||||
|
||||
go func() { |
||||
for { |
||||
select { |
||||
case event, ok := <-watcher.Events: |
||||
if !ok { |
||||
return |
||||
} |
||||
|
||||
if event.Has(fsnotify.Create) { |
||||
log.Println("---> CREATE IS:", event.Name) |
||||
AddWatchDir(watcher, event.Name) |
||||
} else { |
||||
log.Println("event: ", event) |
||||
} |
||||
|
||||
if WatchMatches(event.Name) { |
||||
log.Println("modified file: ", event.Name) |
||||
doit.Reset(wait_time) |
||||
} |
||||
case <-doit.C: |
||||
SyncStaticDir() |
||||
RenderPages() |
||||
case err, ok := <-watcher.Errors: |
||||
if !ok { |
||||
return |
||||
} |
||||
log.Println("error: ", err) |
||||
} |
||||
} |
||||
}() |
||||
|
||||
err = AddWatchDir(watcher, config.Settings.Views) |
||||
if err != nil { |
||||
Fatal(err, "failed to watch %s", config.Settings.Views) |
||||
} |
||||
|
||||
err = AddWatchDir(watcher, filepath.Dir(config.Settings.Layout)) |
||||
if err != nil { |
||||
Fatal(err, "failed to watch %s", filepath.Dir(config.Settings.Layout)) |
||||
} |
||||
|
||||
if config.Settings.SyncDir != "" { |
||||
err = AddWatchDir(watcher, config.Settings.SyncDir) |
||||
if err != nil { |
||||
Fatal(err, "failed to watch %s", config.Settings.SyncDir) |
||||
} |
||||
} |
||||
|
||||
<-make(chan struct{}) |
||||
watcher, err := fsnotify.NewWatcher() |
||||
if err != nil { |
||||
Fatal(err, "can't create new watcher") |
||||
} |
||||
|
||||
defer watcher.Close() |
||||
|
||||
wait_time, err := time.ParseDuration(config.Settings.WatchDelay) |
||||
if err != nil { |
||||
Fatal(err, |
||||
"can't parse watch_delay setting: %s", |
||||
config.Settings.WatchDelay) |
||||
} |
||||
|
||||
doit := time.NewTimer(wait_time) |
||||
doit.Stop() |
||||
|
||||
go func() { |
||||
for { |
||||
select { |
||||
case event, ok := <-watcher.Events: |
||||
if !ok { |
||||
return |
||||
} |
||||
|
||||
if event.Has(fsnotify.Create) { |
||||
log.Println("---> CREATE IS:", event.Name) |
||||
AddWatchDir(watcher, event.Name) |
||||
} else { |
||||
log.Println("event: ", event) |
||||
} |
||||
|
||||
if WatchMatches(event.Name) { |
||||
log.Println("modified file: ", event.Name) |
||||
doit.Reset(wait_time) |
||||
} |
||||
case <-doit.C: |
||||
SyncStaticDir() |
||||
RenderPages() |
||||
case err, ok := <-watcher.Errors: |
||||
if !ok { |
||||
return |
||||
} |
||||
log.Println("error: ", err) |
||||
} |
||||
} |
||||
}() |
||||
|
||||
err = AddWatchDir(watcher, config.Settings.Views) |
||||
if err != nil { |
||||
Fatal(err, "failed to watch %s", config.Settings.Views) |
||||
} |
||||
|
||||
err = AddWatchDir(watcher, filepath.Dir(config.Settings.Layout)) |
||||
if err != nil { |
||||
Fatal(err, "failed to watch %s", filepath.Dir(config.Settings.Layout)) |
||||
} |
||||
|
||||
if config.Settings.SyncDir != "" { |
||||
err = AddWatchDir(watcher, config.Settings.SyncDir) |
||||
if err != nil { |
||||
Fatal(err, "failed to watch %s", config.Settings.SyncDir) |
||||
} |
||||
} |
||||
|
||||
<-make(chan struct{}) |
||||
} |
||||
|
||||
func InitConfig(config_file string) { |
||||
_, err := os.Stat(config_file) |
||||
|
||||
if os.IsNotExist(err) { |
||||
out, err := os.Create(config_file) |
||||
if err != nil { |
||||
Fatal(err, "error opening %s", config_file) |
||||
} |
||||
defer out.Close() |
||||
|
||||
out.WriteString(DEFAULT_CONFIG) |
||||
fmt.Println("new config written to:", config_file) |
||||
} else { |
||||
Fatal(err, "there's already a %s file here", config_file) |
||||
} |
||||
_, err := os.Stat(config_file) |
||||
|
||||
if os.IsNotExist(err) { |
||||
out, err := os.Create(config_file) |
||||
if err != nil { |
||||
Fatal(err, "error opening %s", config_file) |
||||
} |
||||
defer out.Close() |
||||
|
||||
out.WriteString(DEFAULT_CONFIG) |
||||
fmt.Println("new config written to:", config_file) |
||||
} else { |
||||
Fatal(err, "there's already a %s file here", config_file) |
||||
} |
||||
} |
||||
|
||||
func main() { |
||||
var config_file string |
||||
|
||||
flag.StringVar(&config_file, "config", ".ssgod.json", ".json config file to use") |
||||
flag.Parse() |
||||
command := flag.Arg(0) |
||||
|
||||
switch command { |
||||
case "watch": |
||||
config.Load(config_file) |
||||
SyncStaticDir() |
||||
RenderPages() |
||||
WatchDir() |
||||
case "init": |
||||
InitConfig(config_file) |
||||
default: |
||||
config.Load(config_file) |
||||
SyncStaticDir() |
||||
RenderPages() |
||||
} |
||||
var config_file string |
||||
|
||||
flag.StringVar(&config_file, "config", ".ssgod.json", ".json config file to use") |
||||
flag.Parse() |
||||
command := flag.Arg(0) |
||||
|
||||
switch command { |
||||
case "watch": |
||||
config.Load(config_file) |
||||
SyncStaticDir() |
||||
RenderPages() |
||||
WatchDir() |
||||
case "init": |
||||
InitConfig(config_file) |
||||
default: |
||||
config.Load(config_file) |
||||
SyncStaticDir() |
||||
RenderPages() |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue