github.com/abhinav/git-pr@v0.6.1-0.20171029234004-54218d68c11b/scripts/extract_changelog.go (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"os"
     9  	"strings"
    10  )
    11  
    12  func main() {
    13  	if len(os.Args) != 2 {
    14  		fmt.Printf("USAGE: %v VERSION\n", os.Args[0])
    15  		os.Exit(1)
    16  	}
    17  
    18  	version := os.Args[1]
    19  	if err := run(version, os.Stdout); err != nil {
    20  		log.Fatal(err)
    21  	}
    22  }
    23  
    24  const (
    25  	foundVersionNumber = iota + 1
    26  	foundHeader
    27  
    28  	printing
    29  	foundEmptyLine
    30  )
    31  
    32  func run(version string, out io.Writer) error {
    33  	file, err := os.OpenFile("CHANGELOG.md", os.O_RDONLY, 0444)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	defer file.Close()
    38  
    39  	state := 0
    40  	scanner := bufio.NewScanner(file)
    41  	for scanner.Scan() {
    42  		line := scanner.Text()
    43  
    44  		switch state {
    45  		case 0:
    46  			if strings.HasPrefix(line, version+" ") {
    47  				state = foundVersionNumber
    48  			}
    49  		case foundVersionNumber:
    50  			// ---- below the version number
    51  			if strings.Trim(line, "-") == "" {
    52  				state = foundHeader
    53  			} else {
    54  				return fmt.Errorf("unexpected %q after version number", line)
    55  			}
    56  		case foundHeader:
    57  			if line == "" {
    58  				continue
    59  			}
    60  			state = printing
    61  			fallthrough
    62  		case printing:
    63  			if strings.HasPrefix(line, "v") {
    64  				// end of section
    65  				return nil
    66  			}
    67  			if line == "" {
    68  				state = foundEmptyLine
    69  				continue
    70  			}
    71  			fmt.Fprintln(out, line)
    72  		case foundEmptyLine:
    73  			if line == "" {
    74  				// two empty lines end the changelog
    75  				return nil
    76  			}
    77  			fmt.Println()
    78  			fmt.Fprintln(out, line)
    79  			state = printing
    80  		default:
    81  			return fmt.Errorf("unexpected state %v on line %q", state, line)
    82  		}
    83  
    84  	}
    85  
    86  	if err := scanner.Err(); err != nil {
    87  		return err
    88  	}
    89  
    90  	if state < printing {
    91  		return fmt.Errorf("could not find version %q in changelog", version)
    92  	}
    93  	return nil
    94  }