2014-05-02 01:06:01 -04:00
|
|
|
// Licensed under the Simple Public License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
// http://opensource.org/licenses/Simple-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package commands
|
|
|
|
|
|
|
|
import (
|
2014-05-08 18:30:11 -04:00
|
|
|
"bytes"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2014-05-02 01:06:01 -04:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/spf13/hugo/create"
|
|
|
|
"github.com/spf13/hugo/helpers"
|
2014-11-01 11:57:29 -04:00
|
|
|
"github.com/spf13/hugo/hugofs"
|
2014-05-08 18:30:11 -04:00
|
|
|
"github.com/spf13/hugo/parser"
|
2014-05-02 01:06:01 -04:00
|
|
|
jww "github.com/spf13/jwalterweatherman"
|
2014-05-29 18:40:16 -04:00
|
|
|
"github.com/spf13/viper"
|
2014-05-02 01:06:01 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
var siteType string
|
|
|
|
var configFormat string
|
|
|
|
var contentType string
|
|
|
|
var contentFormat string
|
|
|
|
var contentFrontMatter string
|
|
|
|
|
|
|
|
func init() {
|
2014-05-08 18:30:11 -04:00
|
|
|
newSiteCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "config & frontmatter format")
|
2014-05-29 18:40:16 -04:00
|
|
|
newCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "frontmatter format")
|
2014-05-02 01:06:01 -04:00
|
|
|
newCmd.Flags().StringVarP(&contentType, "kind", "k", "", "Content type to create")
|
|
|
|
newCmd.AddCommand(newSiteCmd)
|
2014-05-08 18:30:11 -04:00
|
|
|
newCmd.AddCommand(newThemeCmd)
|
2014-05-02 01:06:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
var newCmd = &cobra.Command{
|
|
|
|
Use: "new [path]",
|
|
|
|
Short: "Create new content for your site",
|
2014-09-28 00:52:15 -04:00
|
|
|
Long: `Create a new content file and automatically set the date and title.
|
2014-05-02 01:06:01 -04:00
|
|
|
It will guess which kind of file to create based on the path provided.
|
|
|
|
You can also specify the kind with -k KIND
|
|
|
|
If archetypes are provided in your theme or site, they will be used.
|
|
|
|
`,
|
|
|
|
Run: NewContent,
|
|
|
|
}
|
|
|
|
|
2014-05-08 18:30:11 -04:00
|
|
|
var newSiteCmd = &cobra.Command{
|
|
|
|
Use: "site [path]",
|
|
|
|
Short: "Create a new site (skeleton)",
|
|
|
|
Long: `Create a new site in the provided directory.
|
|
|
|
The new site will have the correct structure, but no content or theme yet.
|
|
|
|
Use 'hugo new [contentPath]' to create new content.
|
|
|
|
`,
|
|
|
|
Run: NewSite,
|
|
|
|
}
|
|
|
|
|
|
|
|
var newThemeCmd = &cobra.Command{
|
|
|
|
Use: "theme [name]",
|
|
|
|
Short: "Create a new theme",
|
|
|
|
Long: `Create a new theme (skeleton) called [name] in the current directory.
|
|
|
|
New theme is a skeleton. Please add content to the touched files. Add your
|
|
|
|
name to the copyright line in the license and adjust the theme.toml file
|
|
|
|
as you see fit.
|
|
|
|
`,
|
|
|
|
Run: NewTheme,
|
|
|
|
}
|
|
|
|
|
2014-12-11 13:05:02 -05:00
|
|
|
//NewContent adds new content to a Hugo site.
|
2014-05-02 01:06:01 -04:00
|
|
|
func NewContent(cmd *cobra.Command, args []string) {
|
|
|
|
InitializeConfig()
|
|
|
|
|
2014-05-29 18:40:16 -04:00
|
|
|
if cmd.Flags().Lookup("format").Changed {
|
|
|
|
viper.Set("MetaDataFormat", configFormat)
|
|
|
|
}
|
|
|
|
|
2014-05-02 01:06:01 -04:00
|
|
|
if len(args) < 1 {
|
2014-05-08 18:30:11 -04:00
|
|
|
cmd.Usage()
|
2014-05-02 01:06:01 -04:00
|
|
|
jww.FATAL.Fatalln("path needs to be provided")
|
|
|
|
}
|
|
|
|
|
|
|
|
createpath := args[0]
|
|
|
|
|
|
|
|
var kind string
|
|
|
|
|
|
|
|
// assume the first directory is the section (kind)
|
|
|
|
if strings.Contains(createpath[1:], "/") {
|
|
|
|
kind = helpers.GuessSection(createpath)
|
|
|
|
}
|
|
|
|
|
|
|
|
if contentType != "" {
|
|
|
|
kind = contentType
|
|
|
|
}
|
|
|
|
|
|
|
|
err := create.NewContent(kind, createpath)
|
|
|
|
if err != nil {
|
|
|
|
jww.ERROR.Println(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-11 13:05:02 -05:00
|
|
|
// NewSite creates a new hugo site and initializes a structured Hugo directory.
|
2014-05-08 18:30:11 -04:00
|
|
|
func NewSite(cmd *cobra.Command, args []string) {
|
|
|
|
if len(args) < 1 {
|
|
|
|
cmd.Usage()
|
|
|
|
jww.FATAL.Fatalln("path needs to be provided")
|
|
|
|
}
|
|
|
|
|
|
|
|
createpath, err := filepath.Abs(filepath.Clean(args[0]))
|
|
|
|
if err != nil {
|
|
|
|
cmd.Usage()
|
|
|
|
jww.FATAL.Fatalln(err)
|
|
|
|
}
|
|
|
|
|
2014-11-01 11:57:29 -04:00
|
|
|
if x, _ := helpers.Exists(createpath, hugofs.SourceFs); x {
|
|
|
|
y, _ := helpers.IsDir(createpath, hugofs.SourceFs)
|
|
|
|
if z, _ := helpers.IsEmpty(createpath, hugofs.SourceFs); y && z {
|
2014-05-19 09:16:40 -04:00
|
|
|
jww.INFO.Println(createpath, "already exists and is empty")
|
|
|
|
} else {
|
|
|
|
jww.FATAL.Fatalln(createpath, "already exists and is not empty")
|
|
|
|
}
|
2014-05-08 18:30:11 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mkdir(createpath, "layouts")
|
|
|
|
mkdir(createpath, "content")
|
|
|
|
mkdir(createpath, "archetypes")
|
|
|
|
mkdir(createpath, "static")
|
2015-01-20 17:08:01 -05:00
|
|
|
mkdir(createpath, "data")
|
2014-05-08 18:30:11 -04:00
|
|
|
|
|
|
|
createConfig(createpath, configFormat)
|
2014-05-02 01:06:01 -04:00
|
|
|
}
|
|
|
|
|
2014-12-11 13:05:02 -05:00
|
|
|
//NewTheme creates a new Hugo theme.
|
2014-05-08 18:30:11 -04:00
|
|
|
func NewTheme(cmd *cobra.Command, args []string) {
|
2014-05-02 01:06:01 -04:00
|
|
|
InitializeConfig()
|
|
|
|
|
2014-05-08 18:30:11 -04:00
|
|
|
if len(args) < 1 {
|
|
|
|
cmd.Usage()
|
|
|
|
jww.FATAL.Fatalln("theme name needs to be provided")
|
|
|
|
}
|
|
|
|
|
2014-11-06 11:56:14 -05:00
|
|
|
createpath := helpers.AbsPathify(filepath.Join("themes", args[0]))
|
2014-05-08 18:30:11 -04:00
|
|
|
jww.INFO.Println("creating theme at", createpath)
|
|
|
|
|
2014-11-01 11:57:29 -04:00
|
|
|
if x, _ := helpers.Exists(createpath, hugofs.SourceFs); x {
|
2014-05-08 18:30:11 -04:00
|
|
|
jww.FATAL.Fatalln(createpath, "already exists")
|
|
|
|
}
|
|
|
|
|
|
|
|
mkdir(createpath, "layouts", "_default")
|
2014-05-27 18:30:25 -04:00
|
|
|
mkdir(createpath, "layouts", "partials")
|
2014-05-08 18:30:11 -04:00
|
|
|
|
|
|
|
touchFile(createpath, "layouts", "index.html")
|
|
|
|
touchFile(createpath, "layouts", "_default", "list.html")
|
|
|
|
touchFile(createpath, "layouts", "_default", "single.html")
|
|
|
|
|
2014-05-27 18:30:25 -04:00
|
|
|
touchFile(createpath, "layouts", "partials", "header.html")
|
|
|
|
touchFile(createpath, "layouts", "partials", "footer.html")
|
2014-05-08 18:30:11 -04:00
|
|
|
|
|
|
|
mkdir(createpath, "archetypes")
|
|
|
|
touchFile(createpath, "archetypes", "default.md")
|
|
|
|
|
|
|
|
mkdir(createpath, "static", "js")
|
|
|
|
mkdir(createpath, "static", "css")
|
|
|
|
|
|
|
|
by := []byte(`The MIT License (MIT)
|
|
|
|
|
|
|
|
Copyright (c) 2014 YOUR_NAME_HERE
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
|
this software and associated documentation files (the "Software"), to deal in
|
|
|
|
the Software without restriction, including without limitation the rights to
|
|
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
|
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
|
|
subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
|
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
`)
|
|
|
|
|
2014-11-06 11:56:14 -05:00
|
|
|
err := helpers.WriteToDisk(filepath.Join(createpath, "LICENSE.md"), bytes.NewReader(by), hugofs.SourceFs)
|
2014-05-08 18:30:11 -04:00
|
|
|
if err != nil {
|
|
|
|
jww.FATAL.Fatalln(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
createThemeMD(createpath)
|
|
|
|
}
|
|
|
|
|
|
|
|
func mkdir(x ...string) {
|
2014-11-06 11:56:14 -05:00
|
|
|
p := filepath.Join(x...)
|
2014-05-08 18:30:11 -04:00
|
|
|
|
|
|
|
err := os.MkdirAll(p, 0777) // rwx, rw, r
|
|
|
|
if err != nil {
|
|
|
|
jww.FATAL.Fatalln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func touchFile(x ...string) {
|
2014-11-06 11:56:14 -05:00
|
|
|
inpath := filepath.Join(x...)
|
2014-05-08 18:30:11 -04:00
|
|
|
mkdir(filepath.Dir(inpath))
|
2014-11-01 11:57:29 -04:00
|
|
|
err := helpers.WriteToDisk(inpath, bytes.NewReader([]byte{}), hugofs.SourceFs)
|
2014-05-08 18:30:11 -04:00
|
|
|
if err != nil {
|
|
|
|
jww.FATAL.Fatalln(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func createThemeMD(inpath string) (err error) {
|
|
|
|
|
|
|
|
in := map[string]interface{}{
|
|
|
|
"name": helpers.MakeTitle(filepath.Base(inpath)),
|
|
|
|
"license": "MIT",
|
|
|
|
"source_repo": "",
|
|
|
|
"author": "",
|
|
|
|
"description": "",
|
|
|
|
"tags": []string{"", ""},
|
|
|
|
}
|
|
|
|
|
|
|
|
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune("toml"))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-11-06 11:56:14 -05:00
|
|
|
err = helpers.WriteToDisk(filepath.Join(inpath, "theme.toml"), bytes.NewReader(by), hugofs.SourceFs)
|
2014-05-08 18:30:11 -04:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func createConfig(inpath string, kind string) (err error) {
|
|
|
|
in := map[string]string{"baseurl": "http://yourSiteHere", "title": "my new hugo site", "languageCode": "en-us"}
|
|
|
|
kind = parser.FormatSanitize(kind)
|
|
|
|
|
|
|
|
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-11-06 11:56:14 -05:00
|
|
|
err = helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), bytes.NewReader(by), hugofs.SourceFs)
|
2014-05-08 18:30:11 -04:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2014-05-02 01:06:01 -04:00
|
|
|
}
|