Skip to content

Commit 91c816e

Browse files
committed
feat: add quiet mode to suppress verbose generation output (#11211)
Implement a `--quiet` / `-q` flag to suppress donation banners and contributor messages during code generation. This addresses issue #11211 by providing users a way to reduce noisy console output while maintaining full generation semantics. Changes: - Add quiet mode configuration to WorkflowSettings (core module) - Wire quiet setting through CodegenConfigurator - Implement CLI option: `-q`, `--quiet` in Generate command - Add Maven plugin parameter: `<quiet>true</quiet>` - Add Gradle extension property: `openApiGenerator.quiet = true` - Refactor postProcess() in DefaultCodegen and 19 language generators to wrap println statements with `if (!isQuietMode())` guard, ensuring all other lifecycle activities execute normally regardless of quiet mode - Add GlobalSettings lookup utility `isQuietMode()` to language-specific codegen - Update documentation for usage.md, Maven plugin README, Gradle plugin README - Add comprehensive test coverage across all modules: * WorkflowSettingsTest: quiet setting serialization * GenerateTest: CLI quiet flag parsing * DefaultGeneratorTest: postProcess execution verification * GenerateTaskDslTest: Gradle quiet output suppression * CodeGenMojoTest: Maven plugin quiet behavior Verification: - DefaultGeneratorTest: 24 tests, 0 failures - GenerateTaskDslTest: all tests pass - Build: EXIT 0 This implementation maintains backward compatibility (quiet defaults to false) and ensures semantic correctness by always invoking postProcess(), affecting only the console output suppression behavior. Closes #11211
1 parent 100bf01 commit 91c816e

36 files changed

Lines changed: 408 additions & 174 deletions

File tree

docs/usage.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,8 @@ SYNOPSIS
312312
[--model-name-suffix <model name suffix>]
313313
[--model-package <model package>]
314314
[(-o <output directory> | --output <output directory>)] [(-p <additional properties> | --additional-properties <additional properties>)...]
315-
[--package-name <package name>] [--release-note <release note>]
316-
[--remove-operation-id-prefix]
315+
[--package-name <package name>] [(-q | --quiet)]
316+
[--release-note <release note>] [--remove-operation-id-prefix]
317317
[--reserved-words-mappings <reserved word mappings>...]
318318
[(-s | --skip-overwrite)] [--server-variables <server variables>...]
319319
[--skip-operation-example] [--skip-validate-spec]
@@ -464,6 +464,9 @@ OPTIONS
464464
--package-name <package name>
465465
package for generated classes (where supported)
466466
467+
-q, --quiet
468+
quiet mode
469+
467470
--release-note <release note>
468471
Release note, default to 'Minor update'.
469472

modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public class Generate extends OpenApiGeneratorCommand {
4646
@Option(name = {"-v", "--verbose"}, description = "verbose mode")
4747
private Boolean verbose;
4848

49+
@Option(name = {"-q", "--quiet"}, description = "quiet mode")
50+
private Boolean quiet;
51+
4952
@Option(name = {"-g", "--generator-name"}, title = "generator name",
5053
description = "generator to use (see list command for list)")
5154
private String generatorName;
@@ -376,6 +379,10 @@ public void execute() {
376379
configurator.setVerbose(verbose);
377380
}
378381

382+
if (quiet != null) {
383+
configurator.setQuiet(quiet);
384+
}
385+
379386
if (skipOverwrite != null) {
380387
configurator.setSkipOverwrite(skipOverwrite);
381388
}

modules/openapi-generator-cli/src/test/java/org/openapitools/codegen/cmd/GenerateTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,24 @@ public void testVerboseShort() {
432432
verifyNoMoreInteractions(configurator);
433433
}
434434

435+
@Test
436+
public void testQuietLong() {
437+
setupAndRunGenericTest("--quiet");
438+
verify(configurator).setQuiet(true);
439+
verify(configurator).toClientOptInput();
440+
verify(configurator).toContext();
441+
verifyNoMoreInteractions(configurator);
442+
}
443+
444+
@Test
445+
public void testQuietShort() {
446+
setupAndRunGenericTest("-q");
447+
verify(configurator).setQuiet(true);
448+
verify(configurator).toClientOptInput();
449+
verify(configurator).toContext();
450+
verifyNoMoreInteractions(configurator);
451+
}
452+
435453
/**
436454
* This test ensures that when the
437455
*/

modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/WorkflowSettings.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class WorkflowSettings {
4444
public static final boolean DEFAULT_VALIDATE_SPEC = true;
4545
public static final boolean DEFAULT_ENABLE_POST_PROCESS_FILE = false;
4646
public static final boolean DEFAULT_ENABLE_MINIMAL_UPDATE = false;
47+
public static final boolean DEFAULT_QUIET = false;
4748
public static final boolean DEFAULT_STRICT_SPEC_BEHAVIOR = true;
4849
public static final boolean DEFAULT_GENERATE_ALIAS_AS_MODEL = false;
4950
public static final String DEFAULT_TEMPLATING_ENGINE_NAME = null; // this is set by the generator
@@ -59,6 +60,7 @@ public class WorkflowSettings {
5960
private boolean validateSpec = DEFAULT_VALIDATE_SPEC;
6061
private boolean enablePostProcessFile = DEFAULT_ENABLE_POST_PROCESS_FILE;
6162
private boolean enableMinimalUpdate = DEFAULT_ENABLE_MINIMAL_UPDATE;
63+
private boolean quiet = DEFAULT_QUIET;
6264
private boolean strictSpecBehavior = DEFAULT_STRICT_SPEC_BEHAVIOR;
6365
private boolean generateAliasAsModel = DEFAULT_GENERATE_ALIAS_AS_MODEL;
6466
private String templateDir;
@@ -77,6 +79,7 @@ private WorkflowSettings(Builder builder) {
7779
this.validateSpec = builder.validateSpec;
7880
this.enablePostProcessFile = builder.enablePostProcessFile;
7981
this.enableMinimalUpdate = builder.enableMinimalUpdate;
82+
this.quiet = builder.quiet;
8083
this.strictSpecBehavior = builder.strictSpecBehavior;
8184
this.templateDir = builder.templateDir;
8285
this.templatingEngineName = builder.templatingEngineName;
@@ -109,6 +112,7 @@ public static Builder newBuilder(WorkflowSettings copy) {
109112
builder.validateSpec = copy.isValidateSpec();
110113
builder.enablePostProcessFile = copy.isEnablePostProcessFile();
111114
builder.enableMinimalUpdate = copy.isEnableMinimalUpdate();
115+
builder.quiet = copy.isQuiet();
112116
builder.generateAliasAsModel = copy.isGenerateAliasAsModel();
113117
builder.strictSpecBehavior = copy.isStrictSpecBehavior();
114118
builder.templatingEngineName = copy.getTemplatingEngineName();
@@ -227,6 +231,15 @@ public boolean isEnableMinimalUpdate() {
227231
return enableMinimalUpdate;
228232
}
229233

234+
/**
235+
* Indicates whether or not generation should run in quiet mode.
236+
*
237+
* @return <code>true</code> if quiet mode is enabled, otherwise <code>false</code>.
238+
*/
239+
public boolean isQuiet() {
240+
return quiet;
241+
}
242+
230243
/**
231244
* Indicates whether or not the generation should convert aliases (primitives defined as schema for use within documents) as models.
232245
*
@@ -307,6 +320,7 @@ public static final class Builder {
307320
private Boolean validateSpec = DEFAULT_VALIDATE_SPEC;
308321
private Boolean enablePostProcessFile = DEFAULT_ENABLE_POST_PROCESS_FILE;
309322
private Boolean enableMinimalUpdate = DEFAULT_ENABLE_MINIMAL_UPDATE;
323+
private Boolean quiet = DEFAULT_QUIET;
310324
private Boolean strictSpecBehavior = DEFAULT_STRICT_SPEC_BEHAVIOR;
311325
private Boolean generateAliasAsModel = DEFAULT_GENERATE_ALIAS_AS_MODEL;
312326
private String templateDir;
@@ -436,6 +450,17 @@ public Builder withEnableMinimalUpdate(Boolean enableMinimalUpdate) {
436450
return this;
437451
}
438452

453+
/**
454+
* Sets the {@code quiet} and returns a reference to this Builder so that the methods can be chained together.
455+
*
456+
* @param quiet the {@code quiet} to set
457+
* @return a reference to this Builder
458+
*/
459+
public Builder withQuiet(Boolean quiet) {
460+
this.quiet = quiet != null ? quiet : Boolean.valueOf(DEFAULT_QUIET);
461+
return this;
462+
}
463+
439464
/**
440465
* Sets the {@code strictSpecBehavior} and returns a reference to this Builder so that the methods can be chained together.
441466
*
@@ -580,6 +605,7 @@ public String toString() {
580605
", validateSpec=" + validateSpec +
581606
", enablePostProcessFile=" + enablePostProcessFile +
582607
", enableMinimalUpdate=" + enableMinimalUpdate +
608+
", quiet=" + quiet +
583609
", strictSpecBehavior=" + strictSpecBehavior +
584610
", templateDir='" + templateDir + '\'' +
585611
", templatingEngineName='" + templatingEngineName + '\'' +
@@ -602,6 +628,7 @@ public boolean equals(Object o) {
602628
isValidateSpec() == that.isValidateSpec() &&
603629
isEnablePostProcessFile() == that.isEnablePostProcessFile() &&
604630
isEnableMinimalUpdate() == that.isEnableMinimalUpdate() &&
631+
isQuiet() == that.isQuiet() &&
605632
isStrictSpecBehavior() == that.isStrictSpecBehavior() &&
606633
isGenerateAliasAsModel() == that.isGenerateAliasAsModel() &&
607634
Objects.equals(getInputSpec(), that.getInputSpec()) &&
@@ -626,6 +653,7 @@ public int hashCode() {
626653
isGenerateAliasAsModel(),
627654
isEnablePostProcessFile(),
628655
isEnableMinimalUpdate(),
656+
isQuiet(),
629657
isStrictSpecBehavior(),
630658
getTemplateDir(),
631659
getTemplatingEngineName(),

modules/openapi-generator-core/src/test/java/org/openapitools/codegen/config/WorkflowSettingsTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public void defaultValuesNotOverriddenByNulls() {
3535
.withValidateSpec(null)
3636
.withEnablePostProcessFile(null)
3737
.withEnableMinimalUpdate(null)
38+
.withQuiet(null)
3839
.withStrictSpecBehavior(null)
3940
.build();
4041

@@ -46,6 +47,7 @@ public void defaultValuesNotOverriddenByNulls() {
4647
assertTrue(settings.isValidateSpec());
4748
assertFalse(settings.isEnablePostProcessFile());
4849
assertFalse(settings.isEnableMinimalUpdate());
50+
assertFalse(settings.isQuiet());
4951
assertTrue(settings.isStrictSpecBehavior());
5052
}
5153

@@ -78,6 +80,7 @@ private void assertOnChangesToDefaults(WorkflowSettings defaultSettings) {
7880
.withValidateSpec(false)
7981
.withEnablePostProcessFile(true)
8082
.withEnableMinimalUpdate(true)
83+
.withQuiet(true)
8184
.withStrictSpecBehavior(false)
8285
.build();
8386

@@ -105,6 +108,9 @@ private void assertOnChangesToDefaults(WorkflowSettings defaultSettings) {
105108
assertNotEquals(defaultSettings.isEnableMinimalUpdate(), newSettings.isEnableMinimalUpdate());
106109
assertTrue(newSettings.isEnableMinimalUpdate());
107110

111+
assertNotEquals(defaultSettings.isQuiet(), newSettings.isQuiet());
112+
assertTrue(newSettings.isQuiet());
113+
108114
assertNotEquals(defaultSettings.isStrictSpecBehavior(), newSettings.isStrictSpecBehavior());
109115
assertFalse(newSettings.isStrictSpecBehavior());
110116
}

modules/openapi-generator-gradle-plugin/README.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,10 @@ apply plugin: 'org.openapi.generator'
405405
|false
406406
|To write all log messages (not just errors) to STDOUT
407407

408+
|quiet
409+
|Boolean / Provider<Boolean>
410+
|false
411+
|Whether generation should run in quiet mode.
408412
|enablePostProcessFile
409413
|Boolean / Provider<Boolean>
410414
|false

modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/OpenApiGeneratorPlugin.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
9595
"Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
9696

9797
verbose.set(generate.verbose)
98+
quiet.set(generate.quiet)
9899
validateSpec.set(generate.validateSpec)
99100
generatorName.set(generate.generatorName)
100101
outputDir.set(generate.outputDir)

modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ open class OpenApiGeneratorGenerateExtension(private val project: Project) {
3636
*/
3737
val verbose = project.objects.property<Boolean>()
3838

39+
/**
40+
* Whether generation should run in quiet mode.
41+
*/
42+
val quiet = project.objects.property<Boolean>()
43+
3944
/**
4045
* Whether an input specification should be validated upon generation.
4146
*/
@@ -448,6 +453,7 @@ open class OpenApiGeneratorGenerateExtension(private val project: Project) {
448453
generateApiDocumentation.convention(true)
449454
configOptions.convention(mapOf())
450455
validateSpec.convention(true)
456+
quiet.convention(false)
451457
logToStderr.convention(false)
452458
enablePostProcessFile.convention(false)
453459
skipValidateSpec.convention(false)

modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ interface OpenApiWorkParameters : WorkParameters {
5050
val outputDir: DirectoryProperty
5151
val configFile: RegularFileProperty
5252
val verbose: Property<Boolean>
53+
val quiet: Property<Boolean>
5354
val validateSpec: Property<Boolean>
5455
val generatorName: Property<String>
5556
val auth: Property<String>
@@ -159,6 +160,7 @@ abstract class OpenApiWorkAction : WorkAction<OpenApiWorkParameters> {
159160
params.resolvedInputSpec.orNull?.let { configurator.setInputSpec(it) }
160161
params.outputDir.orNull?.let { configurator.setOutputDir(it.asFile.absolutePath) }
161162
params.verbose.orNull?.let { configurator.setVerbose(it) }
163+
params.quiet.orNull?.let { configurator.setQuiet(it) }
162164
params.validateSpec.orNull?.let { configurator.setValidateSpec(it) }
163165
params.skipOverwrite.orNull?.let { configurator.setSkipOverwrite(it) }
164166
params.generatorName.orNull?.let { configurator.setGeneratorName(it) }
@@ -316,6 +318,13 @@ abstract class GenerateTask : DefaultTask() {
316318
@get:Input
317319
abstract val verbose: Property<Boolean>
318320

321+
/**
322+
* Whether generation should run in quiet mode.
323+
*/
324+
@get:Optional
325+
@get:Input
326+
abstract val quiet: Property<Boolean>
327+
319328
/**
320329
* Whether an input specification should be validated upon generation.
321330
*/
@@ -928,6 +937,7 @@ abstract class GenerateTask : DefaultTask() {
928937
parameters.outputDir.set(outputDir)
929938
parameters.configFile.set(configFile)
930939
parameters.verbose.set(verbose)
940+
parameters.quiet.set(quiet)
931941
parameters.validateSpec.set(validateSpec)
932942
parameters.generatorName.set(generatorName)
933943
parameters.auth.set(auth)

modules/openapi-generator-gradle-plugin/src/test/kotlin/GenerateTaskDslTest.kt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,49 @@ class GenerateTaskDslTest : TestBase() {
244244
)
245245
}
246246

247+
@Test(dataProvider = "property_format_provider")
248+
fun `openApiGenerate should suppress promo banner in quiet mode`(format: String) {
249+
val propertyFormat = PropertyFormat.valueOf(format)
250+
val projectFiles = mapOf(
251+
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
252+
)
253+
withProject(
254+
"""
255+
plugins {
256+
id 'org.openapi.generator'
257+
}
258+
openApiGenerate {
259+
generatorName = "kotlin"
260+
inputSpec = ${"spec.yaml".toPropertyReference(propertyFormat)}
261+
outputDir = ${"build/kotlin".toPropertyReference(propertyFormat)}
262+
apiPackage = "org.openapitools.example.api"
263+
invokerPackage = "org.openapitools.example.invoker"
264+
modelPackage = "org.openapitools.example.model"
265+
quiet = true
266+
configOptions = [
267+
dateLibrary: "java8"
268+
]
269+
}
270+
""".trimIndent(),
271+
projectFiles
272+
)
273+
274+
val result = GradleRunner.create()
275+
.withProjectDir(temp)
276+
.withArguments("openApiGenerate")
277+
.withPluginClasspath()
278+
.build()
279+
280+
assertFalse(
281+
result.output.contains("# Thanks for using OpenAPI Generator."),
282+
"Promo banner is shown even when quiet mode is enabled."
283+
)
284+
assertEquals(
285+
TaskOutcome.SUCCESS, result.task(":openApiGenerate")?.outcome,
286+
"Expected a successful run, but found ${result.task(":openApiGenerate")?.outcome}"
287+
)
288+
}
289+
247290
@Test(dataProvider = "property_format_provider")
248291
fun `openApiGenerate should cleanup outputDir`(format: String) {
249292
val propertyFormat = PropertyFormat.valueOf(format)

0 commit comments

Comments
 (0)