Skip to content

Commit

Permalink
Print generated markdown to STDOUT.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmalloc committed Mar 10, 2023
1 parent f04accb commit 7747589
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 30 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ The format is based on [Keep a Changelog], and this project adheres to
[keep a changelog]: https://keepachangelog.com/en/1.0.0/
[semantic versioning]: https://semver.org/spec/v2.0.0.html

## [0.4.1] - 2023-03-10

### Fixed

- Markdown documentation is now rendered to `stdout` (instead of `stderr`) as intended

## [0.4.0] - 2023-03-10

### Added
Expand Down Expand Up @@ -113,6 +119,7 @@ The two most important changes in usage are:
[0.3.5]: https://github.com/dogmatiq/ferrite/releases/tag/v0.3.5
[0.3.6]: https://github.com/dogmatiq/ferrite/releases/tag/v0.3.6
[0.4.0]: https://github.com/dogmatiq/ferrite/releases/tag/v0.4.0
[0.4.1]: https://github.com/dogmatiq/ferrite/releases/tag/v0.4.1

<!-- version template
## [0.0.1] - YYYY-MM-DD
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Ferrite can automatically generate Markdown documentation for the declared
environment variables by executing the application with the `FERRITE_MODE`
environment variable set to `usage/markdown`.

This causes the `ferrite.Init()` function to print the Markdown to `STDERR`, and
This causes the `ferrite.Init()` function to print the Markdown to `STDOUT`, and
then exit the process before the application code is executed.

### Other Implementations
Expand Down
3 changes: 1 addition & 2 deletions init.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ func Init(options ...InitOption) {
switch m := os.Getenv("FERRITE_MODE"); m {
case "usage/markdown":
app := filepath.Base(os.Args[0])
result := markdownmode.Run(app, reg)
io.WriteString(opts.Err, result)
markdownmode.Run(reg, app, opts.Out)
opts.Exit(0)

case "validate", "":
Expand Down
2 changes: 2 additions & 0 deletions init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// example is a helper function that sets up the global state for a testable
// example. It returns a function that resets the global state after the test.
func example() func() {
ferrite.XDefaultInitOptions.Out = os.Stdout
ferrite.XDefaultInitOptions.Err = os.Stdout
ferrite.XDefaultInitOptions.Exit = func(code int) {}

Expand All @@ -19,6 +20,7 @@ func example() func() {

// tearDown resets the environemnt and Ferrite global state after a test.
func tearDown() {
ferrite.XDefaultInitOptions.Out = os.Stdout
ferrite.XDefaultInitOptions.Err = os.Stderr
ferrite.XDefaultInitOptions.Exit = os.Exit

Expand Down
9 changes: 6 additions & 3 deletions internal/markdownmode/preamble_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package markdownmode_test

import (
"bytes"
"os"
"path/filepath"

Expand Down Expand Up @@ -39,12 +40,14 @@ var _ = Describe("func Run()", func() {
)
Expect(err).ShouldNot(HaveOccurred())

actual := Run(
"<app>",
actual := &bytes.Buffer{}
Run(
reg,
"<app>",
actual,
WithoutUsageExamples(),
)
ExpectWithOffset(1, actual).To(EqualX(string(expect)))
ExpectWithOffset(1, actual.String()).To(EqualX(string(expect)))
},
Entry(
"no variables",
Expand Down
22 changes: 11 additions & 11 deletions internal/markdownmode/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package markdownmode

import (
"fmt"
"io"
"strings"

"github.com/dogmatiq/ferrite/internal/wordwrap"
Expand All @@ -10,17 +11,17 @@ import (
)

type renderer struct {
App string
Specs []variable.Spec
App string
Specs []variable.Spec
Output io.Writer

w strings.Builder
withoutPreamble bool
withoutIndex bool
withoutUsageExamples bool
refs map[string]struct{}
}

func (r *renderer) Render() string {
func (r *renderer) Render() {
r.line("# Environment Variables")

if !r.withoutPreamble {
Expand Down Expand Up @@ -52,26 +53,25 @@ func (r *renderer) Render() string {
r.gap()
r.renderRefs()
}

return r.w.String()
}

func (r *renderer) gap() {
r.w.WriteByte('\n')
r.line("")
}

func (r *renderer) line(f string, v ...any) {
fmt.Fprintf(&r.w, f+"\n", v...)
if _, err := fmt.Fprintf(r.Output, f+"\n", v...); err != nil {
panic(err)
}
}

func (r *renderer) paragraph(text ...string) func(...any) {
return func(v ...any) {
text := fmt.Sprintf(strings.Join(text, " "), v...)

r.gap()
for _, l := range wordwrap.Wrap(text, 80) {
r.w.WriteString(l)
r.w.WriteByte('\n')
for _, line := range wordwrap.Wrap(text, 80) {
r.line("%s", line)
}
}
}
Expand Down
14 changes: 9 additions & 5 deletions internal/markdownmode/run.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
package markdownmode

import (
"io"

"github.com/dogmatiq/ferrite/variable"
)

// Run generates environment variable usage instructions in markdown format.
func Run(
app string,
reg *variable.Registry,
app string,
w io.Writer,
options ...Option,
) string {
) {
r := renderer{
App: app,
Specs: reg.Specs(),
App: app,
Specs: reg.Specs(),
Output: w,
}

for _, opt := range options {
opt(&r)
}

return r.Render()
r.Render()
}

// Option is a function that changes the behavior of a renderer.
Expand Down
8 changes: 5 additions & 3 deletions internal/markdownmode/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@ var _ = Describe("func Run()", func() {
)
Expect(err).ShouldNot(HaveOccurred())

actual := Run(
"<app>",
actual := &bytes.Buffer{}
Run(
reg,
"<app>",
actual,
WithoutPreamble(),
WithoutIndex(),
WithoutUsageExamples(),
)
ExpectWithOffset(1, actual).To(EqualX(string(expect)))
ExpectWithOffset(1, actual.String()).To(EqualX(string(expect)))
},

// BOOL
Expand Down
10 changes: 8 additions & 2 deletions internal/markdownmode/usage_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package markdownmode_test

import (
"bytes"
"os"
"path/filepath"

Expand Down Expand Up @@ -39,8 +40,13 @@ var _ = Describe("func Run()", func() {
)
Expect(err).ShouldNot(HaveOccurred())

actual := Run("<app>", reg)
ExpectWithOffset(1, actual).To(EqualX(string(expect)))
actual := &bytes.Buffer{}
Run(
reg,
"<app>",
actual,
)
ExpectWithOffset(1, actual.String()).To(EqualX(string(expect)))
},
Entry(
"usage",
Expand Down
14 changes: 11 additions & 3 deletions internal/validatemode/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,17 @@ func Run(reg *variable.Registry, w io.Writer) bool {
}

if show {
io.WriteString(w, "Environment Variables:\n\n")
t.WriteTo(w)
io.WriteString(w, "\n")
if _, err := io.WriteString(w, "Environment Variables:\n\n"); err != nil {
panic(err)
}

if _, err := t.WriteTo(w); err != nil {
panic(err)
}

if _, err := io.WriteString(w, "\n"); err != nil {
panic(err)
}
}

return valid
Expand Down

0 comments on commit 7747589

Please sign in to comment.