-
Notifications
You must be signed in to change notification settings - Fork 418
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
Add support for variable interpolation in message strings. #526
Comments
Would #428 be sufficient? |
Although system properties could work for one aspect, I don't think it's a general solution since:
Ideally there would be a way to register something similar to a |
I see your point. On the other hand I'm not yet convinced that this needs first-class support with a public API like Providing a system property lookup like |
That's fair, was just relaying where my mind was at. I was also wondering if binding variables from the command itself might be an option, either by an interface or an annotation. |
Unsure what you mean... |
No something like: @Command(...)
public class MyCommand {
@Var("foo")
String foo;
//
// Set foo on construction.
//
@Command(description = "Uses ${foo} to describe things")
public void action() {
// ...
}
} |
That can be achieved by selecting good system property names when using the |
I'm not sure I follow, you mean something like: @Command(...)
public class MyCommand {
{
System.setProperty("foo", "bar");
}
@Command(description = "Uses ${foo} to describe things")
public void action() {
// ...
}
} If so, how does something like this work with inheritance where the base class is defining the method? Wouldn't it be unreconcilable with multiple commands? |
We could have a method: @Command(description = "Uses ${sys:foo} to describe things")
class BaseApp {
String getFooValue() { return "basebar"; }
}
class Subclass extends BaseApp {
@Override String getFooValue() { return "subbar"; }
}
// at app initialization
System.setProperty("foo", getBaseApp().getFooValue()); |
I think this is less than ideal since this information must be controlled at the app level and thus cannot be encapsulated in commands. Second, it assumes no command delegation which I assume is a common pattern (it is for us). Lastly it suffers from all the general problems of singletons and global variables. |
Would a custom lookup |
Indeed it would. Something like |
I just realized that picocli already has |
Ya that might work. I assume it possible to add a bundle programmatically? |
After thinking about this some more, I realized that #480 would also benefit from a Would that meet your requirements? |
I think this plus programmatic message bundles would probably be sufficient. I think having a full parent command path might be more useful than the full command path to the current command. The place this would come in handy is command methods that need to reference peers. |
I have an implementation for String interpolation but still thinking of how to integrate this. Can I bounce this off you: Should the methods in the model return the original Strings, so I don't like losing information, so I would like to do the variable replacement as late as possible, but on the other hand it becomes a bit inconvenient to use... |
Hmm. I guess it is preferred to keep the API surface area as small as possible hence you would just add an overload: |
I'll probably use a flag like The default will be to interpolate. Setting this to |
By the way, for anyone who reads this, would you prefer |
TODO:
|
An initial implementation of this (without the above TODOs) has landed in master. This will be included in the upcoming 4.0-alpha-2 release. If anyone can try this out in the next few days and provide feedback that would be great! Update: the above TODOs have been addressed. TODO:
|
* documentation in release notes * add CommandLine.is/setInterpolateVariables (with tests) * rename CommandSpec.interpolateVariables * support variables in arity and index * annotation processor should not resolve any variables * initial support for escaping with $$ TODO: * interpolating an escaped variable should reduce leading $: replace $${VAR} with ${VAR} * document escaping behaviour * documentation in user manual
All of the above has been implemented and documented. |
See draft release notes for details. |
Very nice work on this, and much appreciated! Will be certain to give feedback as time affords. |
Similar in spirit to
${DEFAULT-VALUE}
and${COMPLETION-CANDIDATES}
, it would be very useful to allow a set of variables to be registered that could then be used in message strings.For example, currently I need to do this on my command methods in a hierarchy:
what would be nicer is:
This would allow inheritance chains to allow for encapsulating command methods in the base class and thus the need to override just to change the variable value statically.
It would be nice to have some predefined variables for common things like parent command name and current command name, as well as the ability to generalize to support this use case and others.
The text was updated successfully, but these errors were encountered: