From 26591f5d7ff1e9d4d2a785e77311d96d39ec5034 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Wed, 5 Sep 2018 08:04:27 +0800 Subject: [PATCH] Use elm-format to format Elm API client (#959) * add elm-format support * update elm petstore samples * add trenneman to elm tech comm * replace dart class with elm class * revise elm format arguments * update petstore samples --- README.md | 2 +- bin/elm-petstore-all.sh | 5 ++ .../codegen/languages/ElmClientCodegen.java | 51 +++++++++++++++++-- .../elm-0.18/.openapi-generator/VERSION | 2 +- .../elm-0.18/src/Data/ApiResponse.elm | 2 - .../petstore/elm-0.18/src/Data/Category.elm | 2 - .../petstore/elm-0.18/src/Data/Order_.elm | 28 +++++----- .../client/petstore/elm-0.18/src/Data/Pet.elm | 28 +++++----- .../client/petstore/elm-0.18/src/Data/Tag.elm | 2 - .../petstore/elm-0.18/src/Data/User.elm | 2 - .../petstore/elm-0.18/src/Request/Pet.elm | 2 +- .../petstore/elm/.openapi-generator/VERSION | 2 +- .../petstore/elm/src/Data/ApiResponse.elm | 2 - .../client/petstore/elm/src/Data/Category.elm | 2 - .../client/petstore/elm/src/Data/Order_.elm | 28 +++++----- samples/client/petstore/elm/src/Data/Pet.elm | 30 +++++------ samples/client/petstore/elm/src/Data/Tag.elm | 2 - samples/client/petstore/elm/src/Data/User.elm | 2 - .../client/petstore/elm/src/Request/Pet.elm | 2 +- 19 files changed, 105 insertions(+), 91 deletions(-) create mode 100755 bin/elm-petstore-all.sh diff --git a/README.md b/README.md index f9e48fd6fcd..2bf2f1cc0b3 100644 --- a/README.md +++ b/README.md @@ -637,7 +637,7 @@ If you want to join the committee, please kindly apply by sending an email to te | Dart | @ircecho (2017/07) @swipesight (2018/09) | | Eiffel | @jvelilla (2017/09) | | Elixir | | -| Elm | | +| Elm | @trenneman (2018/09) | | Erlang | @tsloughter (2017/11) | | Go | @antihax (2017/11) @bvwells (2017/12) @grokify (2018/07) | | Groovy | | diff --git a/bin/elm-petstore-all.sh b/bin/elm-petstore-all.sh new file mode 100755 index 00000000000..0d64cf613cf --- /dev/null +++ b/bin/elm-petstore-all.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +./bin/elm-0.18-petstore.sh +./bin/elm-petstore.sh + diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java index 42b21c5d903..a4d631ab9e2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElmClientCodegen.java @@ -34,6 +34,12 @@ import org.openapitools.codegen.DefaultCodegen; import org.openapitools.codegen.SupportingFile; import org.openapitools.codegen.utils.ModelUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.io.FilenameUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; import java.text.Collator; import java.util.ArrayList; @@ -48,21 +54,20 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; - public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig { + private static final Logger LOGGER = LoggerFactory.getLogger(ElmClientCodegen.class); + private Set customPrimitives = new HashSet(); + private ElmVersion elmVersion = ElmVersion.ELM_019; + private static final String ELM_VERSION = "elmVersion"; private static final String ENCODER = "elmEncoder"; private static final String DECODER = "elmDecoder"; private static final String X_DISCRIMINATOR_TYPE = "x-discriminator-value"; private static final String UNION_TYPE = "elmUnionType"; - private Set customPrimitives = new HashSet(); - protected String packageName = "openapi"; protected String packageVersion = "1.0.0"; - private ElmVersion elmVersion = ElmVersion.ELM_019; - public CodegenType getTag() { return CodegenType.CLIENT; } @@ -160,6 +165,10 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig { public void processOpts() { super.processOpts(); + if (StringUtils.isEmpty(System.getenv("ELM_FORMAT_PATH"))) { + LOGGER.info("Environment variable ELM_FORMAT_PATH not defined so the Elm code may not be properly formatted. To define it, try 'export ELM_FORMAT_PATH=/usr/local/bin/elm-format' (Linux/Mac)"); + } + if (additionalProperties.containsKey(ELM_VERSION)) { final String version = (String) additionalProperties.get(ELM_VERSION); if ("0.18".equals(version)) { @@ -624,4 +633,36 @@ public class ElmClientCodegen extends DefaultCodegen implements CodegenConfig { ELM_018, ELM_019 } + + @Override + public void postProcessFile(File file, String fileType) { + if (file == null) { + return; + } + + String elmFmtPath = System.getenv("ELM_FORMAT_PATH"); + if (StringUtils.isEmpty(elmFmtPath)) { + return; // skip if ELM_FORMAT_PATH env variable is not defined + } + + // only process files with elm extension + if ("elm".equals(FilenameUtils.getExtension(file.toString()))) { + // currently only support "elm-format -w yourcode.elm" + String command = elmFmtPath + " --yes " + file.toString(); + if (ElmVersion.ELM_018.equals(elmVersion)) { + command += " --elm-version=0.18"; + } + + try { + Process p = Runtime.getRuntime().exec(command); + p.waitFor(); + if (p.exitValue() != 0) { + LOGGER.error("Error running the command ({}): {}", command, p.exitValue()); + } + } catch (Exception e) { + LOGGER.error("Error running the command ({}): {}", command, e.getMessage()); + } + LOGGER.info("Successfully executed: " + command); + } + } } diff --git a/samples/client/petstore/elm-0.18/.openapi-generator/VERSION b/samples/client/petstore/elm-0.18/.openapi-generator/VERSION index c791c986fbb..6d94c9c2e12 100644 --- a/samples/client/petstore/elm-0.18/.openapi-generator/VERSION +++ b/samples/client/petstore/elm-0.18/.openapi-generator/VERSION @@ -1 +1 @@ -3.2.3-SNAPSHOT \ No newline at end of file +3.3.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/elm-0.18/src/Data/ApiResponse.elm b/samples/client/petstore/elm-0.18/src/Data/ApiResponse.elm index c7400283086..b392f467ca5 100644 --- a/samples/client/petstore/elm-0.18/src/Data/ApiResponse.elm +++ b/samples/client/petstore/elm-0.18/src/Data/ApiResponse.elm @@ -35,7 +35,6 @@ apiResponseDecoder = |> optional "message" (Decode.nullable Decode.string) Nothing - apiResponseEncoder : ApiResponse -> Encode.Value apiResponseEncoder model = Encode.object @@ -43,4 +42,3 @@ apiResponseEncoder model = , ( "type", withDefault Encode.null (map Encode.string model.type_) ) , ( "message", withDefault Encode.null (map Encode.string model.message) ) ] - diff --git a/samples/client/petstore/elm-0.18/src/Data/Category.elm b/samples/client/petstore/elm-0.18/src/Data/Category.elm index b2baddd929f..c47b3e1fa62 100644 --- a/samples/client/petstore/elm-0.18/src/Data/Category.elm +++ b/samples/client/petstore/elm-0.18/src/Data/Category.elm @@ -33,11 +33,9 @@ categoryDecoder = |> optional "name" (Decode.nullable Decode.string) Nothing - categoryEncoder : Category -> Encode.Value categoryEncoder model = Encode.object [ ( "id", withDefault Encode.null (map Encode.int model.id) ) , ( "name", withDefault Encode.null (map Encode.string model.name) ) ] - diff --git a/samples/client/petstore/elm-0.18/src/Data/Order_.elm b/samples/client/petstore/elm-0.18/src/Data/Order_.elm index 58559b874be..8703f63c8ed 100644 --- a/samples/client/petstore/elm-0.18/src/Data/Order_.elm +++ b/samples/client/petstore/elm-0.18/src/Data/Order_.elm @@ -37,7 +37,6 @@ type Status | Delivered - orderDecoder : Decoder Order_ orderDecoder = decode Order_ @@ -49,7 +48,6 @@ orderDecoder = |> optional "complete" (Decode.nullable Decode.bool) (Just False) - orderEncoder : Order_ -> Encode.Value orderEncoder model = Encode.object @@ -65,20 +63,21 @@ orderEncoder model = statusDecoder : Decoder Status statusDecoder = Decode.string - |> Decode.andThen (\str -> - case str of - "placed" -> - Decode.succeed Placed + |> Decode.andThen + (\str -> + case str of + "placed" -> + Decode.succeed Placed - "approved" -> - Decode.succeed Approved + "approved" -> + Decode.succeed Approved - "delivered" -> - Decode.succeed Delivered + "delivered" -> + Decode.succeed Delivered - other -> - Decode.fail <| "Unknown type: " ++ other - ) + other -> + Decode.fail <| "Unknown type: " ++ other + ) statusEncoder : Status -> Encode.Value @@ -92,6 +91,3 @@ statusEncoder model = Delivered -> Encode.string "delivered" - - - diff --git a/samples/client/petstore/elm-0.18/src/Data/Pet.elm b/samples/client/petstore/elm-0.18/src/Data/Pet.elm index cdb4296712e..76fb0e4d0a2 100644 --- a/samples/client/petstore/elm-0.18/src/Data/Pet.elm +++ b/samples/client/petstore/elm-0.18/src/Data/Pet.elm @@ -38,7 +38,6 @@ type Status | Sold - petDecoder : Decoder Pet petDecoder = decode Pet @@ -50,7 +49,6 @@ petDecoder = |> optional "status" (Decode.nullable statusDecoder) Nothing - petEncoder : Pet -> Encode.Value petEncoder model = Encode.object @@ -66,20 +64,21 @@ petEncoder model = statusDecoder : Decoder Status statusDecoder = Decode.string - |> Decode.andThen (\str -> - case str of - "available" -> - Decode.succeed Available + |> Decode.andThen + (\str -> + case str of + "available" -> + Decode.succeed Available - "pending" -> - Decode.succeed Pending + "pending" -> + Decode.succeed Pending - "sold" -> - Decode.succeed Sold + "sold" -> + Decode.succeed Sold - other -> - Decode.fail <| "Unknown type: " ++ other - ) + other -> + Decode.fail <| "Unknown type: " ++ other + ) statusEncoder : Status -> Encode.Value @@ -93,6 +92,3 @@ statusEncoder model = Sold -> Encode.string "sold" - - - diff --git a/samples/client/petstore/elm-0.18/src/Data/Tag.elm b/samples/client/petstore/elm-0.18/src/Data/Tag.elm index 79d0fa2da27..338eaa7ad27 100644 --- a/samples/client/petstore/elm-0.18/src/Data/Tag.elm +++ b/samples/client/petstore/elm-0.18/src/Data/Tag.elm @@ -33,11 +33,9 @@ tagDecoder = |> optional "name" (Decode.nullable Decode.string) Nothing - tagEncoder : Tag -> Encode.Value tagEncoder model = Encode.object [ ( "id", withDefault Encode.null (map Encode.int model.id) ) , ( "name", withDefault Encode.null (map Encode.string model.name) ) ] - diff --git a/samples/client/petstore/elm-0.18/src/Data/User.elm b/samples/client/petstore/elm-0.18/src/Data/User.elm index 657f6fb6600..2b873692d2d 100644 --- a/samples/client/petstore/elm-0.18/src/Data/User.elm +++ b/samples/client/petstore/elm-0.18/src/Data/User.elm @@ -45,7 +45,6 @@ userDecoder = |> optional "userStatus" (Decode.nullable Decode.int) Nothing - userEncoder : User -> Encode.Value userEncoder model = Encode.object @@ -58,4 +57,3 @@ userEncoder model = , ( "phone", withDefault Encode.null (map Encode.string model.phone) ) , ( "userStatus", withDefault Encode.null (map Encode.int model.userStatus) ) ] - diff --git a/samples/client/petstore/elm-0.18/src/Request/Pet.elm b/samples/client/petstore/elm-0.18/src/Request/Pet.elm index 0a4b5c1769e..948ab5d3c01 100644 --- a/samples/client/petstore/elm-0.18/src/Request/Pet.elm +++ b/samples/client/petstore/elm-0.18/src/Request/Pet.elm @@ -12,8 +12,8 @@ module Request.Pet exposing (addPet, deletePet, findPetsByStatus, findPetsByTags, getPetById, updatePet, updatePetWithForm, uploadFile) -import Data.Pet exposing (Pet, petDecoder, petEncoder) import Data.ApiResponse exposing (ApiResponse, apiResponseDecoder) +import Data.Pet exposing (Pet, petDecoder, petEncoder) import Dict import Http import Json.Decode as Decode diff --git a/samples/client/petstore/elm/.openapi-generator/VERSION b/samples/client/petstore/elm/.openapi-generator/VERSION index c791c986fbb..6d94c9c2e12 100644 --- a/samples/client/petstore/elm/.openapi-generator/VERSION +++ b/samples/client/petstore/elm/.openapi-generator/VERSION @@ -1 +1 @@ -3.2.3-SNAPSHOT \ No newline at end of file +3.3.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/elm/src/Data/ApiResponse.elm b/samples/client/petstore/elm/src/Data/ApiResponse.elm index a8af70b330c..9bb9480a8ae 100644 --- a/samples/client/petstore/elm/src/Data/ApiResponse.elm +++ b/samples/client/petstore/elm/src/Data/ApiResponse.elm @@ -35,7 +35,6 @@ apiResponseDecoder = |> optional "message" (Decode.nullable Decode.string) Nothing - apiResponseEncoder : ApiResponse -> Encode.Value apiResponseEncoder model = Encode.object @@ -43,4 +42,3 @@ apiResponseEncoder model = , ( "type", withDefault Encode.null (map Encode.string model.type_) ) , ( "message", withDefault Encode.null (map Encode.string model.message) ) ] - diff --git a/samples/client/petstore/elm/src/Data/Category.elm b/samples/client/petstore/elm/src/Data/Category.elm index b00828d0418..01b80800072 100644 --- a/samples/client/petstore/elm/src/Data/Category.elm +++ b/samples/client/petstore/elm/src/Data/Category.elm @@ -33,11 +33,9 @@ categoryDecoder = |> optional "name" (Decode.nullable Decode.string) Nothing - categoryEncoder : Category -> Encode.Value categoryEncoder model = Encode.object [ ( "id", withDefault Encode.null (map Encode.int model.id) ) , ( "name", withDefault Encode.null (map Encode.string model.name) ) ] - diff --git a/samples/client/petstore/elm/src/Data/Order_.elm b/samples/client/petstore/elm/src/Data/Order_.elm index f1e713ac7c9..3985c150336 100644 --- a/samples/client/petstore/elm/src/Data/Order_.elm +++ b/samples/client/petstore/elm/src/Data/Order_.elm @@ -37,7 +37,6 @@ type Status | Delivered - orderDecoder : Decoder Order_ orderDecoder = Decode.succeed Order_ @@ -49,7 +48,6 @@ orderDecoder = |> optional "complete" (Decode.nullable Decode.bool) (Just False) - orderEncoder : Order_ -> Encode.Value orderEncoder model = Encode.object @@ -65,20 +63,21 @@ orderEncoder model = statusDecoder : Decoder Status statusDecoder = Decode.string - |> Decode.andThen (\str -> - case str of - "placed" -> - Decode.succeed Placed + |> Decode.andThen + (\str -> + case str of + "placed" -> + Decode.succeed Placed - "approved" -> - Decode.succeed Approved + "approved" -> + Decode.succeed Approved - "delivered" -> - Decode.succeed Delivered + "delivered" -> + Decode.succeed Delivered - other -> - Decode.fail <| "Unknown type: " ++ other - ) + other -> + Decode.fail <| "Unknown type: " ++ other + ) statusEncoder : Status -> Encode.Value @@ -92,6 +91,3 @@ statusEncoder model = Delivered -> Encode.string "delivered" - - - diff --git a/samples/client/petstore/elm/src/Data/Pet.elm b/samples/client/petstore/elm/src/Data/Pet.elm index f37f03e085d..f0968e4c1db 100644 --- a/samples/client/petstore/elm/src/Data/Pet.elm +++ b/samples/client/petstore/elm/src/Data/Pet.elm @@ -38,7 +38,6 @@ type Status | Sold - petDecoder : Decoder Pet petDecoder = Decode.succeed Pet @@ -50,14 +49,13 @@ petDecoder = |> optional "status" (Decode.nullable statusDecoder) Nothing - petEncoder : Pet -> Encode.Value petEncoder model = Encode.object [ ( "id", withDefault Encode.null (map Encode.int model.id) ) , ( "category", withDefault Encode.null (map categoryEncoder model.category) ) , ( "name", Encode.string model.name ) - , ( "photoUrls", (Encode.list Encode.string) model.photoUrls ) + , ( "photoUrls", Encode.list Encode.string model.photoUrls ) , ( "tags", withDefault Encode.null (map (Encode.list tagEncoder) model.tags) ) , ( "status", withDefault Encode.null (map statusEncoder model.status) ) ] @@ -66,20 +64,21 @@ petEncoder model = statusDecoder : Decoder Status statusDecoder = Decode.string - |> Decode.andThen (\str -> - case str of - "available" -> - Decode.succeed Available + |> Decode.andThen + (\str -> + case str of + "available" -> + Decode.succeed Available - "pending" -> - Decode.succeed Pending + "pending" -> + Decode.succeed Pending - "sold" -> - Decode.succeed Sold + "sold" -> + Decode.succeed Sold - other -> - Decode.fail <| "Unknown type: " ++ other - ) + other -> + Decode.fail <| "Unknown type: " ++ other + ) statusEncoder : Status -> Encode.Value @@ -93,6 +92,3 @@ statusEncoder model = Sold -> Encode.string "sold" - - - diff --git a/samples/client/petstore/elm/src/Data/Tag.elm b/samples/client/petstore/elm/src/Data/Tag.elm index 7ab34e9168a..21c76a52eee 100644 --- a/samples/client/petstore/elm/src/Data/Tag.elm +++ b/samples/client/petstore/elm/src/Data/Tag.elm @@ -33,11 +33,9 @@ tagDecoder = |> optional "name" (Decode.nullable Decode.string) Nothing - tagEncoder : Tag -> Encode.Value tagEncoder model = Encode.object [ ( "id", withDefault Encode.null (map Encode.int model.id) ) , ( "name", withDefault Encode.null (map Encode.string model.name) ) ] - diff --git a/samples/client/petstore/elm/src/Data/User.elm b/samples/client/petstore/elm/src/Data/User.elm index 9395b0d02f8..3f08ec51625 100644 --- a/samples/client/petstore/elm/src/Data/User.elm +++ b/samples/client/petstore/elm/src/Data/User.elm @@ -45,7 +45,6 @@ userDecoder = |> optional "userStatus" (Decode.nullable Decode.int) Nothing - userEncoder : User -> Encode.Value userEncoder model = Encode.object @@ -58,4 +57,3 @@ userEncoder model = , ( "phone", withDefault Encode.null (map Encode.string model.phone) ) , ( "userStatus", withDefault Encode.null (map Encode.int model.userStatus) ) ] - diff --git a/samples/client/petstore/elm/src/Request/Pet.elm b/samples/client/petstore/elm/src/Request/Pet.elm index 2a96489a830..0a3b1e89891 100644 --- a/samples/client/petstore/elm/src/Request/Pet.elm +++ b/samples/client/petstore/elm/src/Request/Pet.elm @@ -12,8 +12,8 @@ module Request.Pet exposing (addPet, deletePet, findPetsByStatus, findPetsByTags, getPetById, updatePet, updatePetWithForm, uploadFile) -import Data.Pet exposing (Pet, petDecoder, petEncoder) import Data.ApiResponse exposing (ApiResponse, apiResponseDecoder) +import Data.Pet exposing (Pet, petDecoder, petEncoder) import Dict import Http import Json.Decode as Decode