/*
* Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.cli;
import com.facebook.buck.test.selectors.TestSelectorList;
import com.facebook.buck.test.selectors.TestSelectorParseException;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.infer.annotation.SuppressFieldNotInitialized;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
public class TestSelectorOptions {
@Option(
name = "--test-selectors",
aliases = {"--filter", "-f"},
usage =
"Select tests to run using <class>, #<method> or <class>#<method>. "
+ "Selectors are interpreted as java.util.regex regular expressions. "
+ "If selectors are given, test result caching is disabled. "
+ "If the class (or method) part is omitted, all classes (or methods) will match. "
+ "If both the class and method is omitted (the string '#') then all tests will match. "
+ "Prefix a selector with '!' to exclude a class or method. "
+ "If multiple selectors are given, the first matching selector is used "
+ "to include (or exclude) a test. "
+ "By default, all tests are excluded unless a selector includes them. "
+ "However, if all selectors are exclusive then the default is to include. "
+ "Use the format '@/path/to/file' to load selectors, one per line, from a file. "
+ "Examples: 'com.example.MyTest' to run all tests in MyTest; "
+ "'com.example.MyTest#testFoo' or 'MyTest#Foo' to just run the testFoo test; "
+ "'!MyTest#Foo' to run everything except the testFoo test; "
+ "'#Important !TestA !TestC #' to only run the important tests in TestA and TestC "
+ "and run everything else.)",
handler = TestSelectorsOptionHandler.class
)
@SuppressFieldNotInitialized
public Supplier<TestSelectorList> testSelectorListSupplier;
@Option(
name = "--explain-test-selectors",
usage = "Buck will say how it interpreted your test selectors before running tests."
)
private boolean shouldExplain = false;
public TestSelectorList getTestSelectorList() {
return testSelectorListSupplier.get();
}
public boolean shouldExplain() {
return shouldExplain;
}
public static class TestSelectorsOptionHandler extends OptionHandler<Supplier<TestSelectorList>> {
private final TestSelectorList.Builder builder = TestSelectorList.builder();
public TestSelectorsOptionHandler(
CmdLineParser parser, OptionDef option, Setter<Supplier<TestSelectorList>> setter)
throws CmdLineException {
super(parser, option, setter);
setter.addValue(Suppliers.memoize(builder::build));
}
@Override
public int parseArguments(Parameters parameters) throws CmdLineException {
String rawTestSelector = parameters.getParameter(0);
try {
builder.addRawSelectors(rawTestSelector);
} catch (TestSelectorParseException e) {
String message = "Unable to parse test selectors: " + e.getMessage();
throw new HumanReadableException(e, message);
}
return 1;
}
@Override
public String getDefaultMetaVariable() {
return "TEST-SELECTOR ";
}
}
}