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

(java): java sdk, model and spring generators now support boolean literals #2887

Merged
merged 6 commits into from
Feb 5, 2024
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
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
Loading