2017-05-29 12:38:15 -04:00
#!/usr/bin/env bash
set -euo pipefail
2018-01-27 04:43:46 -05:00
set -o noclobber
2017-05-29 12:38:15 -04:00
usage( ) {
2018-01-27 04:43:46 -05:00
cat <<EOF
Stubs out files for new generators
Usage:
$0 [options]
Options:
2020-09-03 22:04:43 +08:00
$(grep "[[:space:]].)\ #" $0 | tr -d "#" | sed -E 's/( \| \*)//' | sed -E 's/([a-zA-Z])\)/-\1/')
2018-01-27 04:43:46 -05:00
Examples:
Create a server generator for ktor:
$0 -n kotlin -s
Creates:
2018-05-09 12:21:13 +02:00
modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java
2019-01-18 04:39:33 -05:00
modules/openapi-generator/src/main/resources/kotlin-server/README.mustache
2018-05-09 12:21:13 +02:00
modules/openapi-generator/src/main/resources/kotlin-server/model.mustache
modules/openapi-generator/src/main/resources/kotlin-server/api.mustache
2020-09-03 22:04:43 +08:00
bin/configs/kotlin-server-petstore-new.yaml
2018-01-27 04:43:46 -05:00
Create a generic C# server generator:
$0 -n csharp -s -t
Creates:
2018-05-09 12:21:13 +02:00
modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CsharpServerCodegen.java
2019-01-18 04:39:33 -05:00
modules/openapi-generator/src/main/resources/csharp-server/README.mustache
2018-05-09 12:21:13 +02:00
modules/openapi-generator/src/main/resources/csharp-server/model.mustache
modules/openapi-generator/src/main/resources/csharp-server/api.mustache
2020-09-03 22:04:43 +08:00
bin/configs/csharp-server-petstore-new.yaml
2018-05-09 12:21:13 +02:00
modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CsharpServerCodegenTest.java
modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CsharpServerCodegenModelTest.java
modules/openapi-generator/src/test/java/org/openapitools/codegen/csharp/CsharpServerCodegenOptionsTest.java
modules/openapi-generator/src/test/java/org/openapitools/codegen/options/CsharpServerCodegenOptionsProvider.java
2018-01-27 04:43:46 -05:00
EOF
2017-05-29 12:38:15 -04:00
exit 0;
}
2018-01-27 04:43:46 -05:00
declare os = ${ OSTYPE //[0-9.]/ }
declare root = $( cd $( dirname " ${ BASH_SOURCE } " ) && pwd )
declare gen_type =
declare tests = 0
declare gen_name
checkPreviousGenType( ) {
if [ "a" != " a $gen_type " ] ; then
echo "[error] You may only set a single generator type at a time!" >& 2
usage >& 2
exit 1
fi
}
2017-05-29 12:38:15 -04:00
[ $# -eq 0 ] && usage
2020-09-03 22:04:43 +08:00
while getopts ":hcsdtfHn:" arg; do
2017-05-29 12:38:15 -04:00
case ${ arg } in
2018-01-27 04:43:46 -05:00
n) # Required. Specify generator name, should be kebab-cased.
2017-05-29 12:38:15 -04:00
gen_name = ${ OPTARG }
; ;
c) # Create a client generator
2018-01-27 04:43:46 -05:00
checkPreviousGenType
2017-05-29 12:38:15 -04:00
gen_type = client
; ;
s) # Create a server generator
2018-01-27 04:43:46 -05:00
checkPreviousGenType
2017-05-29 12:38:15 -04:00
gen_type = server
; ;
d) # Create a documentation generator
2018-01-27 04:43:46 -05:00
checkPreviousGenType
2017-05-29 12:38:15 -04:00
gen_type = documentation
; ;
2020-09-03 22:04:43 +08:00
H) # Create a schema generator
2019-01-18 04:39:33 -05:00
checkPreviousGenType
gen_type = schema
; ;
f) # Create a config generator
checkPreviousGenType
gen_type = config
; ;
2017-05-29 12:38:15 -04:00
t) # When specified, creates test file(s) for the generator.
tests = 1
; ;
h | *) # Display help.
usage
exit 0
; ;
esac
done
2019-04-06 04:01:06 +02:00
if [ -z " $gen_type " ] ; then
echo "[error] You may set a generator type" >& 2
usage >& 2
exit 1
fi
2017-05-29 12:38:15 -04:00
[ -z " ${ gen_name } " ] && usage
2018-01-27 04:43:46 -05:00
titleCase( ) {
if [ " $os " = = "darwin" ] ; then
echo $1 | tr '-' ' ' | tr '_' ' ' | ruby -e "print STDIN.gets.split.map(&:capitalize).join(' ')" | tr -d ' '
else
read -ra words <<< $( echo $1 | tr '-' ' ' | tr '_' ' ' )
echo " ${ words [@]^ } " | tr -d ' '
fi
}
kebabCase( ) {
2019-04-06 04:01:06 +02:00
echo $1 | tr '_' ' ' | tr ' ' '-' | tr '[:upper:]' '[:lower:]'
}
kebabCasePath( ) {
echo $1 | tr '_' ' ' | tr ' ' '-' | tr '-' '/' | tr '[:upper:]' '[:lower:]'
}
kebabCasePathWin( ) {
echo $1 | tr '_' ' ' | tr ' ' '-' | tr '-' '\\' | tr '[:upper:]' '[:lower:]'
}
kebabCasePkg( ) {
echo $1 | tr '_' ' ' | tr ' ' '-' | tr '-' '.' | tr '[:upper:]' '[:lower:]'
2018-01-27 04:43:46 -05:00
}
upperCase( ) {
echo $1 | tr '[[:lower:]]' '[[:upper:]]'
}
declare lang_classname = $( titleCase " ${ gen_name } - ${ gen_type } -Codegen " )
declare gen_name_camel = $( kebabCase " ${ gen_name } " )
2019-04-06 04:01:06 +02:00
declare gen_name_camel_path = $( kebabCasePath " ${ gen_name } " )
declare gen_name_camel_pathwin = $( kebabCasePathWin " ${ gen_name } " )
declare gen_name_camel_pkg = $( kebabCasePkg " ${ gen_name } " )
2018-01-27 04:43:46 -05:00
declare codegen_type_enum = $( upperCase " ${ gen_type } " )
2017-05-29 12:38:15 -04:00
# Step 1: Add Language Generator
2018-05-09 12:21:13 +02:00
[ -f " ${ root } /modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ ${ lang_classname } .java " ] && \
2017-05-29 12:38:15 -04:00
echo " ${ lang_classname } already exists " && exit 1;
2018-05-09 12:21:13 +02:00
echo " Creating modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ ${ lang_classname } .java "
cat > " ${ root } /modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ ${ lang_classname } .java " <<EOF
package org.openapitools.codegen.languages;
2017-05-29 12:38:15 -04:00
2018-05-09 12:21:13 +02:00
import org.openapitools.codegen.*;
2017-05-29 12:38:15 -04:00
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.MapProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.parameters.Parameter;
import java.io.File;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ${lang_classname} extends DefaultCodegen implements CodegenConfig {
public static final String PROJECT_NAME = "projectName";
2023-02-08 21:07:03 +09:00
private final Logger LOGGER = LoggerFactory.getLogger(${lang_classname}.class);
2017-05-29 12:38:15 -04:00
public CodegenType getTag() {
return CodegenType.${codegen_type_enum};
}
public String getName() {
2019-04-06 04:01:06 +02:00
return "${gen_name_camel}";
2017-05-29 12:38:15 -04:00
}
public String getHelp() {
2019-04-06 04:01:06 +02:00
return "Generates a ${gen_name_camel} ${gen_type}.";
2017-05-29 12:38:15 -04:00
}
public ${lang_classname}() {
super();
2019-04-06 04:01:06 +02:00
outputFolder = "generated-code" + File.separator + "${gen_name_camel}";
2017-05-29 12:38:15 -04:00
modelTemplateFiles.put("model.mustache", ".zz");
apiTemplateFiles.put("api.mustache", ".zz");
2021-04-29 12:23:13 +02:00
embeddedTemplateDir = templateDir = "${gen_name_camel}";
2020-09-03 22:04:43 +08:00
apiPackage = "Apis";
modelPackage = "Models";
2019-01-18 04:39:33 -05:00
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
2017-05-29 12:38:15 -04:00
// TODO: Fill this out.
}
}
EOF
# Step 2: Register the new class with service loader
2018-05-09 12:21:13 +02:00
echo -e " \norg.openapitools.codegen.languages. ${ lang_classname } " >> " ${ root } /modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig "
2017-05-29 12:38:15 -04:00
# Step 3: Create resource files
2021-04-29 12:23:13 +02:00
mkdir -p " ${ root } /modules/openapi-generator/src/main/resources/ ${ gen_name_camel } "
echo " Creating modules/openapi-generator/src/main/resources/ ${ gen_name_camel } /README.mustache " && \
touch " ${ root } /modules/openapi-generator/src/main/resources/ ${ gen_name_camel } /README.mustache "
echo " Creating modules/openapi-generator/src/main/resources/ ${ gen_name_camel } /model.mustache " && \
touch " ${ root } /modules/openapi-generator/src/main/resources/ ${ gen_name_camel } /model.mustache "
echo " Creating modules/openapi-generator/src/main/resources/ ${ gen_name_camel } /api.mustache " && \
touch " ${ root } /modules/openapi-generator/src/main/resources/ ${ gen_name_camel } /api.mustache "
2017-05-29 12:38:15 -04:00
2020-09-03 22:04:43 +08:00
# Step 4: Create generation config scripts
2021-04-29 12:23:13 +02:00
echo " Creating bin/configs/ ${ gen_name_camel } -petstore-new.yaml "
cat > " ${ root } /bin/configs/ ${ gen_name_camel } -petstore-new.yaml " <<EOF
2020-09-03 22:04:43 +08:00
generatorName: ${gen_name_camel}
outputDir: samples/${gen_type}/petstore/${gen_name_camel_path}
2020-10-14 10:13:17 +08:00
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
2020-09-03 22:04:43 +08:00
templateDir: modules/openapi-generator/src/main/resources/${gen_name_camel}
additionalProperties:
hideGenerationTimestamp: "true"
2017-05-29 12:38:15 -04:00
EOF
2018-05-09 12:21:13 +02:00
# Step 5: (optional) Create OpenAPI Generator test files
2017-05-29 12:38:15 -04:00
if [ "1" -eq " ${ tests } " ] ; then
2019-04-06 04:01:06 +02:00
mkdir -p " ${ root } /modules/openapi-generator/src/test/java/org/openapitools/codegen/ ${ gen_name_camel_path } "
2017-05-29 12:38:15 -04:00
# Codegen
2019-04-06 04:01:06 +02:00
echo " Creating modules/openapi-generator/src/test/java/org/openapitools/codegen/ ${ gen_name_camel_path } / ${ lang_classname } Test.java "
cat > " ${ root } /modules/openapi-generator/src/test/java/org/openapitools/codegen/ ${ gen_name_camel_path } / ${ lang_classname } Test.java " <<EOF
package org.openapitools.codegen.${gen_name_camel_pkg};
2017-05-29 12:38:15 -04:00
2018-05-09 12:21:13 +02:00
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.${lang_classname};
2017-05-29 12:38:15 -04:00
import io.swagger.models.*;
import io.swagger.parser.SwaggerParser;
import org.testng.Assert;
import org.testng.annotations.Test;
public class ${lang_classname}Test {
${lang_classname} codegen = new ${lang_classname}();
@Test
public void shouldSucceed() throws Exception {
// TODO: Complete this test.
Assert.fail("Not implemented.");
}
}
EOF
# Model
2019-04-06 04:01:06 +02:00
echo " Creating modules/openapi-generator/src/test/java/org/openapitools/codegen/ ${ gen_name_camel_path } / ${ lang_classname } ModelTest.java "
cat > " ${ root } /modules/openapi-generator/src/test/java/org/openapitools/codegen/ ${ gen_name_camel_path } / ${ lang_classname } ModelTest.java " <<EOF
package org.openapitools.codegen.${gen_name_camel_pkg};
2017-05-29 12:38:15 -04:00
2018-05-09 12:21:13 +02:00
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.${lang_classname};
2017-05-29 12:38:15 -04:00
import io.swagger.models.*;
import io.swagger.models.properties.*;
import org.testng.Assert;
import org.testng.annotations.Test;
@SuppressWarnings("static-method")
public class ${lang_classname}ModelTest {
@Test(description = "convert a simple java model")
public void simpleModelTest() {
final Model model = new ModelImpl()
.description("a sample model")
.property("id", new LongProperty())
.property("name", new StringProperty())
.required("id")
.required("name");
final DefaultCodegen codegen = new ${lang_classname}();
// TODO: Complete this test.
Assert.fail("Not implemented.");
}
}
EOF
# Options
2019-04-06 04:01:06 +02:00
echo " Creating modules/openapi-generator/src/test/java/org/openapitools/codegen/ ${ gen_name_camel_path } / ${ lang_classname } OptionsTest.java "
cat > " ${ root } /modules/openapi-generator/src/test/java/org/openapitools/codegen/ ${ gen_name_camel_path } / ${ lang_classname } OptionsTest.java " <<EOF
package org.openapitools.codegen.${gen_name_camel_pkg};
2017-05-29 12:38:15 -04:00
2018-05-09 12:21:13 +02:00
import org.openapitools.codegen.AbstractOptionsTest;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.languages.${lang_classname};
import org.openapitools.codegen.options.${lang_classname}OptionsProvider;
2017-05-29 12:38:15 -04:00
2020-01-22 18:04:00 -05:00
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
2017-05-29 12:38:15 -04:00
public class ${lang_classname}OptionsTest extends AbstractOptionsTest {
2020-01-22 18:04:00 -05:00
private ${lang_classname} codegen = mock(${lang_classname}.class, mockSettings);
2017-05-29 12:38:15 -04:00
public ${lang_classname}OptionsTest() {
super(new ${lang_classname}OptionsProvider());
}
@Override
protected CodegenConfig getCodegenConfig() {
return codegen;
}
@SuppressWarnings("unused")
@Override
2020-01-22 18:04:00 -05:00
protected void verifyOptions() {
// TODO: Complete options using Mockito
// verify(codegen).someMethod(arguments)
2017-05-29 12:38:15 -04:00
}
}
EOF
# Options Provider
2018-05-09 12:21:13 +02:00
echo " Creating modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ ${ lang_classname } OptionsProvider.java "
cat > " ${ root } /modules/openapi-generator/src/test/java/org/openapitools/codegen/options/ ${ lang_classname } OptionsProvider.java " <<EOF
package org.openapitools.codegen.options;
2017-05-29 12:38:15 -04:00
2018-05-09 12:21:13 +02:00
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.languages.${lang_classname};
2017-05-29 12:38:15 -04:00
import com.google.common.collect.ImmutableMap;
import java.util.Map;
public class ${lang_classname}OptionsProvider implements OptionsProvider {
2018-05-09 12:21:13 +02:00
public static final String PROJECT_NAME_VALUE = "OpenAPI";
2017-05-29 12:38:15 -04:00
@Override
public String getLanguage() {
return "${gen_name_camel}";
}
@Override
public Map<String, String> createOptions() {
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
return builder
.put(${lang_classname}.PROJECT_NAME, PROJECT_NAME_VALUE)
.build();
}
@Override
public boolean isServer() {
return false;
}
}
EOF
fi
echo "Finished."