github.com/quay/claircore@v1.5.28/internal/cmd/mdbook-make_target/main.go (about)

     1  // Mdbook-make_target is a helper to check that documented Makefile targets exist.
     2  package main
     3  
     4  import (
     5  	"bytes"
     6  	"context"
     7  	"fmt"
     8  	"log"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"regexp"
    13  	"strings"
    14  	"sync"
    15  
    16  	"github.com/quay/claircore/internal/mdbook"
    17  )
    18  
    19  var (
    20  	open     sync.Once
    21  	makefile []byte
    22  )
    23  
    24  func readMakefile(ctx context.Context) {
    25  	cmd := exec.CommandContext(ctx, `git`, `rev-parse`, `--show-toplevel`)
    26  	out, err := cmd.Output()
    27  	if err != nil {
    28  		log.Panic(err)
    29  	}
    30  	n := filepath.Join(string(bytes.TrimSpace(out)), `Makefile`)
    31  	makefile, err = os.ReadFile(n)
    32  	if err != nil {
    33  		log.Panic(err)
    34  	}
    35  }
    36  
    37  var marker = regexp.MustCompile(`\{\{#\s*make_target\s(.+)\}\}`)
    38  
    39  func main() {
    40  	mdbook.Main("make_target", newProc)
    41  }
    42  
    43  func newProc(_ context.Context, _ *mdbook.Context) (*mdbook.Proc, error) {
    44  	proc := mdbook.Proc{
    45  		Chapter: func(ctx context.Context, b *strings.Builder, c *mdbook.Chapter) error {
    46  			if c.Path == nil {
    47  				return nil
    48  			}
    49  			var ret error
    50  			c.Content = marker.ReplaceAllStringFunc(c.Content, func(sub string) string {
    51  				ms := marker.FindStringSubmatch(sub)
    52  				if ct := len(ms); ct != 2 {
    53  					ret = fmt.Errorf("unexpected number of arguments: %d", ct)
    54  					return sub
    55  				}
    56  				target := strings.TrimSpace(ms[1])
    57  				re, err := regexp.Compile("\n" + target + `:`)
    58  				if err != nil {
    59  					ret = err
    60  					return sub
    61  				}
    62  				open.Do(func() { readMakefile(ctx) })
    63  				if !re.Match(makefile) {
    64  					ret = fmt.Errorf("unable to find target %q", target)
    65  				}
    66  				log.Printf("found target: %q", target)
    67  				return target
    68  			})
    69  			return ret
    70  		},
    71  	}
    72  	return &proc, nil
    73  }