Jekyll; progresses on #108
Former-commit-id: 05caf8c6dd2df09d064a14c034e221151a2dd341 [formerly df5cbcf51aa8a2e76e39d73f30f4e63f222bd70f] [formerly 3fbf8281b93fed6c16cd7c8f810dccdf1f7347d6 [formerly fe80e98f85
]]
Former-commit-id: b1d034b6c7ee1ce445bd53039ce0306f2b2b7651 [formerly 7b3c5571c7647ae4d4f25f46e66df49aa0e3320c]
Former-commit-id: 0f57d274deaeae52b9da52d8f6495070caba6ee7
pull/726/head
parent
aaf6d60c3c
commit
2462346e56
|
@ -111,6 +111,7 @@ func parse(c *caddy.Controller) ([]*filemanager.FileManager, error) {
|
||||||
AllowCommands: true,
|
AllowCommands: true,
|
||||||
AllowEdit: true,
|
AllowEdit: true,
|
||||||
AllowNew: true,
|
AllowNew: true,
|
||||||
|
AllowPublish: true,
|
||||||
Commands: []string{"git", "svn", "hg"},
|
Commands: []string{"git", "svn", "hg"},
|
||||||
Rules: []*filemanager.Rule{{
|
Rules: []*filemanager.Rule{{
|
||||||
Regex: true,
|
Regex: true,
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
package jekyll
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hacdias/filemanager"
|
||||||
|
"github.com/hacdias/fileutils"
|
||||||
|
"github.com/mholt/caddy"
|
||||||
|
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setup configures a new FileManager middleware instance.
|
||||||
|
func setup(c *caddy.Controller) error {
|
||||||
|
configs, err := parse(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
|
||||||
|
return plugin{Configs: configs, Next: next}
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse(c *caddy.Controller) ([]*filemanager.FileManager, error) {
|
||||||
|
var (
|
||||||
|
configs []*filemanager.FileManager
|
||||||
|
)
|
||||||
|
|
||||||
|
for c.Next() {
|
||||||
|
// jekyll [directory] [admin] {
|
||||||
|
// database path
|
||||||
|
// }
|
||||||
|
directory := "."
|
||||||
|
admin := "/admin"
|
||||||
|
database := ""
|
||||||
|
noAuth := false
|
||||||
|
|
||||||
|
// Get the baseURL and baseScope
|
||||||
|
args := c.RemainingArgs()
|
||||||
|
|
||||||
|
if len(args) >= 1 {
|
||||||
|
directory = args[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 1 {
|
||||||
|
admin = args[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
for c.NextBlock() {
|
||||||
|
switch c.Val() {
|
||||||
|
case "database":
|
||||||
|
if !c.NextArg() {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
|
||||||
|
database = c.Val()
|
||||||
|
case "no_auth":
|
||||||
|
if !c.NextArg() {
|
||||||
|
noAuth = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
noAuth, err = strconv.ParseBool(c.Val())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
caddyConf := httpserver.GetConfig(c)
|
||||||
|
|
||||||
|
path := filepath.Join(caddy.AssetsPath(), "jekyll")
|
||||||
|
err := os.MkdirAll(path, 0700)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is a database path and it is not absolute,
|
||||||
|
// it will be relative to ".caddy" folder.
|
||||||
|
if !filepath.IsAbs(database) && database != "" {
|
||||||
|
database = filepath.Join(path, database)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is no database path on the settings,
|
||||||
|
// store one in .caddy/jekyll/{name}.db.
|
||||||
|
if database == "" {
|
||||||
|
// The name of the database is the hashed value of a string composed
|
||||||
|
// by the host, address path and the baseurl of this File Manager
|
||||||
|
// instance.
|
||||||
|
hasher := md5.New()
|
||||||
|
hasher.Write([]byte(caddyConf.Addr.Host + caddyConf.Addr.Path + admin))
|
||||||
|
sha := hex.EncodeToString(hasher.Sum(nil))
|
||||||
|
database = filepath.Join(path, sha+".db")
|
||||||
|
|
||||||
|
fmt.Println("[WARNING] A database is going to be created for your Jekyll instace at " + database +
|
||||||
|
". It is highly recommended that you set the 'database' option to '" + sha + ".db'\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := filemanager.New(database, filemanager.User{
|
||||||
|
Locale: "en",
|
||||||
|
AllowCommands: true,
|
||||||
|
AllowEdit: true,
|
||||||
|
AllowNew: true,
|
||||||
|
AllowPublish: true,
|
||||||
|
Commands: []string{"git", "svn", "hg"},
|
||||||
|
Rules: []*filemanager.Rule{{
|
||||||
|
Regex: true,
|
||||||
|
Allow: false,
|
||||||
|
Regexp: &filemanager.Regexp{Raw: "\\/\\..+"},
|
||||||
|
}},
|
||||||
|
CSS: "",
|
||||||
|
FileSystem: fileutils.Dir(directory),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the default settings for Jekyll.
|
||||||
|
jekyll := &filemanager.Jekyll{
|
||||||
|
Root: directory,
|
||||||
|
Public: filepath.Join(directory, "_site"),
|
||||||
|
Args: []string{},
|
||||||
|
CleanPublic: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attaches Hugo plugin to this file manager instance.
|
||||||
|
err = m.EnableStaticGen(jekyll)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m.NoAuth = noAuth
|
||||||
|
m.SetBaseURL(admin)
|
||||||
|
m.SetPrefixURL(strings.TrimSuffix(caddyConf.Addr.Path, "/"))
|
||||||
|
configs = append(configs, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return configs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met.
|
||||||
|
func (p plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
for i := range p.Configs {
|
||||||
|
// Checks if this Path should be handled by File Manager.
|
||||||
|
if !httpserver.Path(r.URL.Path).Matches(p.Configs[i].BaseURL) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Configs[i].ServeHTTP(w, r)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.Next.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
caddy.RegisterPlugin("jekyll", caddy.Plugin{
|
||||||
|
ServerType: "http",
|
||||||
|
Action: setup,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type plugin struct {
|
||||||
|
Next httpserver.Handler
|
||||||
|
Configs []*filemanager.FileManager
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ var (
|
||||||
allowCommands bool
|
allowCommands bool
|
||||||
allowEdit bool
|
allowEdit bool
|
||||||
allowNew bool
|
allowNew bool
|
||||||
|
allowPublish bool
|
||||||
showVer bool
|
showVer bool
|
||||||
version = "master"
|
version = "master"
|
||||||
)
|
)
|
||||||
|
@ -46,6 +47,7 @@ func init() {
|
||||||
flag.StringVar(&commands, "commands", "git svn hg", "Default commands option for new users")
|
flag.StringVar(&commands, "commands", "git svn hg", "Default commands option for new users")
|
||||||
flag.BoolVar(&allowCommands, "allow-commands", true, "Default allow commands option for new users")
|
flag.BoolVar(&allowCommands, "allow-commands", true, "Default allow commands option for new users")
|
||||||
flag.BoolVar(&allowEdit, "allow-edit", true, "Default allow edit option for new users")
|
flag.BoolVar(&allowEdit, "allow-edit", true, "Default allow edit option for new users")
|
||||||
|
flag.BoolVar(&allowPublish, "allow-publish", true, "Default allow publish option for new users")
|
||||||
flag.BoolVar(&allowNew, "allow-new", true, "Default allow new option for new users")
|
flag.BoolVar(&allowNew, "allow-new", true, "Default allow new option for new users")
|
||||||
flag.BoolVar(&noAuth, "no-auth", false, "Disables authentication")
|
flag.BoolVar(&noAuth, "no-auth", false, "Disables authentication")
|
||||||
flag.StringVar(&locale, "locale", "en", "Default locale for new users")
|
flag.StringVar(&locale, "locale", "en", "Default locale for new users")
|
||||||
|
@ -63,6 +65,7 @@ func setupViper() {
|
||||||
viper.SetDefault("AllowCommmands", true)
|
viper.SetDefault("AllowCommmands", true)
|
||||||
viper.SetDefault("AllowEdit", true)
|
viper.SetDefault("AllowEdit", true)
|
||||||
viper.SetDefault("AllowNew", true)
|
viper.SetDefault("AllowNew", true)
|
||||||
|
viper.SetDefault("AllowPublish", true)
|
||||||
viper.SetDefault("StaticGen", "")
|
viper.SetDefault("StaticGen", "")
|
||||||
viper.SetDefault("Locale", "en")
|
viper.SetDefault("Locale", "en")
|
||||||
viper.SetDefault("NoAuth", false)
|
viper.SetDefault("NoAuth", false)
|
||||||
|
@ -76,6 +79,7 @@ func setupViper() {
|
||||||
viper.BindPFlag("AllowCommands", flag.Lookup("allow-commands"))
|
viper.BindPFlag("AllowCommands", flag.Lookup("allow-commands"))
|
||||||
viper.BindPFlag("AllowEdit", flag.Lookup("allow-edit"))
|
viper.BindPFlag("AllowEdit", flag.Lookup("allow-edit"))
|
||||||
viper.BindPFlag("AlowNew", flag.Lookup("allow-new"))
|
viper.BindPFlag("AlowNew", flag.Lookup("allow-new"))
|
||||||
|
viper.BindPFlag("AllowPublish", flag.Lookup("allow-publish"))
|
||||||
viper.BindPFlag("Locale", flag.Lookup("locale"))
|
viper.BindPFlag("Locale", flag.Lookup("locale"))
|
||||||
viper.BindPFlag("StaticGen", flag.Lookup("staticgen"))
|
viper.BindPFlag("StaticGen", flag.Lookup("staticgen"))
|
||||||
viper.BindPFlag("NoAuth", flag.Lookup("no-auth"))
|
viper.BindPFlag("NoAuth", flag.Lookup("no-auth"))
|
||||||
|
@ -149,6 +153,7 @@ func main() {
|
||||||
AllowCommands: viper.GetBool("AllowCommands"),
|
AllowCommands: viper.GetBool("AllowCommands"),
|
||||||
AllowEdit: viper.GetBool("AllowEdit"),
|
AllowEdit: viper.GetBool("AllowEdit"),
|
||||||
AllowNew: viper.GetBool("AllowNew"),
|
AllowNew: viper.GetBool("AllowNew"),
|
||||||
|
AllowPublish: viper.GetBool("AllowPublish"),
|
||||||
Commands: viper.GetStringSlice("Commands"),
|
Commands: viper.GetStringSlice("Commands"),
|
||||||
Rules: []*filemanager.Rule{},
|
Rules: []*filemanager.Rule{},
|
||||||
Locale: viper.GetString("Locale"),
|
Locale: viper.GetString("Locale"),
|
||||||
|
@ -164,8 +169,8 @@ func main() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if viper.GetString("StaticGen") == "hugo" {
|
switch viper.GetString("StaticGen") {
|
||||||
// Initialize the default settings for Hugo.
|
case "hugo":
|
||||||
hugo := &filemanager.Hugo{
|
hugo := &filemanager.Hugo{
|
||||||
Root: viper.GetString("Scope"),
|
Root: viper.GetString("Scope"),
|
||||||
Public: filepath.Join(viper.GetString("Scope"), "public"),
|
Public: filepath.Join(viper.GetString("Scope"), "public"),
|
||||||
|
@ -176,6 +181,17 @@ func main() {
|
||||||
if err = fm.EnableStaticGen(hugo); err != nil {
|
if err = fm.EnableStaticGen(hugo); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
case "jekyll":
|
||||||
|
jekyll := &filemanager.Jekyll{
|
||||||
|
Root: viper.GetString("Scope"),
|
||||||
|
Public: filepath.Join(viper.GetString("Scope"), "_site"),
|
||||||
|
Args: []string{"build"},
|
||||||
|
CleanPublic: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = fm.EnableStaticGen(jekyll); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builds the address and a listener.
|
// Builds the address and a listener.
|
||||||
|
|
|
@ -289,6 +289,7 @@ func New(database string, base User) (*FileManager, error) {
|
||||||
u.AllowCommands = true
|
u.AllowCommands = true
|
||||||
u.AllowNew = true
|
u.AllowNew = true
|
||||||
u.AllowEdit = true
|
u.AllowEdit = true
|
||||||
|
u.AllowPublish = true
|
||||||
|
|
||||||
// Saves the user to the database.
|
// Saves the user to the database.
|
||||||
if err := db.Save(&u); err != nil {
|
if err := db.Save(&u); err != nil {
|
||||||
|
@ -365,20 +366,48 @@ func (m *FileManager) EnableStaticGen(data StaticGen) error {
|
||||||
return m.enableHugo(h)
|
return m.enableHugo(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if j, ok := data.(*Jekyll); ok {
|
||||||
|
return m.enableJekyll(j)
|
||||||
|
}
|
||||||
|
|
||||||
return errors.New("unknown static website generator")
|
return errors.New("unknown static website generator")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FileManager) enableHugo(hugo *Hugo) error {
|
func (m *FileManager) enableHugo(h *Hugo) error {
|
||||||
if err := hugo.find(); err != nil {
|
if err := h.find(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
m.staticgen = "hugo"
|
m.staticgen = "hugo"
|
||||||
m.StaticGen = hugo
|
m.StaticGen = h
|
||||||
|
|
||||||
err := m.db.Get("staticgen", "hugo", hugo)
|
err := m.db.Get("staticgen", "hugo", h)
|
||||||
if err != nil && err == storm.ErrNotFound {
|
if err != nil && err == storm.ErrNotFound {
|
||||||
err = m.db.Set("staticgen", "hugo", *hugo)
|
err = m.db.Set("staticgen", "hugo", *h)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FileManager) enableJekyll(j *Jekyll) error {
|
||||||
|
if err := j.find(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(j.Args) == 0 {
|
||||||
|
j.Args = []string{"build"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if j.Args[0] != "build" {
|
||||||
|
j.Args = append([]string{"build"}, j.Args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.staticgen = "jekyll"
|
||||||
|
m.StaticGen = j
|
||||||
|
|
||||||
|
err := m.db.Get("staticgen", "jekyll", j)
|
||||||
|
if err != nil && err == storm.ErrNotFound {
|
||||||
|
err = m.db.Set("staticgen", "jekyll", *j)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
fb7f000455844aaf5021aa2a43f0fcd05f67fa35
|
d12113f698d3e44cb873181f6e7d7c9e17de30ac
|
136
staticgen.go
136
staticgen.go
|
@ -16,8 +16,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrHugoNotFound ...
|
|
||||||
ErrHugoNotFound = errors.New("It seems that tou don't have 'hugo' on your PATH")
|
|
||||||
// ErrUnsupportedFileType ...
|
// ErrUnsupportedFileType ...
|
||||||
ErrUnsupportedFileType = errors.New("The type of the provided file isn't supported for this action")
|
ErrUnsupportedFileType = errors.New("The type of the provided file isn't supported for this action")
|
||||||
)
|
)
|
||||||
|
@ -119,7 +117,6 @@ func (h Hugo) Publish(c *RequestContext, w http.ResponseWriter, r *http.Request)
|
||||||
if err := h.undraft(filename); err != nil {
|
if err := h.undraft(filename); err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regenerates the file
|
// Regenerates the file
|
||||||
|
@ -219,7 +216,138 @@ func (h Hugo) undraft(file string) error {
|
||||||
func (h *Hugo) find() error {
|
func (h *Hugo) find() error {
|
||||||
var err error
|
var err error
|
||||||
if h.Exe, err = exec.LookPath("hugo"); err != nil {
|
if h.Exe, err = exec.LookPath("hugo"); err != nil {
|
||||||
return ErrHugoNotFound
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jekyll is the Jekyll static website generator.
|
||||||
|
type Jekyll struct {
|
||||||
|
// Website root
|
||||||
|
Root string `name:"Website Root"`
|
||||||
|
// Public folder
|
||||||
|
Public string `name:"Public Directory"`
|
||||||
|
// Jekyll executable path
|
||||||
|
Exe string `name:"Executable"`
|
||||||
|
// Jekyll arguments
|
||||||
|
Args []string `name:"Arguments"`
|
||||||
|
// Indicates if we should clean public before a new publish.
|
||||||
|
CleanPublic bool `name:"Clean Public"`
|
||||||
|
// previewPath is the temporary path for a preview
|
||||||
|
previewPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// SettingsPath retrieves the correct settings path.
|
||||||
|
func (j Jekyll) SettingsPath() string {
|
||||||
|
return "/_config.yml"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook is the pre-api handler.
|
||||||
|
func (j Jekyll) Hook(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish publishes a post.
|
||||||
|
func (j Jekyll) Publish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
filename := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
||||||
|
|
||||||
|
// Before save command handler.
|
||||||
|
if err := c.Runner("before_publish", filename); err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only run undraft command if it is a file.
|
||||||
|
if err := j.undraft(filename); err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regenerates the file
|
||||||
|
j.run()
|
||||||
|
|
||||||
|
// Executed the before publish command.
|
||||||
|
if err := c.Runner("before_publish", filename); err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule schedules a post.
|
||||||
|
func (j Jekyll) Schedule(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
t, err := time.Parse("2006-01-02T15:04", r.Header.Get("Schedule"))
|
||||||
|
path := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
||||||
|
path = filepath.Clean(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler := cron.New()
|
||||||
|
scheduler.AddFunc(t.Format("05 04 15 02 01 *"), func() {
|
||||||
|
if err := j.undraft(path); err != nil {
|
||||||
|
log.Printf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
j.run()
|
||||||
|
})
|
||||||
|
|
||||||
|
scheduler.Start()
|
||||||
|
return http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preview handles the preview path.
|
||||||
|
func (j *Jekyll) Preview(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
// Get a new temporary path if there is none.
|
||||||
|
if j.previewPath == "" {
|
||||||
|
path, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
j.previewPath = path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the arguments to execute Hugo: change the base URL,
|
||||||
|
// build the drafts and update the destination.
|
||||||
|
args := j.Args
|
||||||
|
args = append(args, "--baseurl", c.RootURL()+"/preview/")
|
||||||
|
args = append(args, "--drafts")
|
||||||
|
args = append(args, "--destination", j.previewPath)
|
||||||
|
|
||||||
|
// Builds the preview.
|
||||||
|
if err := runCommand(j.Exe, args, j.Root); err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serves the temporary path with the preview.
|
||||||
|
http.FileServer(http.Dir(j.previewPath)).ServeHTTP(w, r)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j Jekyll) run() {
|
||||||
|
// If the CleanPublic option is enabled, clean it.
|
||||||
|
if j.CleanPublic {
|
||||||
|
os.RemoveAll(j.Public)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := runCommand(j.Exe, j.Args, j.Root); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j Jekyll) undraft(file string) error {
|
||||||
|
if !strings.Contains(file, "_drafts") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.Rename(file, strings.Replace(file, "_drafts", "_posts", 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *Jekyll) find() error {
|
||||||
|
var err error
|
||||||
|
if j.Exe, err = exec.LookPath("jekyll"); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue