github.com/stffabi/git-lfs@v2.3.5-0.20180214015214-8eeaa8d88902+incompatible/docs/man/mangen.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "regexp" 10 "strings" 11 ) 12 13 func readManDir() (string, []os.FileInfo) { 14 rootDirs := []string{ 15 "..", 16 "/tmp/docker_run/git-lfs", 17 } 18 19 var err error 20 for _, rootDir := range rootDirs { 21 fs, err := ioutil.ReadDir(filepath.Join(rootDir, "docs", "man")) 22 if err == nil { 23 return rootDir, fs 24 } 25 } 26 27 fmt.Fprintf(os.Stderr, "Failed to open man dir: %v\n", err) 28 os.Exit(2) 29 return "", nil 30 } 31 32 // Reads all .ronn files & and converts them to string literals 33 // triggered by "go generate" comment 34 // Literals are inserted into a map using an init function, this means 35 // that there are no compilation errors if 'go generate' hasn't been run, just 36 // blank man files. 37 func main() { 38 fmt.Fprintf(os.Stderr, "Converting man pages into code...\n") 39 rootDir, fs := readManDir() 40 manDir := filepath.Join(rootDir, "docs", "man") 41 out, err := os.Create(filepath.Join(rootDir, "commands", "mancontent_gen.go")) 42 if err != nil { 43 fmt.Fprintf(os.Stderr, "Failed to create go file: %v\n", err) 44 os.Exit(2) 45 } 46 out.WriteString("package commands\n\nfunc init() {\n") 47 out.WriteString("// THIS FILE IS GENERATED, DO NOT EDIT\n") 48 out.WriteString("// Use 'go generate ./commands' to update\n") 49 fileregex := regexp.MustCompile(`git-lfs(?:-([A-Za-z\-]+))?.\d.ronn`) 50 headerregex := regexp.MustCompile(`^###?\s+([A-Za-z0-9 ]+)`) 51 // only pick up caps in links to avoid matching optional args 52 linkregex := regexp.MustCompile(`\[([A-Z\- ]+)\]`) 53 // man links 54 manlinkregex := regexp.MustCompile(`(git)(?:-(lfs))?-([a-z\-]+)\(\d\)`) 55 count := 0 56 for _, f := range fs { 57 if match := fileregex.FindStringSubmatch(f.Name()); match != nil { 58 fmt.Fprintf(os.Stderr, "%v\n", f.Name()) 59 cmd := match[1] 60 if len(cmd) == 0 { 61 // This is git-lfs.1.ronn 62 cmd = "git-lfs" 63 } 64 out.WriteString("ManPages[\"" + cmd + "\"] = `") 65 contentf, err := os.Open(filepath.Join(manDir, f.Name())) 66 if err != nil { 67 fmt.Fprintf(os.Stderr, "Failed to open %v: %v\n", f.Name(), err) 68 os.Exit(2) 69 } 70 // Process the ronn to make it nicer as help text 71 scanner := bufio.NewScanner(contentf) 72 firstHeaderDone := false 73 skipNextLineIfBlank := false 74 lastLineWasBullet := false 75 scanloop: 76 for scanner.Scan() { 77 line := scanner.Text() 78 trimmedline := strings.TrimSpace(line) 79 if skipNextLineIfBlank && len(trimmedline) == 0 { 80 skipNextLineIfBlank = false 81 lastLineWasBullet = false 82 continue 83 } 84 85 // Special case headers 86 if hmatch := headerregex.FindStringSubmatch(line); hmatch != nil { 87 header := strings.ToLower(hmatch[1]) 88 switch header { 89 case "synopsis": 90 // Ignore this, just go direct to command 91 92 case "description": 93 // Just skip the header & newline 94 skipNextLineIfBlank = true 95 case "options": 96 out.WriteString("Options:" + "\n") 97 case "see also": 98 // don't include any content after this 99 break scanloop 100 default: 101 out.WriteString(strings.ToUpper(header[:1]) + header[1:] + "\n") 102 out.WriteString(strings.Repeat("-", len(header)) + "\n") 103 } 104 firstHeaderDone = true 105 lastLineWasBullet = false 106 continue 107 } 108 109 if lmatches := linkregex.FindAllStringSubmatch(line, -1); lmatches != nil { 110 for _, lmatch := range lmatches { 111 linktext := strings.ToLower(lmatch[1]) 112 line = strings.Replace(line, lmatch[0], `"`+strings.ToUpper(linktext[:1])+linktext[1:]+`"`, 1) 113 } 114 } 115 if manmatches := manlinkregex.FindAllStringSubmatch(line, -1); manmatches != nil { 116 for _, manmatch := range manmatches { 117 line = strings.Replace(line, manmatch[0], strings.Join(manmatch[1:], " "), 1) 118 } 119 } 120 121 // Skip content until after first header 122 if !firstHeaderDone { 123 continue 124 } 125 // OK, content here 126 127 // remove characters that markdown would render invisible in a text env. 128 for _, invis := range []string{"`", "<br>"} { 129 line = strings.Replace(line, invis, "", -1) 130 } 131 132 // indent bullets 133 if strings.HasPrefix(line, "*") { 134 lastLineWasBullet = true 135 } else if lastLineWasBullet && !strings.HasPrefix(line, " ") { 136 // indent paragraphs under bullets if not already done 137 line = " " + line 138 } 139 140 out.WriteString(line + "\n") 141 } 142 out.WriteString("`\n") 143 contentf.Close() 144 count++ 145 } 146 } 147 out.WriteString("}\n") 148 fmt.Fprintf(os.Stderr, "Successfully processed %d man pages.\n", count) 149 150 }