Skip to content

Commit

Permalink
feat: add option to inject docs into existing file
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Rose <[email protected]>
  • Loading branch information
matty-rose committed Nov 14, 2021
1 parent e42ef59 commit bb0860f
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 21 deletions.
16 changes: 15 additions & 1 deletion cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ var format string
// Output file flag
var outputFile string

// Inject flag
var inject bool

// generateCmd represents the generate command
var generateCmd = &cobra.Command{
Use: "generate [PATH]",
Expand All @@ -55,7 +58,11 @@ var generateCmd = &cobra.Command{

content := g.Generate(action)

err = writer.Write(content, outputFile)
err = writer.Write(writer.WriteInputs{
Content: content,
OutputFile: outputFile,
Inject: inject,
})
return err
},
}
Expand All @@ -75,5 +82,12 @@ func init() {
"",
"File to write generated documentation to.",
)
generateCmd.PersistentFlags().BoolVarP(
&inject,
"inject",
"i",
false,
"Set flag to inject generated documentation between markers. Ignored if not writing to a file. Defaults to false.",
)
rootCmd.AddCommand(generateCmd)
}
71 changes: 53 additions & 18 deletions pkg/writer/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,52 +25,87 @@ import (
"fmt"
"io"
"os"
"strings"

"github.com/pkg/errors"
)

const (
BeginInjection string = "<!-- BEGIN GHA DOCS -->"
EndInjection string = "<!-- END GHA DOCS -->"
)

type stdoutWriter struct{}

func (sw stdoutWriter) Write(content []byte) (int, error) {
return os.Stdout.Write(content)
}

type fileWriter struct {
file string
file string
inject bool
}

func (fw fileWriter) Write(content []byte) (n int, err error) {
f, err := os.OpenFile(fw.file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return 0, errors.Wrap(err, fmt.Sprintf("couldn't open file: %s", fw.file))
func (fw fileWriter) Write(content []byte) (int, error) {
if !fw.inject {
return fw.writeFile(content)
}

existingFileContent, err := os.ReadFile(fw.file)
if err != nil || len(existingFileContent) == 0 {
// Even if inject flag is passed, if file doesn't exist OR is empty, then write as per normal.
return fw.writeFile(content)
}

return fw.injectContent(string(existingFileContent), string(content))
}

func (fw fileWriter) injectContent(existing, newContent string) (int, error) {
beginIdx := strings.Index(existing, BeginInjection)
endIdx := strings.Index(existing, EndInjection)

if beginIdx == -1 {
return 0, errors.New(fmt.Sprintf("missing begin injection marker: %s", BeginInjection))
}

if endIdx == -1 {
return 0, errors.New(fmt.Sprintf("missing end injection marker: %s", EndInjection))
}

if endIdx < beginIdx {
return 0, errors.New("end injection marker is before begin injection marker")
}

defer func() {
cerr := f.Close()
if err == nil {
err = cerr
}
}()
injectedContent := existing[:beginIdx+len(BeginInjection)] + "\n" + newContent + existing[endIdx:]

n, err = f.Write(content)
return fw.writeFile([]byte(injectedContent))
}

func (fw fileWriter) writeFile(content []byte) (int, error) {
err := os.WriteFile(fw.file, []byte(content), 0644)
if err != nil {
return 0, errors.Wrap(err, fmt.Sprintf("couldn't write to file: %s", fw.file))
}

// Uses named return values
return
return len(content), err
}

type WriteInputs struct {
Content string
OutputFile string
Inject bool
}

func Write(content string, outputFile string) error {
func Write(inputs WriteInputs) error {
var w io.Writer

if outputFile != "" {
w = fileWriter{outputFile}
if inputs.OutputFile != "" {
w = fileWriter{inputs.OutputFile, inputs.Inject}
} else {
w = stdoutWriter{}
}

_, err := io.WriteString(w, content)
_, err := io.WriteString(w, inputs.Content)

return err
}
4 changes: 2 additions & 2 deletions pkg/writer/writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestStdoutWriter(t *testing.T) {
outC <- buf.String()
}()

writer.Write(tc, "")
writer.Write(writer.WriteInputs{Content: tc, OutputFile: "", Inject: false})

// back to normal state
w.Close()
Expand All @@ -78,7 +78,7 @@ func TestFileWriter(t *testing.T) {
shenanigans`}

for _, tc := range testCases {
writer.Write(tc, testFile)
writer.Write(writer.WriteInputs{Content: tc, OutputFile: testFile, Inject: false})

got, err := os.ReadFile(testFile)
if err != nil {
Expand Down

0 comments on commit bb0860f

Please sign in to comment.