Skip to content

Commit

Permalink
Add missing docs override (#1500)
Browse files Browse the repository at this point in the history
During provider updates, we occasionally have missing docs that we
accept. We also set `PULUMI_MISSING_DOCS_ERROR=true` during updates so
we are made aware. Right now, the solution is to set
`tfbridge.DocInfo{Markdown: []byte(" ")}`, which prevents docs from ever
showing up.

This PR adds a flag for this scenario, that mitigates the error for
missing docs but doesn't preclude the doc showing up in the future.
  • Loading branch information
iwahbe authored Nov 3, 2023
1 parent 1e955db commit 2180299
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 8 deletions.
5 changes: 5 additions & 0 deletions pkg/tfbridge/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,11 @@ type DocInfo struct {
// this document will satisfy the criteria `docs/pulumiToken.md`
// The examples need to wrapped in the correct shortcodes
ReplaceExamplesSection bool

// Don't error when this doc is missing.
//
// This applies when PULUMI_MISSING_DOCS_ERROR="true".
AllowMissing bool
}

// GetImportDetails returns a string of import instructions defined in the Pulumi provider. Defaults to empty.
Expand Down
2 changes: 1 addition & 1 deletion pkg/tfgen/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ func getDocsForResource(g *Generator, source DocsSource, kind DocKind,
msg := fmt.Sprintf("could not find docs for %v %v. Override the Docs property in the %v mapping. See "+
"type tfbridge.DocInfo for details.", kind, formatEntityName(rawname), kind)

if cmdutil.IsTruthy(os.Getenv("PULUMI_MISSING_DOCS_ERROR")) {
if cmdutil.IsTruthy(os.Getenv("PULUMI_MISSING_DOCS_ERROR")) && !info.GetDocs().AllowMissing {
g.error(msg)
return entityDocs{}, fmt.Errorf(msg)
}
Expand Down
92 changes: 85 additions & 7 deletions pkg/tfgen/docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1133,25 +1133,103 @@ func TestParseTFMarkdown(t *testing.T) {
}
}

func TestErrorMissingDocs(t *testing.T) {
tests := []struct {
docs tfbridge.DocInfo
forbidMissingDocsEnv string
source DocsSource
expectErr bool
}{
// No Error, since the docs can be found
{source: mockSource{"raw_name": "some-docs"}},
{
source: mockSource{"raw_name": "some-docs"},
forbidMissingDocsEnv: "true",
},

// Docs are missing, but we don't ask to error on missing
{source: mockSource{}},

// Docs are missing, and we ask to error on missing, so error
{
source: mockSource{},
forbidMissingDocsEnv: "true",
expectErr: true,
},

// Docs are missing and we ask globally to error on missing, but we
// override locally, so no error
{
source: mockSource{},
docs: tfbridge.DocInfo{AllowMissing: true},
forbidMissingDocsEnv: "true",
},
}

for _, tt := range tests {
tt := tt
t.Run("", func(t *testing.T) {
g := &Generator{
sink: mockSink{t},
}
rawName := "raw_name"
t.Setenv("PULUMI_MISSING_DOCS_ERROR", tt.forbidMissingDocsEnv)
_, err := getDocsForResource(g, tt.source, ResourceDocs, rawName, &mockResource{
token: tokens.Token(rawName),
docs: tt.docs,
})
if tt.expectErr {
assert.NotNil(t, err)
} else {
assert.NoError(t, err)
}
})
}
}

type mockSource map[string]string

func (m mockSource) getResource(rawname string, info *tfbridge.DocInfo) (*DocFile, error) {
f, ok := m[rawname]
if !ok {
return nil, nil
}
return &DocFile{
Content: []byte(f),
FileName: rawname + ".md",
}, nil
}
func (m mockSource) getDatasource(rawname string, info *tfbridge.DocInfo) (*DocFile, error) {
return nil, nil
}

type mockSink struct{ t *testing.T }

func (mockSink) warn(string, ...interface{}) {}
func (mockSink) debug(string, ...interface{}) {}
func (mockSink) error(string, ...interface{}) {}
func (mockSink) warn(string, ...interface{}) {}
func (mockSink) debug(string, ...interface{}) {}
func (mockSink) error(string, ...interface{}) {}
func (mockSink) Logf(sev diag.Severity, diag *diag.Diag, args ...interface{}) {}
func (mockSink) Debugf(diag *diag.Diag, args ...interface{}) {}
func (mockSink) Infof(diag *diag.Diag, args ...interface{}) {}
func (mockSink) Infoerrf(diag *diag.Diag, args ...interface{}) {}
func (mockSink) Errorf(diag *diag.Diag, args ...interface{}) {}
func (mockSink) Warningf(diag *diag.Diag, args ...interface{}) {}

func (mockSink) Stringify(sev diag.Severity, diag *diag.Diag, args ...interface{}) (string, string) {
return "", ""
}

type mockResource struct {
docs tfbridge.DocInfo
token tokens.Token
}

func (r *mockResource) GetFields() map[string]*tfbridge.SchemaInfo {
//TODO implement me
panic("implement me")
return map[string]*tfbridge.SchemaInfo{}
}

func (r *mockResource) ReplaceExamplesSection() bool {
//TODO implement me
panic("implement me")
return false
}

func (r *mockResource) GetDocs() *tfbridge.DocInfo {
Expand Down

0 comments on commit 2180299

Please sign in to comment.