Puppet Code Formatter

Thomas Hallgren edited this page Sep 10, 2013 · 1 revision

h2. Basic Principles

h3. Indentation

p. The default indentation for Puppet is 2 spaces, but this can be changed. The Geppetto formatter always use spaces and formats based on the formatting preference (as opposed to the general text-editor setting that affects other non puppet related editors).

h4. Width

p. The page width is set to 132 by default as this is what typically works on most screens. If you want to use the width recommended by the Puppet style guide, you should change this to 80. The width can be set to a value between 40 and 255.

p. Tip: It is possible to turn on "Show print margin" under general preferences for text editors. The print-margin displayed in puppet manifest editors is placed at the formatting width.

h3. Alignment

p. The Geppetto formatter aligns several different types of statements using "cluster analysis":http://en.wikipedia.org/wiki/Cluster_analysis. Elements are clustered based on how close they are to other elements (individual, or already clustered) without making the cluster wider than a given maximum width. A user preference controls the maximum allowed width. In simple terms; lines of similar lengths are grouped, and other elements of similar length are padded to make the element widths equal.

In addition to the maximum cluster width, it is possible to control more details of when things are aligned using preferences. This is described per statement.

h3. Line breaks / spacing

p. All statements starts on their own line. Block statements are preceded with a minimum of one blank line. All other statements allow an optional extra preceding blank line.

The following statements are considered block statements:

  • case
  • define
  • class
  • if
  • node
  • resource statement e.g. file { } (and those that look alike e.g. File { }, and class { }).
  • selector statement

p. A sequence of preceding comments is counted as one in this scheme.

Example - the following input:

# comment
$a = 1
# comment
# comment
case $a {
  1 : {
    $x = true
  }
}

Becomes:

# comment
$a = 1

# comment
# comment
case $a {
  1 : {
    $x = true
  }
}

h3. Workspace vs. Project settings

p. All formatting preferences are settable both for the workspace and for individual projects (that override the workspace settings when present). It is highly recommended to check in the various files found in the project's /.settings directory as this will ensure that all users gets the same settings, and you don't have to remember to set up the preferences the way you want when creating a new workspace.

p. The workspace preferences are found under "Preferences" in the main menu. Project settings are found under "Properties" in the context menu for a project.

p. Pro tip, if you set up one project the way you want, you can copy the corresponding files from .settings to your other projects that should have the same settings/preferences.

h2. Formatting of Resource statements (and lookalikes)

p. Resource statements, as well as statements that look the same; resource-defaults, and realization of parameterized classes, are formatted with aligned parameter/property-settings.

Examples:

file { 'title':
  a   => value,
  bbb => value
}

File {
  a   => value,
  bbb => value
}

class { 'someclass':
  a   => value,
  bbb => value,
}

Resources that fit on one line and that have max a title and a single parameter can optionally be formatted in compact form

file { 'title': ensure => present }

h2. Formatting of lists and hashes

p. Lists and hashes can be formatted using flow layout, or using break and align. In flow layout, elements in the list / hash are simply separated with a space, if the line overflows it is indented and the output again continues until the line overflows or stops.

The formatting of lists and hashes is controlled via preferences. The options are:

  • Always, will always break and align the even if there is no overflow
  • OnOverflow, will break and align the when there is overflow
  • Never, performs flow formatting, on overflow the extra lines are indented from the start of the list/hash.

The preferences are found under "Preferences > Puppet > Formatting > Break and Align".

h2. Formatting of class and definition parameters

p. Geppetto offers formatting of parameters in class and define statements in several ways. The default is to basic spacing formatting; space after comma ,, no space after left parenthesis ( and no space before right parenthesis ) unless the list of parameters overflow the available width. When the list overflows, the default is to break the list with one parameter per line, and to align the assignment operators.

Example:

define formatMe ($a, $b = 10, $aLongName = 20, $anEvenLongerName = 30, $c = 'causes overflow') {
}

Is formatted as:

define formatMe (
  $a,
  $b                = 10,
  $aLongName        = 20,
  $anEvenLongerName = 30,
  $c                = 'causes overflow') {
}

The options are:

  • Always, will always break and align the list even if it does not cause overflow
  • DefaultsPresent, will break and align the list if there are default assignments or if it overflows
  • OnOverflow, will break and align the list if it overflows
  • Never, will do flow formatting of the list if it overflows, indenting following lines

The alignment of the assignment operators is based on clustering where the items closest to each other in length are clustered and a clusters width is never wider than a user preference for cluster width (default is 20 characters).

All preferences can be saved per project and will then override the workspace wide settings in Geppetto.

h2. Formatting of case statements

p. Case statements are formatted with alignment on the colon after the case match expression(s). By default, case expressions are rendered in compact form (the entire case on one line) if possible. A preference controls if compact form rendering is performed, or if the long form should always be used.

p. Case statements can be compressed when:

  • there is only one statement in the case body
  • the single statement does not overflow / is on one line
  • the single statement is not a block statement (they typically span multiple lines)

Two preferences control how cases are formatted; align on :, and compact when possible. Here are some examples:

No alignment, and not compact:

case $a {
  'val1' : {
    $x = true
  }
  'val2', 'val3', 'val4' : {
    $x = false
  }
}

No alignment, and compact:

case $a {
  'val1' : { $x = true }
  'val2', 'val3', 'val4' : { $x = false }
}

And finally (the default), align and compact:

case $a {
  'val1'                 : { $x = true }
  'val2', 'val3', 'val4' : { $x = false }
}

h2. Formatting of Assignment Statements

p. Assignment expression i.e. using operations = and += can optionally be aligned using clustering. A sequence of assignments (that can be a mix of = and +=) that is not broken by some other statement will be processed as one unit. Comments and blank lines does not break the sequence. In case there is a mix of operators in the sequence, alignment is performed on the = sign as in the following example:

$short        = 10
$much_longer  = 20
$my_array    += 30

h2. Formatting of comments

p. Comments are considered verbatim text and are only touched by formatting when they are in a position where they overflow the current max width, or when multi-line comments are not left aligned. These defaults can be overridden under preferences, including turning off comment formatting.

h3. Alignment

h4. Multi line comments

p. Multi-line comments /* / are expected to use as the first character on all additional lines. Formatting will insert missing asterisks, and will use the position of the starting /* to guess at the left margin for lines without a leading asterisk.

class foo {
  /* I have
         * alignment
 *  issues, and 
           missing asterisks
   */
}

Is formatted as:

class foo {
  /* I have
   * alignment
   *  issues, and
   * missing asterisks
   */
}

p. Note that the line with the text 'issues, and' has an extra space in the left margin, this because the left margin is kept when there was a * that showed where the left edge of that comment line really is. For the line 'missing asterisks' the first non whitespace character gets aligned with the natural left edge of the comment text.

h4. Single Line (hash) comments

p. Single line comments are aligned if they are in a sequence with only whitespace separating them, and if a comment line is no further away from its preceding comment than one indent size. A single line comment that is further away is considered to break the sequence and may thus be moved (to the effective indent).

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { # short stuff I
                                                            # wrote here
                                                           #
}

Is formatted as:

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { # short stuff I
                                                             # wrote here
                                                             #
}

And, when a line is further away, it breaks the sequence (and should be placed at the current indent)

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { # short stuff I
                                                            # wrote here
                                                          #
}

Is formatted as:

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { # short stuff I
                                                             # wrote here
  #
}

h3. Overflow

  • A comment line that causes overflow is folded at the leftmost whitespace position closes to the overflow position.
  • Comments will not flow or re-flow paragraphs; long lines are simply folded. (This may change in the future, but requires more advanced formatting for documentation comments as they would otherwise be royally screwed up).
  • Comments at the end of a line that does not fit will first be formatted for this position as a hanging comment, breaking it up on multiple lines if required. If the comment still does not fit (because it contains unbreakable lines, or there is just a tiny bit of space left) the comment is moved to the next line, and formatted to fit the available space on this line.

Examples (formatted for 80 characters width): Input:

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { /* short stuff I wrote here
                                                              */ 
}

Formatted:

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { /* short stuff I
                                                              * wrote here
                                                              */ 
}

Input :

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { /* looooooooooooooooooooong
                                                              * stuff I
                                                              * wrote here
                                                              */ 
}

Formatted:

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { 
  /* looooooooooooooooooooong
   * stuff I
   * wrote here
   */ 
}

A single line comment like this:

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { # short stuff I wrote here 
}

Is formatted as:

class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa { # short stuff I
                                                             # wrote here 
}

h3. Empty line trimming

p. Comment sequences are subject to trimming of trailing empty comment lines. The default is to enforce 1 empty line for multi line comments, and 0 for single line. Both types allow a maximum of 1 empty trailing line.

h3. Left Margin

p. The left margin (between the comment tokens /* * */ # and the following text is one character, with the exception of Banner Lines and Instruction Lines which appear directly after the comment token.

h3. Banner Lines

p. Banner lines are lines consisting of a single repeating non alphanumerical character. Banner lines do not have a left margin, and when they overflow they can optionally be left as they are, folded, or truncated. The default is to truncate them to the available width.

h3. Instruction Lines

p. Instruction lines (just like banners) consist of a single repeating alphanumerical character, but such lines shorter than 5 characters in length are considered to be instruction lines, and they are never folded or truncated. (As an example, --- and +++ are RDoc processing instructions that tells RDoc to not include what follows in the generated documentation (and then start again on +++). It would not be good if these lines where formatted.

h3. Verbatim sections

p. Verbatim sections are sections that appear between $ ... $ and such sections are not eligible for folding. Such verbatim sections are often used for "string replacement on checkout" (primarily when using SVN, but this is also available in Git). Since these special variables may be subject to interpretation by other tools, it is important to keep these sections verbatim.

h3. Comment Formatting Preferences

p. It is possible to control the behavior of the comment formatting:

  • Formatting can be turned on/off for single line and multi-line comments individually.
  • When banners overflow, the rule can be set to NoWrap, Truncate, or Fold.
  • When comment-text overflows, the rule can be set to NoFormat, NoWrap, or Fold, where NoFormat means that not even alignment is done.
  • Instruction/Special line processing (placing them in the left margin) can be turned on/off.
  • Verbatim sections ($..$) can be turned on/off.

All preferences can be saved per project and will then override the workspace wide settings in Geppetto.

h2. Current Issues with comment formatting

  • A comment that is moved/folded from an end of line position may if it then appears next to a documentable statement shift from being just a comment to documentation of the following statement.
  • Currently no preference for max allowed trailing comment lines (max is currently 1)
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.