Skip to content

[Core] Add --publish option #2070

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

Merged
merged 62 commits into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
43b5195
Add --publish option to publish to reports.cucumber.io
Jul 25, 2020
0d41b1e
Change banner to cyan
Jul 26, 2020
803f9ec
Override CUCUMBER_MESSAGE_STORE_URL
Jul 26, 2020
ddde173
Create separate PublishFormatter
Jul 27, 2020
efe3f39
Allow --plugin to be enabled via properties
mpkorstanje Jul 28, 2020
b8cf4d4
Prefer inheritance over composition
mpkorstanje Jul 28, 2020
40d985b
Use PLUGIN_PUBLISH_TOKEN_PROPERTY_NAME to enable publish plugin
mpkorstanje Jul 28, 2020
29361b5
Use `properties.getOrDefault`
mpkorstanje Jul 28, 2020
41421aa
Register cucumber.plugin.publish.url as constant
mpkorstanje Jul 28, 2020
f4fb2dd
--publish enables the plugin, so does properties
mpkorstanje Jul 28, 2020
e7564cc
Don't include publish plugin in supported plugins
mpkorstanje Jul 28, 2020
ff43c64
Add color aware to reporter
mpkorstanje Jul 28, 2020
67ab0de
Add monochrome test
mpkorstanje Jul 28, 2020
d72c875
Enable monochrome on publish formatter
mpkorstanje Jul 28, 2020
3560de9
More color aware
mpkorstanje Jul 28, 2020
1ef7165
Clean up
mpkorstanje Jul 28, 2020
92999a4
Clean up
mpkorstanje Jul 28, 2020
44ae655
Clean up
mpkorstanje Jul 28, 2020
69bd809
Fix getOrDefault
mpkorstanje Jul 28, 2020
a7c5ee2
Publish should be the last plugin to receive events
mpkorstanje Jul 28, 2020
97521a2
Add to Cucumber options
mpkorstanje Jul 28, 2020
3ca96c0
Add to CucumberEngineOptions
mpkorstanje Jul 28, 2020
6214e10
Add to CucumberEngineOptions
mpkorstanje Jul 28, 2020
e61334a
Add to PLUGIN_PUBLISH_ENABLED_PROPERTY_NAME
mpkorstanje Jul 28, 2020
58028c0
Merge remote-tracking branch 'origin/main' into publish-option
mpkorstanje Jul 28, 2020
0a1a867
Validate token
mpkorstanje Jul 28, 2020
08986af
Fix token
mpkorstanje Jul 28, 2020
36281c0
[Build] Clean up release command
mpkorstanje Jul 29, 2020
c84bfab
Code formatting
Jul 29, 2020
3537cab
Extract banner class so we can create more banners with ease
Jul 29, 2020
0295666
Tweak banner text and colours
Jul 30, 2020
3f949ee
Formatting
Jul 30, 2020
c588b2a
Add option to quiet publish advertising banner
Jul 30, 2020
9f873f2
Use NoPublishFormatter in junit-platform
Jul 30, 2020
a742163
Merge with main
Jul 30, 2020
cd0706f
Merge branch 'main' into publish-option
Jul 30, 2020
7987d18
Avoid adding a plugin that does nothing
mpkorstanje Jul 30, 2020
f3e9559
Merge branch 'publish-option' of github.com:cucumber/cucumber-jvm int…
mpkorstanje Jul 30, 2020
0e19f99
Fix merge
mpkorstanje Jul 30, 2020
92d1637
Don't test your eye balls
mpkorstanje Jul 30, 2020
c9fdba9
Formatting
mpkorstanje Jul 30, 2020
429851d
Fix merge
mpkorstanje Jul 30, 2020
42ba971
Use case classes for Format and Formats
mpkorstanje Jul 30, 2020
93a4886
require non null
mpkorstanje Jul 30, 2020
53d5ff4
Fix typo
mpkorstanje Jul 30, 2020
79d9db8
Clean up
mpkorstanje Jul 30, 2020
250bd6a
Revapi
mpkorstanje Jul 30, 2020
19ba439
Clean up
mpkorstanje Jul 30, 2020
9c6e90a
Remove unused
mpkorstanje Jul 31, 2020
73c0cff
Merge remote-tracking branch 'origin/main' into publish-option
mpkorstanje Jul 31, 2020
d9fc4b2
Nice curloption
mpkorstanje Jul 31, 2020
b69a04a
Nice curloption
mpkorstanje Jul 31, 2020
31145a7
Merge remote-tracking branch 'origin/main' into publish-option
mpkorstanje Jul 31, 2020
53e5be2
Enable publish plugin via feature toggle
mpkorstanje Jul 31, 2020
ab3e2cb
Clean up
mpkorstanje Jul 31, 2020
55f81f3
Revapi
mpkorstanje Jul 31, 2020
aaf0125
Merge remote-tracking branch 'origin/main' into publish-option
Aug 7, 2020
90f8916
Merge branch 'main' into publish-option
Aug 10, 2020
d4a9b38
Merge branch 'main' into publish-option
Aug 12, 2020
e81fff8
Remove CUCUMBER_PLUGIN_PUBLISH_URL env var. The messages.cucumber.io …
Aug 12, 2020
ba136d0
Update changelog
Aug 12, 2020
7b30c84
Update changelog
Aug 12, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ jobs:
- stage: test
jdk: openjdk11
script: mvn verify -P-spotless-apply --toolchains .travis-toolchains.xml
env: VERIFY=true
env:
- VERIFY=true
# Override https://messages.cucumber.io/api/reports because the subdomain is not yet set up
# Remove this when it is.
- CUCUMBER_PLUGIN_PUBLISH_URL=https://b1f2yk58d8.execute-api.eu-west-3.amazonaws.com/api/reports
- CUCUMBER_PLUGIN_PUBLISH_TOKEN=trigger/build/with/publish/plugin

# 1.3 Coverage
- stage: test
jdk: openjdk11
script: mvn jacoco:prepare-agent verify jacoco:report coveralls:report --toolchains .travis-toolchains.xml
env: COVERAGE=true
env:
- COVERAGE=true

# 1.4 Javadoc
- jdk: openjdk11
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ private RuntimeOptionsBuilder parse(List<String> args) {
parsedOptions.addGlue(parse);
} else if (arg.equals("--tags") || arg.equals("-t")) {
parsedOptions.addTagFilter(TagExpressionParser.parse(removeArgFor(arg, args)));
} else if (arg.equals("--publish")) {
parsedOptions.setPublish(true);
} else if (arg.equals("--plugin") || arg.equals("-p")) {
parsedOptions.addPluginName(removeArgFor(arg, args));
} else if (arg.equals("--no-dry-run") || arg.equals("--dry-run") || arg.equals("-d")) {
Expand Down Expand Up @@ -140,6 +142,7 @@ private RuntimeOptionsBuilder parse(List<String> args) {
}
}
}

return parsedOptions;
}

Expand Down
23 changes: 23 additions & 0 deletions core/src/main/java/io/cucumber/core/options/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,29 @@ public final class Constants {
*/
public static final String PLUGIN_PROPERTY_NAME = "cucumber.plugin";

/**
* Setting this to true will enable publishing.
*/
public static final String PLUGIN_PUBLISH_ENABLED_PROPERTY_NAME = "cucumber.plugin.publish.enabled";

// TODO: Document consistently with other parameters.
/**
* Setting this to true will enable publishing with a Bearer token.
*/
public static final String PLUGIN_PUBLISH_TOKEN_PROPERTY_NAME = "cucumber.plugin.publish.token";

/**
* Defining this will override the publishing URL (it is not sufficient to
* activate publishing).
*/
public static final String PLUGIN_PUBLISH_URL_PROPERTY_NAME = "cucumber.plugin.publish.url";

/**
* Setting this to true will prevent the publish advertising banner from
* being printed.
*/
public static final String PLUGIN_PUBLISH_QUIET_PROPERTY_NAME = "cucumber.plugin.publish.quiet";

/**
* Property name to control naming convention for generated snippets:
* {@value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public RuntimeOptionsBuilder parse(Class<?> clazz) {
addMonochrome(options, args);
addTags(classWithOptions, options, args);
addPlugins(options, args);
addPublish(options, args);
addStrict(options, args);
addName(options, args);
addSnippets(options, args);
Expand Down Expand Up @@ -87,6 +88,12 @@ private void addPlugins(CucumberOptions options, RuntimeOptionsBuilder args) {
}
}

private void addPublish(CucumberOptions options, RuntimeOptionsBuilder args) {
if (options.publish()) {
args.setPublish(true);
}
}

private void addStrict(CucumberOptions options, RuntimeOptionsBuilder args) {
if (!options.strict()) {
throw new CucumberException(
Expand Down Expand Up @@ -199,6 +206,8 @@ public interface CucumberOptions {

String[] plugin();

boolean publish();

boolean monochrome();

String[] name();
Expand Down
37 changes: 17 additions & 20 deletions core/src/main/java/io/cucumber/core/options/CucumberProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import static io.cucumber.core.options.Constants.CUCUMBER_PROPERTIES_FILE_NAME;
import static java.util.Objects.requireNonNull;

/**
* Store properties.
Expand Down Expand Up @@ -58,43 +61,37 @@ public static Map<String, String> fromPropertiesFile() {

public static Map<String, String> fromEnvironment() {
Map<String, String> p = System.getenv();
CucumberPropertiesMap properties = new CucumberPropertiesMap();
properties.putAll(p);
return properties;
return new CucumberPropertiesMap(p);
}

public static Map<String, String> fromSystemProperties() {
Properties p = System.getProperties();
return CucumberPropertiesMap.create(p);
}

static class CucumberPropertiesMap extends HashMap<String, String> {
static class CucumberPropertiesMap extends AbstractMap<String, String> {

private final CucumberPropertiesMap parent;
private final Map<String, String> delegate;

CucumberPropertiesMap() {
this(null);
}

CucumberPropertiesMap(CucumberPropertiesMap parent) {
this(parent, Collections.emptyMap());
CucumberPropertiesMap(CucumberPropertiesMap parent, Map<String, String> delegate) {
this.delegate = requireNonNull(delegate);
this.parent = parent;
}

CucumberPropertiesMap(CucumberPropertiesMap parent, Map<String, String> properties) {
super(properties);
this.parent = parent;
CucumberPropertiesMap(Map<String, String> delegate) {
this(null, delegate);
}

CucumberPropertiesMap(Map<String, String> properties) {
this(null, properties);
@Override
public Set<Entry<String, String>> entrySet() {
return delegate.entrySet();
}

private static CucumberPropertiesMap create(Properties p) {
CucumberPropertiesMap properties = new CucumberPropertiesMap();
for (String key : p.stringPropertyNames()) {
properties.put(key, p.getProperty(key));
}
return properties;
Map<String, String> copy = new HashMap<>();
p.stringPropertyNames().forEach(s -> copy.put(s, p.getProperty(s)));
return new CucumberPropertiesMap(copy);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
import static io.cucumber.core.options.Constants.GLUE_PROPERTY_NAME;
import static io.cucumber.core.options.Constants.OBJECT_FACTORY_PROPERTY_NAME;
import static io.cucumber.core.options.Constants.PLUGIN_PROPERTY_NAME;
import static io.cucumber.core.options.Constants.PLUGIN_PUBLISH_ENABLED_PROPERTY_NAME;
import static io.cucumber.core.options.Constants.PLUGIN_PUBLISH_QUIET_PROPERTY_NAME;
import static io.cucumber.core.options.Constants.PLUGIN_PUBLISH_TOKEN_PROPERTY_NAME;
import static io.cucumber.core.options.Constants.SNIPPET_TYPE_PROPERTY_NAME;
import static io.cucumber.core.options.Constants.WIP_PROPERTY_NAME;
import static io.cucumber.core.options.OptionsFileParser.parseFeatureWithLinesFile;
Expand Down Expand Up @@ -97,6 +100,21 @@ public RuntimeOptionsBuilder parse(Map<String, String> properties) {
splitAndMap(Function.identity()),
builder::addPluginName);

parse(properties,
PLUGIN_PUBLISH_TOKEN_PROPERTY_NAME,
PublishTokenParser::parse,
builder::setPublishToken);

parse(properties,
PLUGIN_PUBLISH_ENABLED_PROPERTY_NAME,
Boolean::parseBoolean,
builder::setPublish);

parse(properties,
PLUGIN_PUBLISH_QUIET_PROPERTY_NAME,
Boolean::parseBoolean,
builder::setPublishQuiet);

parse(properties,
SNIPPET_TYPE_PROPERTY_NAME,
SnippetTypeParser::parseSnippetType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public final class CurlOption {
private final HttpMethod method;
private final List<Entry<String, String>> headers;

CurlOption(URI uri, HttpMethod method, List<Entry<String, String>> headers) {
public CurlOption(URI uri, HttpMethod method, List<Entry<String, String>> headers) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Nicer method here.

this.uri = uri;
this.method = method;
this.headers = headers;
Expand Down
18 changes: 16 additions & 2 deletions core/src/main/java/io/cucumber/core/options/PluginOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import static java.util.Collections.unmodifiableMap;
import static java.util.Collections.unmodifiableSet;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;

public class PluginOption implements Options.Plugin {
Expand Down Expand Up @@ -88,8 +89,8 @@ public class PluginOption implements Options.Plugin {
private final String argument;

private PluginOption(String pluginString, Class<? extends Plugin> pluginClass, String argument) {
this.pluginString = pluginString;
this.pluginClass = pluginClass;
this.pluginString = requireNonNull(pluginString);
this.pluginClass = requireNonNull(pluginClass);
this.argument = argument;
}

Expand All @@ -104,6 +105,19 @@ public static PluginOption parse(String pluginSpecification) {
return new PluginOption(pluginSpecification, pluginClass, pluginWithFile.group(2));
}

public static PluginOption forClass(Class<? extends Plugin> pluginClass, String argument) {
requireNonNull(pluginClass);
requireNonNull(argument);
String name = pluginClass.getName();
return new PluginOption(name + ":" + argument, pluginClass, argument);
}

public static PluginOption forClass(Class<? extends Plugin> pluginClass) {
requireNonNull(pluginClass);
String name = pluginClass.getName();
return new PluginOption(name, pluginClass, null);
}

@SuppressWarnings("unchecked")
private static Class<? extends Plugin> parsePluginName(String pluginSpecification, String pluginName) {
// Refuse plugins known to implement the old API
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.cucumber.core.options;

import java.util.regex.Pattern;

public final class PublishTokenParser {

private PublishTokenParser() {

}

public static String parse(String argument) {
Pattern pattern = Pattern.compile("^[A-Za-z0-9+/=]+$");
if (argument == null || !pattern.matcher(argument).matches()) {
throw new IllegalArgumentException(
"Invalid token. A token must consist of a RFC4648 Base64 encoded string");
}
return argument;
}

}
31 changes: 31 additions & 0 deletions core/src/main/java/io/cucumber/core/options/RuntimeOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import io.cucumber.core.feature.FeatureWithLines;
import io.cucumber.core.order.PickleOrder;
import io.cucumber.core.order.StandardPickleOrders;
import io.cucumber.core.plugin.NoPublishFormatter;
import io.cucumber.core.plugin.PublishFormatter;
import io.cucumber.core.snippets.SnippetType;
import io.cucumber.tagexpressions.Expression;

Expand All @@ -20,6 +22,7 @@

import static io.cucumber.core.resource.ClasspathSupport.rootPackageUri;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;

Expand All @@ -44,6 +47,9 @@ public final class RuntimeOptions implements
private PickleOrder pickleOrder = StandardPickleOrders.lexicalUriOrder();
private int count = 0;
private Class<? extends ObjectFactory> objectFactoryClass;
private String publishToken;
private boolean publish;
private boolean publishQuiet;

private RuntimeOptions() {

Expand Down Expand Up @@ -102,9 +108,23 @@ public List<Plugin> plugins() {
List<Plugin> plugins = new ArrayList<>();
plugins.addAll(formatters);
plugins.addAll(summaryPrinters);
plugins.addAll(getPublishPlugin());
return plugins;
}

private List<Plugin> getPublishPlugin() {
if (publishToken != null) {
return singletonList(PluginOption.forClass(PublishFormatter.class, publishToken));
}
if (publish) {
return singletonList(PluginOption.forClass(PublishFormatter.class));
}
if (publishQuiet) {
return emptyList();
}
return singletonList(PluginOption.forClass(NoPublishFormatter.class));
}

@Override
public boolean isMonochrome() {
return monochrome;
Expand Down Expand Up @@ -229,4 +249,15 @@ void setPickleOrder(PickleOrder pickleOrder) {
this.pickleOrder = pickleOrder;
}

void setPublishToken(String token) {
this.publishToken = token;
}

public void setPublish(boolean publish) {
this.publish = publish;
}

public void setPublishQuiet(boolean publishQuiet) {
this.publishQuiet = publishQuiet;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public final class RuntimeOptionsBuilder {
private boolean addDefaultFormatterIfAbsent;
private boolean addDefaultGlueIfAbsent;
private boolean addDefaultFeaturePathIfAbsent;
private String parsedPublishToken = null;
private Boolean parsedPublish;
private Boolean parsedPublishQuiet;

public RuntimeOptionsBuilder addRerun(Collection<FeatureWithLines> featureWithLines) {
if (parsedRerunPaths == null) {
Expand Down Expand Up @@ -149,6 +152,18 @@ public RuntimeOptions build(RuntimeOptions runtimeOptions) {
runtimeOptions.addDefaultFeaturePathIfAbsent();
}

if (parsedPublishToken != null) {
runtimeOptions.setPublishToken(parsedPublishToken);
}

if (parsedPublish != null) {
runtimeOptions.setPublish(parsedPublish);
}

if (parsedPublishQuiet != null) {
runtimeOptions.setPublishQuiet(parsedPublishQuiet);
}

return runtimeOptions;
}

Expand Down Expand Up @@ -224,4 +239,16 @@ public RuntimeOptionsBuilder addDefaultFeaturePathIfAbsent() {
public void setObjectFactoryClass(Class<? extends ObjectFactory> objectFactoryClass) {
this.parsedObjectFactoryClass = objectFactoryClass;
}

public void setPublishToken(String token) {
this.parsedPublishToken = token;
}

public void setPublish(boolean publish) {
this.parsedPublish = publish;
}

public void setPublishQuiet(boolean publishQuiet) {
this.parsedPublishQuiet = publishQuiet;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.cucumber.core.plugin;

final class AnsiEscapes {

static final AnsiEscapes RESET = color(0);
static final AnsiEscapes BLACK = color(30);
static final AnsiEscapes RED = color(31);
Expand Down
Loading