hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

main.go (6423B)

    1 package main
    2 
    3 import (
    4 	"fmt"
    5 	"io/ioutil"
    6 	"log"
    7 	"os"
    8 	"path/filepath"
    9 	"regexp"
   10 	"strings"
   11 
   12 	"github.com/gohugoio/hugo/common/hexec"
   13 
   14 	"github.com/gohugoio/hugo/common/hugio"
   15 
   16 	"github.com/spf13/afero"
   17 )
   18 
   19 func main() {
   20 	// The current is built with 41a82aa9c3 text/template/parse: allow space after continue or break
   21 	fmt.Println("Forking ...")
   22 	defer fmt.Println("Done ...")
   23 
   24 	cleanFork()
   25 
   26 	htmlRoot := filepath.Join(forkRoot, "htmltemplate")
   27 
   28 	for _, pkg := range goPackages {
   29 		copyGoPackage(pkg.dstPkg, pkg.srcPkg)
   30 	}
   31 
   32 	for _, pkg := range goPackages {
   33 		doWithGoFiles(pkg.dstPkg, pkg.rewriter, pkg.replacer)
   34 	}
   35 
   36 	goimports(htmlRoot)
   37 	gofmt(forkRoot)
   38 }
   39 
   40 const (
   41 	// TODO(bep)
   42 	goSource = "/Users/bep/dev/go/misc/go/src"
   43 	forkRoot = "../../tpl/internal/go_templates"
   44 )
   45 
   46 type goPackage struct {
   47 	srcPkg   string
   48 	dstPkg   string
   49 	replacer func(name, content string) string
   50 	rewriter func(name string)
   51 }
   52 
   53 var (
   54 	textTemplateReplacers = strings.NewReplacer(
   55 		`"text/template/`, `"github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/`,
   56 		`"internal/fmtsort"`, `"github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort"`,
   57 		`"internal/testenv"`, `"github.com/gohugoio/hugo/tpl/internal/go_templates/testenv"`,
   58 		"TestLinkerGC", "_TestLinkerGC",
   59 		// Rename types and function that we want to overload.
   60 		"type state struct", "type stateOld struct",
   61 		"func (s *state) evalFunction", "func (s *state) evalFunctionOld",
   62 		"func (s *state) evalField(", "func (s *state) evalFieldOld(",
   63 		"func (s *state) evalCall(", "func (s *state) evalCallOld(",
   64 		"func isTrue(val reflect.Value) (truth, ok bool) {", "func isTrueOld(val reflect.Value) (truth, ok bool) {",
   65 	)
   66 
   67 	testEnvReplacers = strings.NewReplacer(
   68 		`"internal/cfg"`, `"github.com/gohugoio/hugo/tpl/internal/go_templates/cfg"`,
   69 	)
   70 
   71 	htmlTemplateReplacers = strings.NewReplacer(
   72 		`. "html/template"`, `. "github.com/gohugoio/hugo/tpl/internal/go_templates/htmltemplate"`,
   73 		`"html/template"`, `template "github.com/gohugoio/hugo/tpl/internal/go_templates/htmltemplate"`,
   74 		"\"text/template\"\n", "template \"github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate\"\n",
   75 		`"html/template"`, `htmltemplate "html/template"`,
   76 		`"fmt"`, `htmltemplate "html/template"`,
   77 		`t.Skip("this test currently fails with -race; see issue #39807")`, `// t.Skip("this test currently fails with -race; see issue #39807")`,
   78 	)
   79 )
   80 
   81 func commonReplace(name, content string) string {
   82 	if strings.HasSuffix(name, "_test.go") {
   83 		content = strings.Replace(content, "package template\n", `// +build go1.13,!windows
   84 
   85 package template
   86 `, 1)
   87 		content = strings.Replace(content, "package template_test\n", `// +build go1.13
   88 
   89 package template_test
   90 `, 1)
   91 
   92 		content = strings.Replace(content, "package parse\n", `// +build go1.13
   93 
   94 package parse
   95 `, 1)
   96 
   97 	}
   98 
   99 	return content
  100 }
  101 
  102 var goPackages = []goPackage{
  103 	{
  104 		srcPkg: "text/template", dstPkg: "texttemplate",
  105 		replacer: func(name, content string) string { return textTemplateReplacers.Replace(commonReplace(name, content)) },
  106 	},
  107 	{
  108 		srcPkg: "html/template", dstPkg: "htmltemplate", replacer: func(name, content string) string {
  109 			if strings.HasSuffix(name, "content.go") {
  110 				// Remove template.HTML types. We need to use the Go types.
  111 				content = removeAll(`(?s)// Strings of content.*?\)\n`, content)
  112 			}
  113 
  114 			content = commonReplace(name, content)
  115 
  116 			return htmlTemplateReplacers.Replace(content)
  117 		},
  118 		rewriter: func(name string) {
  119 			for _, s := range []string{"CSS", "HTML", "HTMLAttr", "JS", "JSStr", "URL", "Srcset"} {
  120 				rewrite(name, fmt.Sprintf("%s -> htmltemplate.%s", s, s))
  121 			}
  122 			rewrite(name, `"text/template/parse" -> "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse"`)
  123 		},
  124 	},
  125 	{srcPkg: "internal/fmtsort", dstPkg: "fmtsort", rewriter: func(name string) {
  126 		rewrite(name, `"internal/fmtsort" -> "github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort"`)
  127 	}},
  128 	{
  129 		srcPkg: "internal/testenv", dstPkg: "testenv",
  130 		replacer: func(name, content string) string { return testEnvReplacers.Replace(content) }, rewriter: func(name string) {
  131 			rewrite(name, `"internal/testenv" -> "github.com/gohugoio/hugo/tpl/internal/go_templates/testenv"`)
  132 		},
  133 	},
  134 	{srcPkg: "internal/cfg", dstPkg: "cfg", rewriter: func(name string) {
  135 		rewrite(name, `"internal/cfg" -> "github.com/gohugoio/hugo/tpl/internal/go_templates/cfg"`)
  136 	}},
  137 }
  138 
  139 var fs = afero.NewOsFs()
  140 
  141 // Removes all non-Hugo files in the go_templates folder.
  142 func cleanFork() {
  143 	must(filepath.Walk(filepath.Join(forkRoot), func(path string, info os.FileInfo, err error) error {
  144 		if !info.IsDir() && len(path) > 10 && !strings.Contains(path, "hugo") {
  145 			must(fs.Remove(path))
  146 		}
  147 		return nil
  148 	}))
  149 }
  150 
  151 func must(err error, what ...string) {
  152 	if err != nil {
  153 		log.Fatal(what, " ERROR: ", err)
  154 	}
  155 }
  156 
  157 func copyGoPackage(dst, src string) {
  158 	from := filepath.Join(goSource, src)
  159 	to := filepath.Join(forkRoot, dst)
  160 	fmt.Println("Copy", from, "to", to)
  161 	must(hugio.CopyDir(fs, from, to, func(s string) bool { return true }))
  162 }
  163 
  164 func doWithGoFiles(dir string,
  165 	rewrite func(name string),
  166 	transform func(name, in string) string) {
  167 	if rewrite == nil && transform == nil {
  168 		return
  169 	}
  170 	must(filepath.Walk(filepath.Join(forkRoot, dir), func(path string, info os.FileInfo, err error) error {
  171 		if info.IsDir() {
  172 			return nil
  173 		}
  174 
  175 		if !strings.HasSuffix(path, ".go") || strings.Contains(path, "hugo_") {
  176 			return nil
  177 		}
  178 
  179 		fmt.Println("Handle", path)
  180 
  181 		if rewrite != nil {
  182 			rewrite(path)
  183 		}
  184 
  185 		if transform == nil {
  186 			return nil
  187 		}
  188 
  189 		data, err := ioutil.ReadFile(path)
  190 		must(err)
  191 		f, err := os.Create(path)
  192 		must(err)
  193 		defer f.Close()
  194 		_, err = f.WriteString(transform(path, string(data)))
  195 		must(err)
  196 
  197 		return nil
  198 	}))
  199 }
  200 
  201 func removeAll(expression, content string) string {
  202 	re := regexp.MustCompile(expression)
  203 	return re.ReplaceAllString(content, "")
  204 }
  205 
  206 func rewrite(filename, rule string) {
  207 	cmf, _ := hexec.SafeCommand("gofmt", "-w", "-r", rule, filename)
  208 	out, err := cmf.CombinedOutput()
  209 	if err != nil {
  210 		log.Fatal("gofmt failed:", string(out))
  211 	}
  212 }
  213 
  214 func goimports(dir string) {
  215 	cmf, _ := hexec.SafeCommand("goimports", "-w", dir)
  216 	out, err := cmf.CombinedOutput()
  217 	if err != nil {
  218 		log.Fatal("goimports failed:", string(out))
  219 	}
  220 }
  221 
  222 func gofmt(dir string) {
  223 	cmf, _ := hexec.SafeCommand("gofmt", "-w", dir)
  224 	out, err := cmf.CombinedOutput()
  225 	if err != nil {
  226 		log.Fatal("gofmt failed:", string(out))
  227 	}
  228 }