hugo

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

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

releasenotes_writer.go (5677B)

    1 // Copyright 2017-present The Hugo Authors. All rights reserved.
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 // http://www.apache.org/licenses/LICENSE-2.0
    7 //
    8 // Unless required by applicable law or agreed to in writing, software
    9 // distributed under the License is distributed on an "AS IS" BASIS,
   10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   11 // See the License for the specific language governing permissions and
   12 // limitations under the License.
   13 
   14 // Package releaser implements a set of utilities and a wrapper around Goreleaser
   15 // to help automate the Hugo release process.
   16 package releaser
   17 
   18 import (
   19 	"bytes"
   20 	"fmt"
   21 	"io"
   22 	"io/ioutil"
   23 	"net/http"
   24 	"os"
   25 	"path/filepath"
   26 	"strings"
   27 	"text/template"
   28 )
   29 
   30 const (
   31 	issueLinkTemplate                        = "#%d"
   32 	linkTemplate                             = "[%s](%s)"
   33 	releaseNotesMarkdownTemplatePatchRelease = `
   34 {{ if eq (len .All) 1 }}
   35 This is a bug-fix release with one important fix.
   36 {{ else }}
   37 This is a bug-fix release with a couple of important fixes.
   38 {{ end }}
   39 {{ range .All }}
   40 {{- if .GitHubCommit -}}
   41 * {{ .Subject }} {{ .Hash }} {{ . | author }} {{ range .Issues }}{{ . | issue }} {{ end }}
   42 {{ else -}}
   43 * {{ .Subject }} {{ range .Issues }}{{ . | issue }} {{ end }}
   44 {{ end -}}
   45 {{- end }}
   46 
   47 
   48 `
   49 	releaseNotesMarkdownTemplate = `
   50 {{- $contribsPerAuthor := .All.ContribCountPerAuthor -}}
   51 {{- $docsContribsPerAuthor := .Docs.ContribCountPerAuthor -}}
   52 
   53 This release represents **{{ len .All }} contributions by {{ len $contribsPerAuthor }} contributors** to the main Hugo code base.
   54 
   55 {{- if  gt (len $contribsPerAuthor) 3 -}}
   56 {{- $u1 := index $contribsPerAuthor 0 -}}
   57 {{- $u2 := index $contribsPerAuthor 1 -}}
   58 {{- $u3 := index $contribsPerAuthor 2 -}}
   59 {{- $u4 := index $contribsPerAuthor 3 -}}
   60 {{- $u1.AuthorLink }} leads the Hugo development with a significant amount of contributions, but also a big shoutout to {{ $u2.AuthorLink }}, {{ $u3.AuthorLink }}, and {{ $u4.AuthorLink }} for their ongoing contributions.
   61 And thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) for his ongoing work on keeping the themes site in pristine condition.
   62 {{ end }}
   63 Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
   64 which has received **{{ len .Docs }} contributions by {{ len $docsContribsPerAuthor }} contributors**.
   65 {{- if  gt (len $docsContribsPerAuthor) 3 -}}
   66 {{- $u1 := index $docsContribsPerAuthor 0 -}}
   67 {{- $u2 := index $docsContribsPerAuthor 1 -}}
   68 {{- $u3 := index $docsContribsPerAuthor 2 -}}
   69 {{- $u4 := index $docsContribsPerAuthor 3 }} A special thanks to {{ $u1.AuthorLink }}, {{ $u2.AuthorLink }}, {{ $u3.AuthorLink }}, and {{ $u4.AuthorLink }} for their work on the documentation site.
   70 {{ end }}
   71 
   72 Hugo now has:
   73 
   74 {{ with .Repo -}}
   75 * {{ .Stars }}+ [stars](https://github.com/gohugoio/hugo/stargazers)
   76 * {{ len .Contributors }}+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
   77 {{- end -}}
   78 {{ with .ThemeCount }}
   79 * {{ . }}+ [themes](http://themes.gohugo.io/)
   80 {{ end }}
   81 {{ with .Notes }}
   82 ## Notes
   83 {{ template "change-section" . }}
   84 {{- end -}}
   85 {{ with .All }}
   86 ## Changes
   87 {{ template "change-section" . }}
   88 {{ end }}
   89 
   90 {{ define "change-section" }}
   91 {{ range . }}
   92 {{- if .GitHubCommit -}}
   93 * {{ .Subject }} {{ .Hash }} {{ . | author }} {{ range .Issues }}{{ . | issue }} {{ end }}
   94 {{ else -}}
   95 * {{ .Subject }} {{ range .Issues }}{{ . | issue }} {{ end }}
   96 {{ end -}}
   97 {{- end }}
   98 {{ end }}
   99 `
  100 )
  101 
  102 var templateFuncs = template.FuncMap{
  103 	"isPatch": func(c changeLog) bool {
  104 		return !strings.HasSuffix(c.Version, "0")
  105 	},
  106 	"issue": func(id int) string {
  107 		return fmt.Sprintf(issueLinkTemplate, id)
  108 	},
  109 	"commitURL": func(info gitInfo) string {
  110 		if info.GitHubCommit.HTMLURL == "" {
  111 			return ""
  112 		}
  113 		return fmt.Sprintf(linkTemplate, info.Hash, info.GitHubCommit.HTMLURL)
  114 	},
  115 	"author": func(info gitInfo) string {
  116 		return "@" + info.GitHubCommit.Author.Login
  117 	},
  118 }
  119 
  120 func writeReleaseNotes(version string, infosMain, infosDocs gitInfos, to io.Writer) error {
  121 	client := newGitHubAPI("hugo")
  122 	changes := newChangeLog(infosMain, infosDocs)
  123 	changes.Version = version
  124 	repo, err := client.fetchRepo()
  125 	if err == nil {
  126 		changes.Repo = &repo
  127 	}
  128 	themeCount, err := fetchThemeCount()
  129 	if err == nil {
  130 		changes.ThemeCount = themeCount
  131 	}
  132 
  133 	mtempl := releaseNotesMarkdownTemplate
  134 
  135 	if !strings.HasSuffix(version, "0") {
  136 		mtempl = releaseNotesMarkdownTemplatePatchRelease
  137 	}
  138 
  139 	tmpl, err := template.New("").Funcs(templateFuncs).Parse(mtempl)
  140 	if err != nil {
  141 		return err
  142 	}
  143 
  144 	err = tmpl.Execute(to, changes)
  145 	if err != nil {
  146 		return err
  147 	}
  148 
  149 	return nil
  150 }
  151 
  152 func fetchThemeCount() (int, error) {
  153 	resp, err := http.Get("https://raw.githubusercontent.com/gohugoio/hugoThemesSiteBuilder/main/themes.txt")
  154 	if err != nil {
  155 		return 0, err
  156 	}
  157 	defer resp.Body.Close()
  158 
  159 	b, _ := ioutil.ReadAll(resp.Body)
  160 	return bytes.Count(b, []byte("\n")) - bytes.Count(b, []byte("#")), nil
  161 }
  162 
  163 func getReleaseNotesFilename(version string) string {
  164 	return filepath.FromSlash(fmt.Sprintf("temp/%s-relnotes-ready.md", version))
  165 }
  166 
  167 func (r *ReleaseHandler) writeReleaseNotesToTemp(version string, isPatch bool, infosMain, infosDocs gitInfos) (string, error) {
  168 	filename := getReleaseNotesFilename(version)
  169 
  170 	var w io.WriteCloser
  171 
  172 	if !r.try {
  173 		f, err := os.Create(filename)
  174 		if err != nil {
  175 			return "", err
  176 		}
  177 
  178 		defer f.Close()
  179 
  180 		w = f
  181 
  182 	} else {
  183 		w = os.Stdout
  184 	}
  185 
  186 	if err := writeReleaseNotes(version, infosMain, infosDocs, w); err != nil {
  187 		return "", err
  188 	}
  189 
  190 	return filename, nil
  191 }