Issue #11404 has been reported by Nick Fagerlund.
----------------------------------------
Bug #11404: Indentation gets borked when generating the @doc string for a
type's :provider parameter
https://projects.puppetlabs.com/issues/11404
Author: Nick Fagerlund
Status: Accepted
Priority: Normal
Assignee: Nick Fagerlund
Category: documentation
Target version: 2.7.x
Affected Puppet version: 2.7.8
Keywords: references, providers, types
Branch:
Formatting tweaks to the type and provider desc strings for version 2.7.8
revealed a longstanding bug in the way indentation is handled when assembling
parameter doc fragments to create the `:provider` parameter's doc string. In
summary:
* Using an indented code example in a provider's desc string will cause the
type reference to blow up.
* The multi-paragraph unordered list element in which we wrap the list of
providers should actually not work, but we've been getting by on luck until now.
In detail:
Markdown uses hanging indents (canonically four spaces, but most
implementations also allow alignment to the first text following a list marker)
to delimit the content of multi-paragraph list items. The doc fragments
scattered throughout our type and provider code use indents to preserve the
structure of the files they're contained in. Thus, when assembling fragments
into a document, we have to remove the purely cosmetic indents while preserving
the semantic indents. This is done with the `scrub()` method in
`Puppet::Util::Docs`.
Unfortunately, we're assembling fragments into fragments when building the
provider parameter's documentation, and we weren't handling indentation
recursively. This meant we were assembling a string that:
* Started with a block of eight-space indented text:
desc <<-EOT
The specific backend to use for this
`#{self.to_s.split('::')[2].downcase}`
resource. You will seldom need to specify this --- Puppet will usually
discover the appropriate provider for your platform.
EOT
* ...followed by a block of two-space indented text (which looked "outdented"
compared to its parent):
def self.doc
@doc + " Available providers are:\n\n" + ...
* ...followed by a series of fragments, each of which started with a flush-left
list item and continued with a block of text (pulled from a provider) with a
completely unreliable and arbitrary indent, depending on how its surrounding
code was indented.
}.collect { |i|
"* **#{i}**: #{parenttype().provider(i).doc}"
}.join("\n")
This USUALLY -- by coincidence alone -- came out to an amount of indent
that our markdown processor would accept as a multi-paragraph list item. Note
that these blocks still appeared "outdented" compared to the initial
eight-space indent.
Then, once the whole thing was assembled, it would be fed through `scrub`.
Scrub actually leaves outdented text alone, it turns out! It determines the
amount of space it should be trimming, attempts to trim that from each line,
and leaves the line alone if it doesn't find that amount of space. This usually
resulted in making the original intro text flush left, leaving the list bullets
flush left, and leaving the per-provider text at the (totally coincidental)
correct indentation necessary to stay within its list item element.
However, if you added an indented code example to a parameter's description,
the space of the code indent plus the space of the arbitrary formatting indent
would add up to eight or more spaces, which would cause `scrub` to attack and
allow the code example to escape its enclosing list item element. Which in turn
would cause everything BELOW the code example (indented somewhere kinda-sorta
around four spaces, remember) to look like a really big code block.
This was being hidden before by anemic indentation for the parameters'
description text -- the initial line of the code examples wasn't being
outdented, although the attributes in the example resource were:
service { "myservice":
provider => "daemontools",
path => "/path/to/daemons",
}
...and so it wasn't escaping its list item.
In conclusion, we need to strip cosmetic indents recursively when assembling
fragments out of other fragments, and then specify the exact amount of semantic
indent we want instead of just leaking the cosmetic indent into the final
product and hoping it comes out right.
We should also use definition lists for the lists of providers instead of
unordered lists where each item begins with a bolded label, just because that's
a better conceptual match for what these lists are.
--
You have received this notification because you have either subscribed to it,
or are involved in it.
To change your notification preferences, please click here:
http://projects.puppetlabs.com/my/account
--
You received this message because you are subscribed to the Google Groups
"Puppet Bugs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-bugs?hl=en.