Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

puppet-lint: Fails to parse parameter of data-type Optional with no default-value #176

Closed
ChrLau opened this issue Nov 15, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@ChrLau
Copy link

ChrLau commented Nov 15, 2023

Introduction

Puppet defines "optional parameters" as parameters with a default value (undef is NOT allowed).
Example: String $i_am_an_optional_parameter = "Because I have a value"
Documentation: https://www.puppet.com/docs/puppet/8/style_guide.html#params-display-order

Puppet also has the Optional data-type for parameters marking them as - well - optional in the terms that undef IS allowed.
Example: Optional[String] $am_i_an_optional_parameter_too = "or not?"
Or with undef:
Example: Optional[String] $am_i_an_optional_parameter_too
Documentation: https://www.puppet.com/docs/puppet/8/lang_data_abstract.html#optional-data-type

Puppet explictily states that: "This is useful for matching values that are allowed to be absent."
Full parapgraph:

The Optional data type wraps one other data type, and results in a data type that matches anything that type would match plus undef. This is useful for matching values that are allowed to be absent.

This naming convention is absolutely misleading as in 99% my clients refer to the later example when they use the term "optional parameter". While "Parameter of data-type optional" would be precise.

Hence I recommend getting rid of the term "optional parameter" in the warning messages all together as it's too ambiguous and therefore not helpful. (Or least make the warning more explanatory.)
Currently, when puppet-lint encounters an optional value which doesn't meet it's criteria it will print the following warning:
WARNING: optional parameter listed before required parameter on line X (check: parameter_order)

Additionlly the official Puppet documentation doesn't help much in the way that it too spreads confusion by stating that "you can list required parameters before optional parameters", when this is clearly not the case. As you MUST list all required parameters (parameters without a default-value) BEFORE any optional parameter (paramters with a default-value).

In parameterized class and defined resource type definitions, you can list required parameters before optional parameters (that is, parameters with defaults).
Documentation: https://www.puppet.com/docs/puppet/8/style_guide.html#params-display-order

Adding to problem is the fact that many people list parameters without the Optional data-type first, and then the parameters with the Optional data-type after them.
Which from my point of view also originates from the fact that the term "optional parameter" is poorly choosen in relation to what it really means technically. (How about the term: "valued parameter"?)

Describe the Bug

These 2 code examples will illustrate the problem as they generate the exact same warning:

  1. Data-Type Optional with a default-value listed before required parameter $blatest with no default-value
class profile::services::test (
  # Switch the next 2 lines and puppet-lint won't print a warning
  Optional[Hash[Stdlib::Port, Stdlib::Host]] $backupservers = {},
  String $blatest,
  String $password = "test",
  Pattern[/^\d+\.\d+\.\d+(?:-\d+)?$/] $version = '11.2.3-4',
  String $system = 'SOMEEXAMPELSTRING',
) {
# intentionally left empty
}
  1. Data-Type Optional with no default-value listed after all parameters which are not of data-type Optional
    This should be allowed according to the documentation. But it isn't.
class profile::services::test (
  String $blatest,
  String $password = "test",
  Pattern[/^\d+\.\d+\.\d+(?:-\d+)?$/] $version = '11.2.3-4',
  String $system = 'SOMEEXAMPELSTRING',
  # Define the Hash as empty or move he lint above/below the $blatest parameter and it passes puppet-lint
  Optional[Hash[Stdlib::Port, Stdlib::Host]] $backupservers,
) {
# intentionally left empty
}

While these 2 code examples will pass puppet-lint:
3. Data-Type Optional with default-value listed after all parameters which are not of data-type Optional and correct ordering of parameters with (no) default-value.

class profile::services::test (
  String $blatest,
  String $password = "test",
  Pattern[/^\d+\.\d+\.\d+(?:-\d+)?$/] $version = '11.2.3-4',
  String $system = 'SOMEEXAMPELSTRING',
  Optional[Hash[Stdlib::Port, Stdlib::Host]] $backupservers = {},
) {
# intentionally left empty
}
  1. Data-Type Optional with no default-value listed before parameters with default-value
class profile::services::test (
  Optional[Hash[Stdlib::Port, Stdlib::Host]] $backupservers,
  String $blatest,
  String $password = "test",
  Pattern[/^\d+\.\d+\.\d+(?:-\d+)?$/] $version = '11.2.3-4',
  String $system = 'SOMEEXAMPELSTRING',
) {
# intentionally left empty
}

However from what the documentation says the code in example 2 should pass puppet-lint without a warning.
Currently it does not.

Expected Behavior

That parameters with no-default value and the Data-Type of Optional produce no linter warning.

This should work according to the documentation:

class profile::services::test (
  String $blatest,
  String $password = "test",
  Pattern[/^\d+\.\d+\.\d+(?:-\d+)?$/] $version = '11.2.3-4',
  String $system = 'SOMEEXAMPELSTRING',
  # Define the Hash as empty or move the line above/below the $blatest parameter and it passes puppet-lint
  Optional[Hash[Stdlib::Port, Stdlib::Host]] $backupservers,
) {
# intentionally left empty
}

Fixed linter warning

Maybe adjust the message from:
WARNING: optional parameter listed before required parameter on line X (check: parameter_order)

to:
WARNING: parameter with default-value ("optional parameter") listed before parameter without default-value ("required parameter") on line X (check: parameter_order)

Environment

  • puppet-lint 4.2.1 (Currently can't test with 5.0.0 because of issue Issue #169 )
@ChrLau ChrLau added the bug Something isn't working label Nov 15, 2023
@ChrLau
Copy link
Author

ChrLau commented Nov 15, 2023

See also #122 which might have added to the confusion/complexity back then.

@ChrLau
Copy link
Author

ChrLau commented Dec 7, 2023

I close this issue. The main problem is that Puppet has the term "optional parameter" for parameters with an assigned default.
But also the Optional-DataType. And that most people refer to the later (as Parameters with that DataType can be undef).

@ChrLau ChrLau closed this as completed Dec 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant