Issue #11404 has been updated by Nick Fagerlund.

I fixed it [on this 
branch](https://github.com/nfagerlund/puppet/tree/ticket/2.7.x/11404-type-reference-indentation),
 but there are nine test failures. I may need dev resources tomorrow, but most 
of them will probably be obvious fixes.
----------------------------------------
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.

Reply via email to