vitess.io/vitess@v0.16.2/go/tools/releases/releases.go (about) 1 /* 2 Copyright 2023 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 // The changelog directory is composed of a README that lists 20 // and links to all major releases of Vitess. It has one 21 // sub-directory for each major version. Each sub-directory is 22 // composed of another README that also lists and links all the 23 // patch releases of this major release. Those sub-directories 24 // are composed of one directory per patch release. Finally, 25 // the patch release directory contains the old files markdown: 26 // summary, release_notes, changelog. 27 // 28 // This tool is solely responsible for generating the READMEs 29 // and making sure they are up-to-date with the list of major 30 // and patch releases we have. 31 32 import ( 33 "log" 34 "os" 35 "path" 36 "sort" 37 "strings" 38 "text/template" 39 ) 40 41 const ( 42 rootDir = "./changelog/" 43 44 rootFileTmpl = `## Releases 45 46 {{- range $r := .SubDirs }} 47 * [{{ $r.Name }}]({{ $r.Name }}) 48 {{- end -}} 49 ` 50 51 majorVersionTmpl = `## v{{ .Name }} 52 53 {{- if .Team }} 54 The dedicated team for this release can be found [here]({{.Team}}).{{ end }} 55 56 {{- range $r := .SubDirs }} 57 * **[{{ $r.Name }}]({{ $r.Name }})** 58 {{ if $r.Changelog }} * [Changelog]({{ $r.Name }}/{{ $r.Changelog }}) 59 {{ end -}} 60 {{ if $r.ReleaseNotes }} * [Release Notes]({{ $r.Name }}/{{ $r.ReleaseNotes }}) 61 {{ end -}} 62 {{- end -}} 63 ` 64 ) 65 66 type dir struct { 67 Name string 68 Path string 69 Changelog string 70 ReleaseNotes string 71 Team string 72 SubDirs []dir 73 } 74 75 func main() { 76 rootDir, err := getDirs(dir{Path: rootDir}) 77 if err != nil { 78 log.Fatal(err) 79 } 80 81 err = execReadMeTemplateWithDir(rootDir, rootFileTmpl) 82 if err != nil { 83 log.Fatal(err) 84 } 85 86 for _, subDir := range rootDir.SubDirs { 87 err := execReadMeTemplateWithDir(subDir, majorVersionTmpl) 88 if err != nil { 89 log.Fatal(err) 90 } 91 } 92 } 93 94 func execReadMeTemplateWithDir(d dir, tmpl string) error { 95 rootRM, err := os.OpenFile(path.Join(d.Path, "README.md"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0640) 96 if err != nil { 97 return err 98 } 99 100 t := template.Must(template.New("root_readme").Parse(tmpl)) 101 err = t.ExecuteTemplate(rootRM, "root_readme", d) 102 if err != nil { 103 return err 104 } 105 return nil 106 } 107 108 func getDirs(curDir dir) (dir, error) { 109 entries, err := os.ReadDir(curDir.Path) 110 if err != nil { 111 return dir{}, err 112 } 113 114 for _, entry := range entries { 115 if entry.IsDir() { 116 subDir, err := getDirs(dir{ 117 Name: entry.Name(), 118 Path: path.Join(curDir.Path, entry.Name()), 119 }) 120 if err != nil { 121 return dir{}, err 122 } 123 curDir.SubDirs = append(curDir.SubDirs, subDir) 124 continue 125 } 126 127 switch { 128 case strings.Contains(entry.Name(), "changelog.md"): 129 curDir.Changelog = entry.Name() 130 case strings.Contains(entry.Name(), "release_notes.md"): 131 curDir.ReleaseNotes = entry.Name() 132 case strings.Contains(entry.Name(), "team.md"): 133 curDir.Team = entry.Name() 134 } 135 } 136 sort.Slice(curDir.SubDirs, func(i, j int) bool { 137 if len(curDir.SubDirs[i].Name) < len(curDir.SubDirs[j].Name) { 138 return false 139 } 140 return curDir.SubDirs[i].Name > curDir.SubDirs[j].Name 141 }) 142 return curDir, nil 143 }