github.com/decomp/exp@v0.0.0-20210624183419-6d058f5e1da6/cmd/dot2png/main.go (about)

     1  // The dot2png tool converts DOT files to PNG images.
     2  //
     3  // Usage:
     4  //
     5  //    dot2png FILE.dot...
     6  //
     7  // Flags:
     8  //
     9  //    -f    force overwrite existing images
    10  package main
    11  
    12  import (
    13  	"flag"
    14  	"fmt"
    15  	"log"
    16  	"os"
    17  	"os/exec"
    18  
    19  	"github.com/mewkiz/pkg/errutil"
    20  	"github.com/mewkiz/pkg/pathutil"
    21  )
    22  
    23  func usage() {
    24  	const use = `
    25  Usage: dot2png FILE.dot...
    26  Convert DOT files to PNG images.
    27  
    28  Flags:
    29  `
    30  	fmt.Fprintln(os.Stderr, use[1:])
    31  	flag.PrintDefaults()
    32  }
    33  
    34  func main() {
    35  	// Parse command line options.
    36  	var (
    37  		// force specifies whether to force overwrite existing images.
    38  		force bool
    39  	)
    40  	flag.BoolVar(&force, "f", false, "force overwrite existing images")
    41  	flag.Usage = usage
    42  	flag.Parse()
    43  
    44  	// Convert DOT files to PNG images.
    45  	for _, dotPath := range flag.Args() {
    46  		if err := convert(dotPath, force); err != nil {
    47  			log.Fatal(err)
    48  		}
    49  	}
    50  }
    51  
    52  // convert converts the provided DOT file to a PNG image.
    53  func convert(dotPath string, force bool) error {
    54  	pngPath := pathutil.TrimExt(dotPath) + ".png"
    55  
    56  	// Skip existing files unless the "-f" flag is set.
    57  	if !force {
    58  		dotStat, err := os.Stat(dotPath)
    59  		if err != nil {
    60  			return errutil.Err(err)
    61  		}
    62  		pngStat, err := os.Stat(pngPath)
    63  		if err != nil {
    64  			if !os.IsNotExist(err) {
    65  				return errutil.Err(err)
    66  			}
    67  		} else {
    68  			dotMod, pngMod := dotStat.ModTime(), pngStat.ModTime()
    69  			if dotMod.Before(pngMod) {
    70  				// PNG file is newer than DOT file, ignore.
    71  				return nil
    72  			}
    73  		}
    74  	}
    75  
    76  	// Convert the DOT file to a PNG image.
    77  	cmd := exec.Command("dot", "-Tpng", "-o", pngPath, dotPath)
    78  	cmd.Stdout = os.Stdout
    79  	cmd.Stderr = os.Stderr
    80  	log.Printf("Creating: %q", pngPath)
    81  	if err := cmd.Run(); err != nil {
    82  		return errutil.Err(err)
    83  	}
    84  
    85  	return nil
    86  }