Skip to content
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

[cli][docker] Better expose version/sha information of builds #5736

Merged
merged 3 commits into from
Apr 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 26 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,33 @@ after_success:
fi;
fi;
## docker: build and push openapi-generator-online to DockerHub
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && docker build -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/openapi-generator-online && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_GENERATOR_IMAGE_NAME:latest $DOCKER_GENERATOR_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_GENERATOR_IMAGE_NAME && echo "Pushed to $DOCKER_GENERATOR_IMAGE_NAME"; fi; fi
- if [ $DOCKER_HUB_USERNAME ]; then
echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin;
export cli_version=$(\mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\[');
export build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ");
docker build --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-online --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_GENERATOR_IMAGE_NAME ./modules/openapi-generator-online;
if [ ! -z "$TRAVIS_TAG" ]; then
docker tag $DOCKER_GENERATOR_IMAGE_NAME:latest $DOCKER_GENERATOR_IMAGE_NAME:$TRAVIS_TAG;
fi;
if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then
docker push $DOCKER_GENERATOR_IMAGE_NAME && echo "Pushed to $DOCKER_GENERATOR_IMAGE_NAME";
fi;
fi;
## docker: build cli image and push to Docker Hub
- if [ $DOCKER_HUB_USERNAME ]; then echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin && cp docker-entrypoint.sh ./modules/openapi-generator-cli && docker build -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli && if [ ! -z "$TRAVIS_TAG" ]; then docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG; fi && if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME && echo "Pushed to $DOCKER_CODEGEN_CLI_IMAGE_NAME"; fi; fi
- if [ $DOCKER_HUB_USERNAME ]; then
echo "$DOCKER_HUB_PASSWORD" | docker login --username=$DOCKER_HUB_USERNAME --password-stdin;
cp docker-entrypoint.sh ./modules/openapi-generator-cli;
export cli_version=$(\mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\[');
export build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ");
docker build --label=org.opencontainers.image.created=$build_date --label=org.opencontainers.image.title=openapi-generator-cli --label=org.opencontainers.image.revision=$TRAVIS_COMMIT --label=org.opencontainers.image.version=$cli_version -t $DOCKER_CODEGEN_CLI_IMAGE_NAME ./modules/openapi-generator-cli;
if [ ! -z "$TRAVIS_TAG" ]; then
docker tag $DOCKER_CODEGEN_CLI_IMAGE_NAME:latest $DOCKER_CODEGEN_CLI_IMAGE_NAME:$TRAVIS_TAG;
fi;
if [ ! -z "$TRAVIS_TAG" ] || [ "$TRAVIS_BRANCH" = "master" ]; then
docker push $DOCKER_CODEGEN_CLI_IMAGE_NAME;
echo "Pushed to $DOCKER_CODEGEN_CLI_IMAGE_NAME";
fi;
fi;
## publish latest website, variables below are secure environment variables which are unavailable to PRs from forks.
- if [ "$TRAVIS_BRANCH" = "master" ] && [ -z $TRAVIS_TAG ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
cd website;
Expand Down
16 changes: 16 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ The most commonly used openapi-generator-cli commands are:

See 'openapi-generator-cli help <command>' for more information on a specific
command.
```

## version

The version command provides version information, returning either the semver version by default or the git sha when passed `--sha`.

```bash
NAME
openapi-generator-cli version - Show version information

SYNOPSIS
openapi-generator-cli version [--sha]

OPTIONS
--sha
Git commit SHA version

```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.openapitools.codegen;

public class Constants {
private Constants(){ }

public static final String CLI_NAME = "openapi-generator-cli";
public static final String GIT_REPO = "https://github.com/openapitools/openapi-generator";
public static final String SITE = "https://openapi-generator.tech/";
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,38 @@
package org.openapitools.codegen;

import io.airlift.airline.Cli;
import io.airlift.airline.Help;
import io.airlift.airline.ParseArgumentsUnexpectedException;
import io.airlift.airline.ParseOptionMissingException;
import io.airlift.airline.ParseOptionMissingValueException;
import org.openapitools.codegen.cmd.*;

import java.util.Locale;

import static org.openapitools.codegen.Constants.CLI_NAME;

/**
* User: lanwen Date: 24.03.15 Time: 17:56
* <p>
* Command line interface for OpenAPI Generator use `openapi-generator-cli.jar help` for more info
*
* @since 2.1.3-M1
*/
public class OpenAPIGenerator {

public static void main(String[] args) {
String version = Version.readVersionFromResources();
Cli.CliBuilder<Runnable> builder =
Cli.<Runnable>builder("openapi-generator-cli")
BuildInfo buildInfo = new BuildInfo();
Cli.CliBuilder<OpenApiGeneratorCommand> builder =
Cli.<OpenApiGeneratorCommand>builder(CLI_NAME)
.withDescription(
String.format(
Locale.ROOT,
"OpenAPI generator CLI (version %s).",
version))
.withDefaultCommand(ListGenerators.class)
"OpenAPI Generator CLI %s (%s).",
buildInfo.getVersion(),
buildInfo.getSha()))
.withDefaultCommand(HelpCommand.class)
.withCommands(
ListGenerators.class,
Generate.class,
Meta.class,
Help.class,
HelpCommand.class,
ConfigHelp.class,
Validate.class,
Version.class,
Expand All @@ -60,7 +60,7 @@ public static void main(String[] args) {
try {
builder.build().parse(args).run();

// If CLI is run without a command, consider this an error. This exists after initial parse/run
// If CLI runs without a command, consider this an error. This exists after initial parse/run
// so we can present the configured "default command".
// We can check against empty args because unrecognized arguments/commands result in an exception.
// This is useful to exit with status 1, for example, so that misconfigured scripts fail fast.
Expand All @@ -71,10 +71,10 @@ public static void main(String[] args) {
System.exit(1);
}
} catch (ParseArgumentsUnexpectedException e) {
System.err.printf(Locale.ROOT,"[error] %s%n%nSee 'openapi-generator help' for usage.%n", e.getMessage());
System.err.printf(Locale.ROOT, "[error] %s%n%nSee '%s help' for usage.%n", e.getMessage(), CLI_NAME);
System.exit(1);
} catch (ParseOptionMissingException | ParseOptionMissingValueException e) {
System.err.printf(Locale.ROOT,"[error] %s%n", e.getMessage());
System.err.printf(Locale.ROOT, "[error] %s%n", e.getMessage());
System.exit(1);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.openapitools.codegen.cmd;

import java.io.IOException;
import java.io.InputStream;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import java.util.Properties;

import static org.openapitools.codegen.Constants.*;

/**
* Presents build-time information
*/
@SuppressWarnings({"java:S108"})
public class BuildInfo {
private static final String VERSION_PLACEHOLDER = "${project.version}";
private static final String UNSET = "unset";
private static final String UNKNOWN = "unknown";

private static final Properties properties = new Properties();

static {
try (InputStream is = BuildInfo.class.getResourceAsStream("/version.properties")) {
Properties versionProps = new Properties();
versionProps.load(is);
properties.putAll(versionProps);
} catch (IOException ignored) {
}
try (InputStream is = BuildInfo.class.getResourceAsStream("/openapi-generator-git.properties")) {
Properties gitProps = new Properties();
gitProps.load(is);
properties.putAll(gitProps);
} catch (IOException ignored) {
}
}

/**
* Gets the version of the toolset.
*
* @return A semver string
*/
public String getVersion() {
String version = (String) properties.getOrDefault("version", UNKNOWN);
if (VERSION_PLACEHOLDER.equals(version)) {
return UNSET;
} else {
return version;
}
}

/**
* Gets the git commit SHA1 hash. Useful for differentiating between SNAPSHOT builds.
*
* @return A short git SHA
*/
public String getSha() {
return (String) properties.getOrDefault("git.commit.id.abbrev", UNKNOWN);
}

/**
* Gets the time when this tool was built.
*
* @return The time as {@link OffsetDateTime}, or {@link OffsetDateTime#MIN} if metadata cannot be parsed.
*/
public OffsetDateTime getBuildTime() {
try {
String time = (String) properties.getOrDefault("git.build.time", "");
return OffsetDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ROOT));
} catch (DateTimeParseException e) {
return OffsetDateTime.MIN;
}
}

/**
* Gets the full version display text, as one would expect from a '--version' CLI option
*
* @return Human-readable version display information
*/
public String versionDisplayText() {
StringBuilder sb = new StringBuilder(CLI_NAME);
sb.append(" ").append(this.getVersion()).append(System.lineSeparator());
sb.append(" commit : ").append(this.getSha()).append(System.lineSeparator());
sb.append(" built : ").append(this.getBuildTime().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)).append(System.lineSeparator());
sb.append(" source : ").append(GIT_REPO).append(System.lineSeparator());
sb.append(" docs : ").append(SITE).append(System.lineSeparator());
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@
import static com.google.common.collect.Lists.newArrayList;
import static io.airlift.airline.ParserUtil.createInstance;

@SuppressWarnings({"java:S106"})
@Command(name = "completion", description = "Complete commands (for using in tooling such as Bash Completions).", hidden = true)
public class CompletionCommand
public class CompletionCommand extends OpenApiGeneratorCommand
implements Runnable, Callable<Void> {
private static final Map<Context, Class<? extends Suggester>> BUILTIN_SUGGESTERS = ImmutableMap.<Context, Class<? extends Suggester>>builder()
.put(Context.GLOBAL, GlobalSuggester.class)
Expand Down Expand Up @@ -95,7 +96,7 @@ public Iterable<String> generateSuggestions() {
}

@Override
public void run() {
void execute() {
System.out.println(Joiner.on("\n").join(generateSuggestions()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
import static org.apache.commons.lang3.StringUtils.isEmpty;

@SuppressWarnings("unused")
@SuppressWarnings({"unused","java:S106"})
@Command(name = "config-help", description = "Config help for chosen lang")
public class ConfigHelp implements Runnable {
public class ConfigHelp extends OpenApiGeneratorCommand {

private static final Logger LOGGER = LoggerFactory.getLogger(Generate.class);

Expand Down Expand Up @@ -91,7 +91,7 @@ public class ConfigHelp implements Runnable {
private String newline = System.lineSeparator();

@Override
public void run() {
public void execute() {
if (isEmpty(generatorName)) {
LOGGER.error("[error] A generator name (--generator-name / -g) is required.");
System.exit(1);
Expand Down Expand Up @@ -320,6 +320,7 @@ private void generateYamlSample(StringBuilder sb, CodegenConfig config) {
}
}

@SuppressWarnings({"java:S1117"})
private void generatePlainTextHelp(StringBuilder sb, CodegenConfig config) {
sb.append(newline).append("CONFIG OPTIONS");
if (Boolean.TRUE.equals(namedHeader)) {
Expand Down Expand Up @@ -418,6 +419,7 @@ private void generatePlainTextHelp(StringBuilder sb, CodegenConfig config) {
}
}

@SuppressWarnings({"java:S1117"})
private void writePlainTextFromMap(
StringBuilder sb,
Map<String, String> map,
Expand Down Expand Up @@ -449,6 +451,7 @@ private void writePlainTextFromMap(
}
}

@SuppressWarnings({"java:S1117"})
private void writePlainTextFromArray(StringBuilder sb, String[] arr, String optIndent) {
if (arr.length > 0) {
// target a width of 20, then take the max up to 40.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"java:S106"})
@Command(name = "generate", description = "Generate code with the specified generator.")
public class Generate implements Runnable {
public class Generate extends OpenApiGeneratorCommand {

CodegenConfigurator configurator;
Generator generator;
Expand Down Expand Up @@ -244,7 +245,7 @@ public class Generate implements Runnable {
private Boolean minimalUpdate;

@Override
public void run() {
public void execute() {
if (logToStderr != null) {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
Stream.of(Logger.ROOT_LOGGER_NAME, "io.swagger", "org.openapitools")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"})
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection", "java:S106"})
@Command(name = "batch", description = "Generate code in batch via external configs.", hidden = true)
public class GenerateBatch implements Runnable {
public class GenerateBatch extends OpenApiGeneratorCommand {

private static final Logger LOGGER = LoggerFactory.getLogger(GenerateBatch.class);

Expand Down Expand Up @@ -89,7 +89,7 @@ public class GenerateBatch implements Runnable {
* @see Thread#run()
*/
@Override
public void run() {
public void execute() {
if (configs.size() < 1) {
LOGGER.error("No configuration file inputs specified");
System.exit(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.openapitools.codegen.cmd;

import io.airlift.airline.Option;

import static io.airlift.airline.OptionType.GLOBAL;

public class GlobalOptions {
@Option(type = GLOBAL, name = "--version", description = "Display full version output", hidden = true)
public boolean version;

@Option(type = GLOBAL, name = "--help", description = "Display help about the tool", hidden = true)
public boolean help;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.openapitools.codegen.cmd;

import io.airlift.airline.Command;
import io.airlift.airline.Help;

import javax.inject.Inject;

@Command(name = "help", description = "Display help information about openapi-generator")
public class HelpCommand extends OpenApiGeneratorCommand {

@Inject
public Help help;

@Override
public void execute() {
help.call();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
import java.util.stream.Collectors;

// NOTE: List can later have subcommands such as list languages, list types, list frameworks, etc.
@SuppressWarnings({"java:S106"})
@Command(name = "list", description = "Lists the available generators")
public class ListGenerators implements Runnable {
public class ListGenerators extends OpenApiGeneratorCommand {

@Option(name = {"-s", "--short" }, description = "shortened output (suitable for scripting)")
private Boolean shortened = false;
Expand All @@ -34,7 +35,7 @@ public class ListGenerators implements Runnable {
private String include = "stable,beta,experimental";

@Override
public void run() {
public void execute() {
List<CodegenConfig> generators = new ArrayList<>();
List<Stability> stabilities = Arrays.asList(Stability.values());

Expand Down
Loading