1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-30 07:08:59 +01:00

Move from urfave CLI -> Kingpin

This commit is contained in:
Oliver Steele 2017-06-21 13:14:30 -04:00
parent 1142e00733
commit 2ff73da9c3
2 changed files with 96 additions and 142 deletions

View File

@ -9,7 +9,6 @@ import (
"strings"
"time"
"gopkg.in/urfave/cli.v1"
yaml "gopkg.in/yaml.v2"
"github.com/osteele/gojekyll"
@ -19,7 +18,7 @@ import (
// main sets this
var commandStartTime = time.Now()
func buildCommand(c *cli.Context, site *gojekyll.Site) error {
func buildCommand(site *gojekyll.Site) error {
printPathSetting("Destination:", site.Destination)
printSetting("Generating...", "")
if buildOptions.DryRun {
@ -34,7 +33,7 @@ func buildCommand(c *cli.Context, site *gojekyll.Site) error {
return nil
}
func profileCommand(c *cli.Context, _ *gojekyll.Site) error {
func profileCommand(_ *gojekyll.Site) error {
printSetting("Profiling...", "")
var profilePath = "gojekyll.prof"
f, err := os.Create(profilePath)
@ -46,7 +45,7 @@ func profileCommand(c *cli.Context, _ *gojekyll.Site) error {
}
t0 := time.Now()
for i := 0; time.Since(t0) < 10*time.Second; i++ {
site, err := loadSite(c.GlobalString("source"), c.GlobalString("destination"))
site, err := loadSite(*source, *destination)
if err != nil {
return err
}
@ -64,12 +63,12 @@ func profileCommand(c *cli.Context, _ *gojekyll.Site) error {
return nil
}
func serveCommand(c *cli.Context, site *gojekyll.Site) error {
func serveCommand(site *gojekyll.Site) error {
server := gojekyll.Server{Site: site}
return server.Run(printSetting)
}
func varsCommand(c *cli.Context, site *gojekyll.Site) error {
func varsCommand(site *gojekyll.Site) error {
printSetting("Variables:", "")
siteData := site.Variables
// The YAML representation including collections is impractically large for debugging.
@ -80,15 +79,15 @@ func varsCommand(c *cli.Context, site *gojekyll.Site) error {
}
var data interface{} //gojekyll.VariableMap
switch {
case c.Bool("site"):
case *siteVariable:
data = siteData
case c.Bool("data"):
case *dataVariable:
data = siteData["data"].(gojekyll.VariableMap)
if c.NArg() >= 1 {
data = data.(gojekyll.VariableMap)[c.Args().Get(0)]
if *variablePath != "" {
data = data.(gojekyll.VariableMap)[*variablePath]
}
default:
page, err := cliPage(c, site)
page, err := cliPage(site, *variablePath)
if err != nil {
return err
}
@ -102,11 +101,11 @@ func varsCommand(c *cli.Context, site *gojekyll.Site) error {
return nil
}
func routesCommand(c *cli.Context, site *gojekyll.Site) error {
func routesCommand(site *gojekyll.Site) error {
printSetting("Routes:", "")
urls := []string{}
for u, p := range site.Paths {
if !(c.Bool("dynamic") && p.Static()) {
if !(*dynamicRoutes && p.Static()) {
urls = append(urls, u)
}
}
@ -117,8 +116,8 @@ func routesCommand(c *cli.Context, site *gojekyll.Site) error {
return nil
}
func renderCommand(c *cli.Context, site *gojekyll.Site) error {
page, err := cliPage(c, site)
func renderCommand(site *gojekyll.Site) error {
page, err := cliPage(site, *renderPath)
if err != nil {
return err
}
@ -133,10 +132,10 @@ func renderCommand(c *cli.Context, site *gojekyll.Site) error {
// If path starts with /, it's a URL path. Else it's a file path relative
// to the site source directory.
func cliPage(c *cli.Context, site *gojekyll.Site) (page gojekyll.Page, err error) {
func cliPage(site *gojekyll.Site, path string) (page gojekyll.Page, err error) {
arg := "/"
if c.NArg() > 0 {
arg = c.Args().Get(0)
if path != "" {
arg = path
}
if strings.HasPrefix(arg, "/") {
page, _ = site.PageForURL(arg)
@ -151,36 +150,3 @@ func cliPage(c *cli.Context, site *gojekyll.Site) (page gojekyll.Page, err error
}
return
}
// Load the site specified at destination into the site global, and print the common banner settings.
func loadSite(source, destination string) (*gojekyll.Site, error) {
site, err := gojekyll.NewSiteFromDirectory(source)
if err != nil {
return nil, err
}
site.UseRemoteLiquidEngine = useRemoteLiquidEngine
if destination != "" {
site.Destination = destination
}
if site.ConfigFile != nil {
printPathSetting(configurationFileLabel, *site.ConfigFile)
} else {
printSetting(configurationFileLabel, "none")
}
printPathSetting("Source:", site.Source)
return site, site.Load()
}
// Given a subcommand function, load the site and then call the subcommand.
func loadSiteAndRun(siteLoader func() (*gojekyll.Site, error), cmd func(*cli.Context, *gojekyll.Site) error) func(*cli.Context) error {
return func(c *cli.Context) error {
site, err := siteLoader()
if err != nil {
return cli.NewExitError(err, 1)
}
if err := cmd(c, site); err != nil {
return cli.NewExitError(err, 1)
}
return nil
}
}

View File

@ -7,12 +7,43 @@ import (
"github.com/osteele/gojekyll"
"github.com/osteele/gojekyll/helpers"
"gopkg.in/urfave/cli.v1"
"gopkg.in/alecthomas/kingpin.v2"
)
// Command-line options
var buildOptions gojekyll.BuildOptions
var useRemoteLiquidEngine bool
var (
buildOptions gojekyll.BuildOptions
useRemoteLiquidEngine bool
site *gojekyll.Site
)
var (
app = kingpin.New("gojekyll", "a (maybe someday) Jekyll-compatible blog generator in Go")
source = app.Flag("source", "Source directory").Default(".").String()
destination = app.Flag("destination", "Destination directory").Default("").String()
serve = app.Command("serve", "Serve your site locally").Alias("server").Alias("s")
build = app.Command("build", "Build your site").Alias("b")
profile = app.Command("profile", "Build several times, and write a profile file")
variables = app.Command("variables", "Display a file or URL path's variables").Alias("v").Alias("var").Alias("vars")
dataVariable = variables.Flag("data", "Display site.data").Bool()
siteVariable = variables.Flag("site", "Display site variables instead of page variables").Bool()
variablePath = variables.Arg("PATH", "Path or URL").String()
routes = app.Command("routes", "Display site permalinks and associated files")
dynamicRoutes = routes.Flag("dynamic", "Only show routes to non-static files").Bool()
render = app.Command("render", "Render a file or URL path")
renderPath = variables.Arg("PATH2", "Path or URL").String()
)
func init() {
app.Flag("use-liquid-server", "Use Liquid JSON-RPC server").BoolVar(&useRemoteLiquidEngine)
build.Flag("dry-run", "Dry run").Short('n').BoolVar(&buildOptions.DryRun)
}
// This is the longest label. Pull it out here so we can both use it, and measure it for alignment.
const configurationFileLabel = "Configuration file:"
@ -30,93 +61,50 @@ func printPathSetting(label string, name string) {
}
func main() {
var source, destination string
app := cli.NewApp()
app.Name = "gojekyll"
app.Usage = "a (maybe someday) Jekyll-compatible blog generator in Go"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "source",
Value: ".",
Usage: "Source directory",
Destination: &source,
},
cli.StringFlag{
Name: "destination",
Value: "",
Usage: "Destination directory",
Destination: &destination,
},
cli.BoolFlag{
Name: "use-liquid-server",
Usage: "Use Liquid JSON-RPC server",
Destination: &useRemoteLiquidEngine,
},
cmd := kingpin.MustParse(app.Parse(os.Args[1:]))
if err := run(cmd); err != nil {
app.FatalIfError(err, "")
}
withSite := func(cmd func(*cli.Context, *gojekyll.Site) error) func(*cli.Context) error {
siteLoader := func() (*gojekyll.Site, error) { return loadSite(source, destination) }
return loadSiteAndRun(siteLoader, cmd)
}
app.Commands = []cli.Command{
{
Name: "serve",
Aliases: []string{"server", "s"},
Usage: "Serve your site locally",
Action: withSite(serveCommand),
},
{
Name: "build",
Aliases: []string{"b"},
Usage: "Build your site",
Action: withSite(buildCommand),
Flags: []cli.Flag{
cli.BoolFlag{
Name: "dry-run, n",
Usage: "Dry run",
Destination: &buildOptions.DryRun,
},
},
},
{
Name: "profile",
Usage: "Build several times, and write a profile file",
Action: withSite(profileCommand),
}, {
Name: "variables",
Aliases: []string{"v", "var", "vars"},
Usage: "Print a file or URL path's variables",
Action: withSite(varsCommand),
Flags: []cli.Flag{
cli.BoolFlag{
Name: "data",
},
cli.BoolFlag{
Name: "site",
Usage: "Display site variables instead of page variables",
},
},
},
{
Name: "routes",
Usage: "Display site permalinks and associated files",
Action: withSite(routesCommand),
Flags: []cli.Flag{
cli.BoolFlag{
Name: "dynamic",
Usage: "Only show routes to non-static files",
},
},
},
{
Name: "render",
Usage: "Render a file or URL path",
Action: withSite(renderCommand),
},
}
_ = app.Run(os.Args)
}
func run(cmd string) error {
site, err := loadSite(*source, *destination)
if err != nil {
return err
}
switch cmd {
case build.FullCommand():
return buildCommand(site)
case profile.FullCommand():
return profileCommand(site)
case render.FullCommand():
return renderCommand(site)
case routes.FullCommand():
return routesCommand(site)
case serve.FullCommand():
return serveCommand(site)
case variables.FullCommand():
return varsCommand(site)
}
return nil
}
// Load the site specified at destination into the site global, and print the common banner settings.
func loadSite(source, destination string) (*gojekyll.Site, error) {
site, err := gojekyll.NewSiteFromDirectory(source)
if err != nil {
return nil, err
}
site.UseRemoteLiquidEngine = useRemoteLiquidEngine
if destination != "" {
site.Destination = destination
}
if site.ConfigFile != nil {
printPathSetting(configurationFileLabel, *site.ConfigFile)
} else {
printSetting(configurationFileLabel, "none")
}
printPathSetting("Source:", site.Source)
err = site.Load()
return site, err
}