// Copyright 2026 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package sgutil import ( "bufio" "bytes" "fmt" "go/format" "os" "path/filepath" ) func CreatePath(newFile string) (*os.File, error) { dir := filepath.Dir(newFile) err := os.MkdirAll(dir, 0755) if err != nil { return nil, fmt.Errorf("failed to create directory %s: %w", dir, err) } f, err := os.Create(newFile) if err != nil { return nil, fmt.Errorf("failed to create file %s: %w", newFile, err) } return f, nil } // FormatWriteAndClose formats the Go source code in source and writes it // to newFile. If there is a problem with the formatting, the // entire source is numbered and emitted along with the error message, // to help figure out where the source code generation went wrong. func FormatWriteAndClose(source *bytes.Buffer, newFile string) { b, err := format.Source(source.Bytes()) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%s\n", NumberLines(source.Bytes())) fmt.Fprintf(os.Stderr, "%v\n", err) panic(err) } else { WriteAndClose(b, newFile) } } // WriteAndClose creates newFile, writes g to it, // and closes the file. func WriteAndClose(b []byte, newFile string) { ofile, err := CreatePath(newFile) if err != nil { panic(err) } ofile.Write(b) ofile.Close() } // NumberLines takes a slice of bytes, and returns a string where each line // is numbered, starting from 1. func NumberLines(data []byte) string { var buf bytes.Buffer r := bytes.NewReader(data) s := bufio.NewScanner(r) for i := 1; s.Scan(); i++ { fmt.Fprintf(&buf, "%d: %s\n", i, s.Text()) } return buf.String() }