Skip to content

Commit

Permalink
(java): java sdk, model and spring generators now support boolean lit…
Browse files Browse the repository at this point in the history
…erals (#2887)

* java generators now support boolean literals

* update examples snapshots

* udpate object test definition snapshots

* update snapshots

* fix cli

* update object snapshots
  • Loading branch information
dsinghvi authored Feb 5, 2024
1 parent 2a4f202 commit 20d3a18
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 542 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ Postman Collections, Server boilerplate, etc.). Below you can find a list of all
| `fernapi/fern-fastapi-server` | FastAPI boilerplate | `0.7.7` | [CHANGELOG.md](./generators/python/fastapi/CHANGELOG.md) | [cli.py](./generators/python/src/fern_python/generators/sdk/cli.py) |
| `fernapi/fern-openapi` | OpenAPI Spec | `0.0.30` | [CHANGELOG.md](./generators/openapi/CHANGELOG.md) | [cli.ts](./generators/openapi/src/cli.ts) |
| `fernapi/fern-ruby-model` | Ruby Models | `0.0.6` | [CHANGELOG.md](./generators/ruby/model/CHANGELOG.md) | [cli.ts](./generators/ruby/model/src/cli.ts) |
| `fernapi/fern-java-sdk` | Java SDK | `0.6.1` | [CHANGELOG.md](./generators/java/sdk/CHANGELOG.md) | [Cli.java](./generators/java/sdk/src/main/java/com/fern/java/client/Cli.java) |
| `fernapi/java-model` | Java Models | `0.6.1` | [CHANGELOG.md](./generators/java/model/CHANGELOG.md) | [Cli.java](./generators/java/model/src/main/java/com/fern/java/model/Cli.java) |
| `fernapi/fern-java-spring` | Spring boilerplate | `0.6.1` | [CHANGELOG.md](./generators/java/spring/CHANGELOG.md) | [Cli.java](./generators/java/spring/src/main/java/com/fern/java/spring/Cli.java)|
| `fernapi/fern-java-sdk` | Java SDK | `0.7.1` | [CHANGELOG.md](./generators/java/sdk/CHANGELOG.md) | [Cli.java](./generators/java/sdk/src/main/java/com/fern/java/client/Cli.java) |
| `fernapi/java-model` | Java Models | `0.7.1` | [CHANGELOG.md](./generators/java/model/CHANGELOG.md) | [Cli.java](./generators/java/model/src/main/java/com/fern/java/model/Cli.java) |
| `fernapi/fern-java-spring` | Spring boilerplate | `0.7.1` | [CHANGELOG.md](./generators/java/spring/CHANGELOG.md) | [Cli.java](./generators/java/spring/src/main/java/com/fern/java/spring/Cli.java)|

## CLI Commands

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fern.ir.model.commons.Name;
import com.fern.ir.model.types.ContainerType;
import com.fern.ir.model.types.Literal;
import com.fern.ir.model.types.Literal.Visitor;
import com.fern.ir.model.types.ObjectProperty;
import com.fern.java.immutables.StagedBuilderImmutablesStyle;
import com.fern.java.utils.JavaDocUtils;
Expand Down Expand Up @@ -33,11 +34,11 @@ public interface EnrichedObjectProperty {

Optional<String> docs();

Optional<String> literalValue();
Optional<Literal> literal();

@Value.Lazy
default Optional<FieldSpec> fieldSpec() {
if (literalValue().isPresent()) {
if (literal().isPresent()) {
return Optional.empty();
}
return Optional.of(FieldSpec.builder(
Expand All @@ -54,8 +55,25 @@ default MethodSpec getterProperty() {
KeyWordUtils.getKeyWordCompatibleMethodName("get" + pascalCaseKey()))
.addModifiers(Modifier.PUBLIC)
.returns(poetTypeName());
if (literalValue().isPresent()) {
getterBuilder.addStatement("return $S", literalValue().get());
if (literal().isPresent()) {
literal().get().visit(new Literal.Visitor<Void>() {
@Override
public Void visitString(String string) {
getterBuilder.addStatement("return $S", string);
return null;
}

@Override
public Void visitBoolean(boolean boolean_) {
getterBuilder.addStatement("return $L", boolean_);
return null;
}

@Override
public Void _visitUnknown(Object unknownType) {
return null;
}
});
} else {
getterBuilder.addStatement("return $L", fieldSpec().get().name);
}
Expand All @@ -79,19 +97,18 @@ static ImmutableEnrichedObjectProperty.CamelCaseKeyBuildStage builder() {

static EnrichedObjectProperty of(ObjectProperty objectProperty, boolean fromInterface, TypeName poetTypeName) {
Name name = objectProperty.getName().getName();
Optional<String> maybeLiteral = objectProperty
Optional<Literal> maybeLiteral = objectProperty
.getValueType()
.getContainer()
.flatMap(ContainerType::getLiteral)
.flatMap(Literal::getString);
.flatMap(ContainerType::getLiteral);
return EnrichedObjectProperty.builder()
.camelCaseKey(name.getCamelCase().getSafeName())
.pascalCaseKey(name.getPascalCase().getSafeName())
.poetTypeName(poetTypeName)
.fromInterface(fromInterface)
.wireKey(objectProperty.getName().getWireValue())
.docs(objectProperty.getDocs())
.literalValue(maybeLiteral)
.literal(maybeLiteral)
.build();
}
}
17 changes: 16 additions & 1 deletion generators/java/model/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.7.0-rc0] - 2024-02-04
## [0.7.1] - 2024-02-04
- Chore: Bump intermediate representation to v31
- Feature: The generated models now support boolean literals and users
do not have to specify them in the builder.
For example, for the following object
```yaml
Actor:
properties:
name: string
isMale: literal<true>
```
the user will not need to specify the literal properties when building
the object.
```java
var actor = Actor.builder()
.name("Brad Pitt")
.build();

## [0.6.1] - 2024-02-03

Expand Down
2 changes: 1 addition & 1 deletion generators/java/model/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.0-rc0
0.7.1
18 changes: 17 additions & 1 deletion generators/java/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.7.0-rc2] - 2024-02-04
## [0.7.1] - 2024-02-04
- Chore: Bump intermediate representation to v31
- Feature: The SDK generator now supports idempotency headers. Users
will be able to specify the idempotency headers in RequestOptions.
Expand All @@ -25,6 +25,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
.apiKey("...") // defaults to System.getenv("IMDB_API_KEY")
.build();
```
- Feature: The generated models now support boolean literals and users
do not have to specify them in the builder.
For example, for the following object
```yaml
Actor:
properties:
name: string
isMale: literal<true>
```
the user will not need to specify the literal properties when building
the object.
```java
var actor = Actor.builder()
.name("Brad Pitt")
.build();
```

## [0.6.1] - 2024-02-03

Expand Down
2 changes: 1 addition & 1 deletion generators/java/sdk/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.0-rc2
0.7.1
18 changes: 17 additions & 1 deletion generators/java/spring/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.7.0-rc0] - 2024-02-04
## [0.7.1] - 2024-02-04
- Chore: Bump intermediate representation to v31
- Feature: The generated models now support boolean literals and users
do not have to specify them in the builder.
For example, for the following object
```yaml
Actor:
properties:
name: string
isMale: literal<true>
```
the user will not need to specify the literal properties when building
the object.
```java
var actor = Actor.builder()
.name("Brad Pitt")
.build();
```

## [0.6.1] - 2024-02-03

Expand Down
2 changes: 1 addition & 1 deletion generators/java/spring/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.0-rc0
0.7.1
104 changes: 53 additions & 51 deletions packages/seed/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ function addTestCommand(cli: Argv) {
(yargs) =>
yargs
.option("workspace", {
type: "string"
type: "array",
string: true,
default: undefined,
demandOption: true,
description: "The workspace to run tests on"
})
.option("parallel", {
type: "number",
Expand All @@ -40,7 +44,9 @@ function addTestCommand(cli: Argv) {
description: "Path to the api directory"
})
.option("fixture", {
type: "string",
type: "array",
string: true,
default: FIXTURES,
choices: FIXTURES,
demandOption: false,
description: "Runs on all fixtures if not provided"
Expand All @@ -63,58 +69,54 @@ function addTestCommand(cli: Argv) {
async (argv) => {
const workspaces = await loadSeedWorkspaces();

const filteredWorkspace = workspaces.filter((workspace) => {
return workspace.workspaceName === argv.workspace;
});

if (filteredWorkspace[0] == null) {
throw new Error(`Failed to find workspace ${argv.workspace}`);
}
for (const workspace of workspaces) {
if (!argv.workspace.includes(workspace.workspaceName)) {
continue;
}

const workspace = filteredWorkspace[0];
const parsedDockerImage = validateAndParseDockerImage(workspace.workspaceConfig.docker);

const parsedDockerImage = validateAndParseDockerImage(workspace.workspaceConfig.docker);

const taskContextFactory = new TaskContextFactory(argv["log-level"]);
if (workspace.workspaceConfig.dockerCommand != null) {
const workspaceTaskContext = taskContextFactory.create(workspace.workspaceName);
await runScript({
commands:
typeof workspace.workspaceConfig.dockerCommand === "string"
? [workspace.workspaceConfig.dockerCommand]
: workspace.workspaceConfig.dockerCommand,
logger: workspaceTaskContext.logger,
workingDir: path.dirname(path.dirname(workspace.absolutePathToWorkspace)),
doNotPipeOutput: false
});
}
const taskContextFactory = new TaskContextFactory(argv["log-level"]);
if (workspace.workspaceConfig.dockerCommand != null) {
const workspaceTaskContext = taskContextFactory.create(workspace.workspaceName);
await runScript({
commands:
typeof workspace.workspaceConfig.dockerCommand === "string"
? [workspace.workspaceConfig.dockerCommand]
: workspace.workspaceConfig.dockerCommand,
logger: workspaceTaskContext.logger,
workingDir: path.dirname(path.dirname(workspace.absolutePathToWorkspace)),
doNotPipeOutput: false
});
}

if (argv.customFixture != null) {
await testCustomFixture({
pathToFixture: argv.customFixture.startsWith("/")
? AbsoluteFilePath.of(argv.customFixture)
: join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of(argv.customFixture)),
workspace,
irVersion: workspace.workspaceConfig.irVersion,
language: workspace.workspaceConfig.language,
docker: parsedDockerImage,
logLevel: argv["log-level"],
numDockers: argv.parallel,
keepDocker: argv.keepDocker
});
} else {
await testWorkspaceFixtures({
workspace,
fixtures: argv.fixture != null ? [argv.fixture] : FIXTURES,
irVersion: workspace.workspaceConfig.irVersion,
language: workspace.workspaceConfig.language,
docker: parsedDockerImage,
scripts: workspace.workspaceConfig.scripts,
logLevel: argv["log-level"],
numDockers: argv.parallel,
taskContextFactory,
keepDocker: argv.keepDocker
});
if (argv.customFixture != null) {
await testCustomFixture({
pathToFixture: argv.customFixture.startsWith("/")
? AbsoluteFilePath.of(argv.customFixture)
: join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of(argv.customFixture)),
workspace,
irVersion: workspace.workspaceConfig.irVersion,
language: workspace.workspaceConfig.language,
docker: parsedDockerImage,
logLevel: argv["log-level"],
numDockers: argv.parallel,
keepDocker: argv.keepDocker
});
} else {
await testWorkspaceFixtures({
workspace,
fixtures: argv.fixture,
irVersion: workspace.workspaceConfig.irVersion,
language: workspace.workspaceConfig.language,
docker: parsedDockerImage,
scripts: workspace.workspaceConfig.scripts,
logLevel: argv["log-level"],
numDockers: argv.parallel,
taskContextFactory,
keepDocker: argv.keepDocker
});
}
}
}
);
Expand Down
Loading

0 comments on commit 20d3a18

Please sign in to comment.