| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
When we introduced verification of options, we forgot to handle the case that
global options from the Puppet settings system could be passed to the face.
This, in turn, means that the system would fail if you used any of those.
This remediates that, and now these work as expected.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
|
|
|
|
|
|
|
| |
Rewrite the process of validating and updating the options to fully reflect
the contract - we fail if there are unknown options passed, report nicely
errors of duplicate names, pass only the canonical names to the action code,
and generally enforce nicely.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Rather than having multiple, separate operations that modify and validate the
arguments to an action, a single pass makes sense. This also means less walks
across the set of data, and a few less expensive method calls in Ruby.
Additionally, we work on a duplicate of the arguments hash rather than
directly modifying the original. Because everything we do is at the top level
key/value mapping, this is sufficient to isolate the original.
While mostly theoretical, we now don't mutilate the hash passed in, so the
user won't get nastily surprised by the fact that we could have done so.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
As part of moving to load actions first, and their associated face, when
invoked from the command line, it makes sense to push the logic for finding
the action and face down into the Puppet::Face implementation.
This means that we can change the logic there without needing to update the
public part of the CLI implementation, and that any further facades can use
the same, correct, logic to locate the action for the face.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
|
|
|
|
|
|
| |
This implement support for options with default values, allowing faces to set
those values when not invoked. This can eliminate substantial duplicate code
from actions, especially when there are face-level options in use.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
|
|
|
|
|
|
| |
The problem was caused by the fact that the
options method returns a list of options that
treated the aliases as seperate options.
The fix is to only maintain a list of options
and not add all aliases to the options list.
|
|
|
|
|
|
|
| |
2.7.x"
This reverts commit b7ee0258ab40478329c20177eda9b250f27ede18, reversing
changes made to 8fe2e555ac3d57f5b6503ffe1a5466db8d6e190a.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
puppet help was reprinting every option once
for every alias that is had.
This fix involves only storing the option.name
in the @options instance var for both face and
actions options. The @options_hash still
maintains the list of options and aliases as its
keys.
Reviewed-by: Daniel Pittman (puppet-dev list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We accidentally omitted whitespace between multiple options while building the
synopsis. This fixes that, by introducing a breakable space in the right
location.
Additionally, we extract the code that was 99 percent identical from the face
and action synopsis generators, push it down into the documentation module,
and then invoke it from both places.
This eliminates the duplicate code, allowing me to fix that bug once and have
it apply to both parts of the code; this is pretty much assured to be true
any time we change the synopsis generation.
Reviewed-By: Nick Fagerlund <nick.fagerlund@puppetlabs.com>
|
|
|
|
|
|
|
|
|
|
| |
Since some actions take arguments and some do not, action synopses were
incomplete and ambiguous.
This commit adds a method for explicitly declaring what argument(s) an
action takes, and places the arguments at the appropriate spot in the
action's synopsis. By convention, individual arguments should be wrapped
in angle brackets.
|
|
|
|
|
|
|
|
| |
Ruby 1.9 is strict about argument arity for methods that are
metaprogrammatically defined. A ton of specs that were setting up
when_invoked didn't pass options even though they should have been.
Reviewed-by: Daniel Pittman <daniel@puppetlabs.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
We refer to rendering formats pretty consistently as `json`, `yaml`, `s`, and
so forth; unqualified names.
On the other hand, we refer to the rendering hooks *mostly* as `to_*`, except
the `:for_humans` and `:json` formats. Which is kind of confusing because of
the internal inconsistency, and because it doesn't match the public name.
Fix the code to resolve both, so the `to_*` format still works, but we mostly
expect to use the `*` version, to match public expectation.
|
|
|
|
|
|
|
|
| |
We want to be able to document the data returned from an action, since this is
one of the most critical parts of the API for Ruby developers. This adds a
multiline documentation block that captures that.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We used to let actions be declared without the `when_invoked` block, which was
usually a sign of either someone writing their method code direct in action
declaration, or someone forgetting to add their code at all.
This was just let silently by: the error only showed up when you finally tried
to invoke the action, and a NoMethod error was raised by the face.
...except for our own testing. We took advantage of this a whole pile of
times in there; fixing the original UI issue means fixing all those too.
Reviewed-By: Nick Lewis <nick@puppetlabs.com>
|
|\ |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
`before_action` decorations should always resolve in resolution order
from most general (inherited from furthest away) to most specific
(declared on the instance), and should always execute Face-level
option decorations before action-level option decorations.
`after_action` decorations should execute in the opposite order.
Reviewed-By: Daniel Pittman
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
From the command line, and other facades, it is fairly difficult to call an
action with two aliases of the same option in the invocation, but from the
Ruby API it would be relatively easy to achieve.
This is now checked, and raises an error, so that we don't accidentally have
strange or unusual behaviour coming out of the whole system.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We had a problem, previously, in the generic translation of command line
arguments to Ruby method calls: we could mistake the options, added by the CLI
wrapper, for a positional argument to the action method.
This was caused by a combination of factors, but primarily that the wrapper
methods for actions are designed to present a friendly, helpful Ruby API for
internal use. Consequently, they have a default value if you don't wish to
pass options.
Unfortunately, this meant that the options that the CLI *always* passed could
be treated as a positional argument instead, and the default set of options
added to the back of the call.
To resolve this we now check the number of positional arguments in the CLI
wrapper, and raise an exception if they are mismatched. This makes the
generic CLI handling do the right thing in adapting the command line
arguments to the Ruby API.
(As an aside, we would have had a similar-but-different failure mode if we
type-checked positional arguments: these calls would have failed with an
invalid argument validation error.)
Reviewed-By: Max Martin <max@puppetlabs.com>
|
|\ \
| |/
|/| |
|
| |
| |
| |
| |
| |
| |
| | |
This extends the last of the documentation support, down into options, so they
can be described as expected. In the process we split out the modular docs
API into a full and short version options only want short docs, but the
behaviours are identical to the full version.
|
| |
| |
| |
| |
| |
| | |
Given that we have identical documentation behaviour in the face and action
code, it should properly be written once. So, move it into a module, extend
the other classes with it, and have done.
|
|/
|
|
|
|
| |
This allows users to write before_action advice that does basic
option validation very easily.
Reviewed-By: Daniel Pittman
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We previously used *args to collect all arguments to the action when_invoked
block, then tried vaguely to massage some little bits of them into the right
shape.
Methods defined with blocks, in Ruby 1.8, also have some fun behaviours. The
most special is that if you pass more than one argument to a block defined
with only one Ruby will automatically coerce the arguments into an array – and
this is preserved when it is bound to a method.
This led to routine situations where we would pass the wrong number of
arguments to the block because, say, the user gave an extra argument on the
command line.
Instead of failing this would transmogrify the arguments in counterintuitive
ways, and end up with horrible stack traces when that interacted badly with
the code as written.
Now, instead, we work out the right argument format based on the arguments
that the when_invoked block takes. This gives much better (albeit perhaps not
so user friendly) behaviour at the interface level. Which is, at least,
consistent with other Ruby API.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
|
|
|
|
|
|
|
| |
The comment discussing the purpose of the wrapper and related details rightly
belongs outside the method; move it there so it doesn't perturb the functional
changes that follow.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
|\
| |
| |
| | |
Fix the conflicts over changes in my previous commit.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We now find, and call, the appropriate rendering hooks on actions during the
rendering phase. This allows the user to intercept and replace the result
object that passes through the rest of the rendering system on the fly.
Example usage:
action :foo do
when_rendering :pson do |result|
{ :whatever => result[a],
:foobar => result[b],
}
end
end
Reviewed-By: Max Martin <max@puppetlabs.com>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We no longer establish the rendering mode in the actions; they just default to
"nothing", and let that flow on out to the application layer. That lets the
facade we put before the face determine the default behaviour.
This is mostly a no-op down in the CLI side, but it makes it much easier to
integrate into MCollective, HTTP-API, and for other non-CLI users of Faces.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Now we want to support action-based rendering, it is super-hard to define the
semantics around defaulting where things are unspecified: the execution
context (CLI, HTTP, etc) vs the face, vs the action all have different
semantics.
Without solving the problem of how we express all that context and those
semantics down in the action, especially one written by a third party, this
just becomes a box of counter-intuitive and annoying semantics and edge-cases.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
| |
| |
| |
| |
| |
| |
| |
| | |
We can return a method bound to the current face instance when we access the
'when_rendering' hook, which allows us to directly call them. Make that
change, and add appropriate testing.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
These define the API used by folks writing actions that supports their
rendering hooks. 'when_rendering' defines a helper method on the interface,
which runs the users code in their expected context.
'render_as' just sets the default rendering format; by default this is
:for_humans.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
| |
| |
| |
| |
| |
| |
| | |
We had a pending test for this, but forgot to write it way back when we were
implementing the feature. Add it now.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
|\ \
| |/
|/| |
|
| |
| |
| |
| |
| |
| |
| | |
This adds the 'description' method to the faces and actions, as well as
structured testing to ensure that the DSL works as expected.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Our summary documentation is used to provide single-line context to faces,
actions, and other items. To support this we hard-fail if someone tries to
use the summary to embed the long documentation, and point them to the right
place to add the extended text.
Reviewed-By: Max Martin <max@puppetlabs.com>
|
|/
|
|
|
|
|
|
| |
This adds another hook into the generated wrapper, which invokes a method to
validate arguments. This is used to raise an exception when required options
have not been passed to the method.
Reviewed-By: Daniel Pittman <daniel@puppetlabs.com>
|
|\
| |
| |
| | |
'feature/2.7.x/6978-face-and-action-options-should-have-hooks-for-various-actions' into 2.7.x
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Options can now add before_action and after_action blocks; these are invoked
before or after any action is invoked on the face. This allows these options
to declare common behaviour and have it automatically applied to the actions
invoked.
Option hooks have no defined order of invocation: they will run in a
completely random order. Where there are dependencies they should be on the
value of the options hash passed to the invocation, not on side-effects of the
other invocations.
You are not able to influence the arguments, options, or calling of the action
body in a before or after decorator. This is by design.
The invocation passes to the hook:
1. The action object representing this action.
2. The arguments to the action, as an array.
3. The options for the action, as a hash.
Paired-With: Max Martin <max@puppetlabs.com>
|
|/
|
|
|
|
|
| |
This also enables the 'help' action on the 'help'
face to serve as a default action.
Reviewed-By: Daniel Pittman
Reviewed-By: Nick Lewis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We implemented the naive version of inheritance in the faces, in which an
action declared on a superclass remains bound to that even when accessed
from a subclass.
As a consequence our visibility of options on inherited classes is actually
much more limited than it should be, and the actions we inherit would never
see the options they should correctly have.
To fix this we correct the binding bug and handle lookup correctly over
inheritance in our code.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
|
|
|
|
|
| |
This extends the summary function down through the actions themselves,
allowing us to display a useful summary to the user.
Reviewed-By: Matt Robinson <matt@puppetlabs.com>
|
|
|
|
|
|
|
|
|
| |
This splits out the plumbing into the Puppet::Interface namespace, and uses
Puppet::Faces for all the public-facing code.
The fault line is "what you care about if you are using or writing a face",
which is public, against "what you care about to enable either of those two",
which is the plumbing.
|
|
|
|
|
|
|
| |
Now that we have settled on the final public name for the API,
"Puppet::String", mass-rename and mass-edit all the files to follow.
Reviewed-By: Randall Hansen <randall@puppetlabs.com>
|
|
|
|
|
|
|
|
|
| |
When initializing we need to set the name and interface before we do anything
else, since the reasonable assumption for users is that those invariants are
there when their setter is called.
This allows someone to override the interface or name by misusing the call to
new, but they could already screw up by passing the wrong values, so whatever.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
At the moment the action method is a fairly heavy tool: it provides a DSL, and
is designed to allow substantial metadata to be added to the action.
For some users this is low on value, since they just want to write a little
script that drives things a bit differently. Which there is substantial value
in the metadata, adding the capability to do these light-weight things quickly
is valid.
To meet this we add a script action; the contrast is:
action :foo do
# other metadata goes here
invoke do |args|
# method body goes here
end
end
script :bar do |args|
# method body goes here
end
# ...and if you want metadata, you have to add it in more ugly, procedural
# ways, which we are not going to encourage.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
|
|
This class will represents an action, and allows us to store metadata for an
action, and programmatically introspect and invoke them. A helper class
ActionBuilder represents the DSL for defining an action.
Also defined an "invoke" DSL method to handle the functionality of defining the
method for an action.
Reviewed-By: Daniel Pittman
|