I have a command with subcommands. In my application I want it mandatory for the user to specify a subcommand. How should I do this?
(See also https://github.com/remkop/picocli/issues/529)
Update: this is now documented in the picocli manual: https://picocli.info/#_required_subcommands
Prior to picocli 4.3, the way to achieve this would be to show an error or throw a ParameterException if the top-level command is invoked without subcommand.
For example:
#Command(name = "top", subcommands = {Sub1.class, Sub2.class},
synopsisSubcommandLabel = "COMMAND")
class TopCommand implements Runnable {
#Spec CommandSpec spec;
public void run() {
throw new ParameterException(spec.commandLine(), "Missing required subcommand");
}
public static void main(String[] args) {
CommandLine.run(new TopCommand(), args);
}
}
#Command(name = "sub1)
class Sub1 implements Runnable {
public void run() {
System.out.println("All good, executing Sub1");
}
}
#Command(name = "sub2)
class Sub2 implements Runnable {
public void run() {
System.out.println("All good, executing Sub2");
}
}
From picocli 4.3, this can be accomplished more easily by making the top-level command not implement Runnable or Callable.
If the command has subcommands but does not implement Runnable or Callable, picocli will make subcommands mandatory.
For example:
#Command(name = "top", subcommands = {Sub1.class, Sub2.class},
synopsisSubcommandLabel = "COMMAND")
class TopCommand {
public static void main(String[] args) {
CommandLine.run(new TopCommand(), args);
}
}
Related
I'm new to Antlr, pardon me for basic question, I'm trying to validate the below statement, like if while_condition contains f_lastmove.. do something The while_condition can have other conditions as well. How can I drill down the while_condition? I'm using Listener Pattern with Golang.
I don't know Go, but in Java you could do something like this:
// In this example, the grammar is called `T.g4`
class WhileLastMoveListener extends TBaseListener {
private boolean insideWhileCondition = false;
#Override
public void enterWhile_condition(TParser.While_conditionContext ctx) {
this.insideWhileCondition = true;
}
#Override
public void exitWhile_condition(TParser.While_conditionContext ctx) {
this.insideWhileCondition = false;
}
#Override
public void enterF_lastmove(TParser.F_lastmoveContext ctx) {
if (this.insideWhileCondition) {
// Found a `f_lastmove` rule inside a while `while_condition`
}
}
}
[long description warning]
I'm running some cucumber tests which have to be executed intercalated a defined server - for instance:
a.feature -> JBoss Server 1 | b.feature -> JBoss Serv. 2 | c.feature -> JB1 | etc.
For that, I created a hypothetical ExecutorService like this:
final ExecutorService executorService = Executors.newFixedThreadPool(2); //numberOfServers
for (Runnable task : tasks) {
executorService.execute(task);
}
executorService.shutdown();
try {
executorService.awaitTermination(1000, TimeUnit.SECONDS);
} catch (InterruptedException e) {
//doX();
}
The way that I manage about how will be the server chosen as liable to execute is:
inside of my Runnable class created for the executorService, I pass as a parameter a instanceId to a TestNG (XmlTest class) as below:
#Override
public void run() {
setupTest().run();
}
private TestNG setupTest() {
TestNG testNG = new TestNG();
XmlSuite xmlSuite = new XmlSuite();
XmlTest xmlTest = new XmlTest(xmlSuite);
xmlTest.setName(//irrelevant);
xmlTest.addParameter("instanceId", String.valueOf(instanceId));
xmlTest.setXmlClasses(..........);
testNG.setXmlSuites(..........);
return testNG;
}
Then, I get this just fine in a class that extends TestNgCucumberAdaptor:
#BeforeTest
#Parameters({"instanceId"})
public void setInstanceId(#Optional("") String instanceId) {
if (!StringUtils.isEmpty(instanceId)) {
this.instanceId = Integer.valueOf(instanceId);
}
}
And inside a #BeforeClass I'm populating a Pojo with this instanceId and setting the Pojo in a threadLocal attribute of another class. So far, so good.
public class CurrentPojoContext {
private static final ThreadLocal<PojoContext> TEST_CONTEXT = new ThreadLocal<PojoContext>();
...
public static PojoContext getContext(){
TEST_CONTEXT.get();
}
Now the problem really starts - I'm using Guice (Cucumber guice as well) in a 3rd class, injecting this pojo object that contains the instanceId. The example follows:
public class Environment {
protected final PojoContext pojoContext;
#Inject
public Environment() {
this.pojoContext = CurrentPojoContext.getContext();
}
public void foo() {
print(pojoContext.instanceId); // output: 1
Another.doSomething(pojoContext);
}
class Another{
public String doSomething(PojoContext p){
print(p.instanceId); // output: 2
}
}
}
Here it is not every time like this the outputs (1 and 2) but from time to time, I realized that the execution of different threads is messing with the attribute pojoContext. I know that is a little confusing, but my guess is that the Guice Injector is not thread-safe for this scenario - it might be a long shot, but I'd appreciate if someone else takes a guess.
Regards
Well, just in order to provide a solution for someone else, my solution was the following:
Create a class that maintains a Map with an identifier (unique and thread-safe one) as the key and a Guice Injector as value;
Inside my instantiation of Guice injector, I created my own module
Guice.createInjector(Stage.PRODUCTION, MyOwnModules.SCENARIO, new RandomModule());
and for this module:
public class MyOwnModules {
public static final Module SCENARIO = new ScenarioModule(MyOwnCucumberScopes.SCENARIO);
}
the scope defined here provides the following:
public class MyOwnCucumberScopes {
public static final ScenarioScope SCENARIO = new ParallelScenarioScope();
}
To sum up, the thread-safe will be in the ParallelScenarioScope:
public class ParallelScenarioScope implements ScenarioScope {
private static final Logger LOGGER = Logger.getLogger(ParallelScenarioScope.class);
private final ThreadLocal<Map<Key<?>, Object>> threadLocalMap = new ThreadLocal<Map<Key<?>, Object>>();
#Override
public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
return new Provider<T>() {
public T get() {
Map<Key<?>, Object> scopedObjects = getScopedObjectMap(key);
#SuppressWarnings("unchecked")
T current = (T) scopedObjects.get(key);
if (current == null && !scopedObjects.containsKey(key)) {
current = unscoped.get();
scopedObjects.put(key, current);
}
return current;
}
};
}
protected <T> Map<Key<?>, Object> getScopedObjectMap(Key<T> key) {
Map<Key<?>, Object> map = threadLocalMap.get();
if (map == null) {
throw new OutOfScopeException("Cannot access " + key + " outside of a scoping block");
}
return map;
}
#Override
public void enterScope() {
checkState(threadLocalMap.get() == null, "A scoping block is already in progress");
threadLocalMap.set(new ConcurrentHashMap<Key<?>, Object>());
}
#Override
public void exitScope() {
checkState(threadLocalMap.get() != null, "No scoping block in progress");
threadLocalMap.remove();
}
private void checkState(boolean expression, String errorMessage) {
if (!expression) {
LOGGER.info("M=checkState, Will throw exception: " + errorMessage);
throw new IllegalStateException(errorMessage);
}
}
}
Now the gotcha is just to be careful regarding the #ScenarioScoped and the code will work as expected.
I have written a custom OnMethodBoundaryAspect called TraceAspect. This aspect checks within the OnEntry, OnExit, and OnException methods whether tracing is enabled or not. I have a central class for reading and writing settings. Both of the two methods Settings.GetLoggingEnabled() and Settings.GetLogLevel() are called from the TraceAspect. They are there, so I reuse them which results in a StackOverflowException.
[assembly: MyCompany.MyProduct.TraceAspect]
[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (Settings.GetLogginEnabled() && Settings.GetLogLevel() == LogLevel.Trace)
{
// Log the message
}
}
}
Applying the [TraceAspect(AttributeExclude = true)] attribute to the TraceAspect class leads to the same behaviour.
I could write something like this. But this is code duplication.
[assembly: MyCompany.MyProduct.TraceAspect]
[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
if (this.GetLogginEnabled() && this.GetLogLevel() == LogLevel.Trace)
{
// Log the message
}
}
private bool GetLoggingEnabled()
{
// copy code from Settings.GetLogginEnabled()
}
private bool GetLogLevel()
{
// copy code from Settings.GetLogLevel()
}
}
How can I tell that the Settings.GetLoggingEnabled() and Settings.GetLogTrace() methods should not be traced, when they are called by the aspect?
You can break the recursion during logging by introducing a thread static flag to indicate that you're currently inside the logging call.
[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
[ThreadStatic]
private static bool isLogging;
public override void OnEntry(MethodExecutionArgs args)
{
if (isLogging) return;
isLogging = true;
try
{
if (Settings.GetLogginEnabled() && Settings.GetLogLevel() == LogLevel.Trace)
{
// Log the message
}
}
finally
{
isLogging = false;
}
}
}
I have two projects and two .exes as outputs of these projects. But I want to create one .exe file that can run both. How can I do this in Visual studio 2010?
Move the code from the second project to Class Library instead of an executable. Reference the new project from the first, and then call the code in the second when the first one runs. Your original second executable would also call the code in the new class library.
Two programs:
namespace ProgramA
{
class Program
{
static void Main(string[] args)
{
// Do stuff A
}
}
}
namespace ProgramB
{
class Program
{
static void Main(string[] args)
{
// Do stuff B
}
}
}
Move the code from the second into a class library:
public class ClassB
{
public void DoStuff()
{
// Do stuff B
}
}
Then call it from your first program and your second program:
namespace ProgramA
{
class Program
{
static void Main(string[] args)
{
// Do stuff A
// Do stuff B
var classB = new ClassB();
classB.DoStuff();
}
}
}
namespace ProgramB
{
class Program
{
static void Main(string[] args)
{
// Do stuff B
var classB = new ClassB();
classB.DoStuff();
}
}
}
I'm new to PostSharp and investigating it's use for our project. I'm trying to apply OnMethodBoundaryAspect on an abstract method and getting the following error: http://screencast.com/t/1LyzIz2M
Able to execute the aspect just fine with regular and virtual methods, am I missing anything or is it not possible w/ abstract members?
Here's my simple aspect:
[Serializable]
public sealed class TraceAttribute : OnMethodBoundaryAspect
{
protected string _strMethodName;
protected static readonly Stopwatch _sw = new Stopwatch();
public TraceAttribute(string pMethodName)
{
_strMethodName = pMethodName;
}
public override void OnEntry(MethodExecutionArgs args)
{
_sw.Start();
string strMsg = string.Format(">> Entering {0}.{1}", args.Method.DeclaringType.Name, args.Method);
Debug.Print(strMsg);
}
public override void OnExit(MethodExecutionArgs args)
{
_sw.Stop();
string strMsg = string.Format("<< Leaving {0}.{1} - EXECTIME: {2} ms", args.Method.DeclaringType.Name,
args.Method, _sw.ElapsedMilliseconds);
Debug.Print(strMsg);
_sw.Reset();
}
}