github.com/vugu/vugu@v0.3.6-0.20240430171613-3f6f402e014b/vugufmt/gofmt.go (about)

     1  package vugufmt
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  )
     9  
    10  // UseGoFmt sets the formatter to use gofmt on x-go blocks.
    11  // Set simplifyAST to true to simplify the AST. This is false
    12  // by default for gofmt, and is the same as passing in -s for it.
    13  func UseGoFmt(simplifyAST bool) func(*Formatter) {
    14  
    15  	return func(f *Formatter) {
    16  		f.ScriptFormatters["application/x-go"] = func(input []byte) ([]byte, *FmtError) {
    17  			return runGoFmt(input, simplifyAST)
    18  		}
    19  	}
    20  }
    21  
    22  func runGoFmt(input []byte, simplify bool) ([]byte, *FmtError) {
    23  	// build up command to run
    24  	cmd := exec.Command("gofmt")
    25  
    26  	if simplify {
    27  		cmd.Args = []string{"-s"}
    28  	}
    29  
    30  	var resBuff bytes.Buffer
    31  
    32  	// I need to capture output
    33  	cmd.Stderr = &resBuff
    34  	cmd.Stdout = &resBuff
    35  
    36  	// also set up input pipe
    37  	cmd.Stdin = bytes.NewReader(input)
    38  
    39  	// copy down environment variables
    40  	cmd.Env = os.Environ()
    41  
    42  	// start gofmt
    43  	if err := cmd.Start(); err != nil {
    44  		return input, &FmtError{Msg: fmt.Sprintf("can't run gofmt: %s", err.Error())}
    45  	}
    46  
    47  	// wait until gofmt is done
    48  	err := cmd.Wait()
    49  
    50  	// Get all the output
    51  	res := resBuff.Bytes()
    52  
    53  	// Wrap the output in an error.
    54  	if err != nil {
    55  		return input, fromGoFmt(string(resBuff.String()))
    56  	}
    57  
    58  	return res, nil
    59  }