Skip to content

Immutable types #11

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

Draft
wants to merge 28 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4d549ee
Update config
dmdashenkov Sep 4, 2020
4235d78
Update Gradle
dmdashenkov Sep 4, 2020
b1e3a3d
Fix path to script
dmdashenkov Sep 4, 2020
8b23b6c
Add contribution guidelines
dmdashenkov Sep 4, 2020
b28f5e7
Update copyright
dmdashenkov Sep 4, 2020
1c15d46
Ignore all `.gradle` dirs for Git
dmdashenkov Sep 4, 2020
f3f03ee
Add a missing param type
dmdashenkov Sep 4, 2020
996fbf0
Freeze everything!
dmdashenkov Sep 4, 2020
983e3d5
Remove use of deprecated Firebase API
dmdashenkov Sep 4, 2020
e8b00fe
Generate templates for consumption by `built_value`
dmdashenkov Sep 7, 2020
070b6c0
Update `code_builder`
dmdashenkov Sep 7, 2020
202ff20
Fix function type
dmdashenkov Sep 7, 2020
544def1
Remove logging
dmdashenkov Sep 7, 2020
8879f59
Update dependencies
dmdashenkov Sep 8, 2020
9f42d37
Configure `built_value`
dmdashenkov Sep 8, 2020
638dfba
Fix imports in generated code
dmdashenkov Sep 8, 2020
697ea4c
Update gitignore
dmdashenkov Sep 8, 2020
5764dfe
Set up immutable type generation
dmdashenkov Sep 8, 2020
c8c044b
Use `FieldDeclaration` instead of `FieldDescriptorProto`
dmdashenkov Sep 12, 2020
8e9b290
Extract immutable type generation
dmdashenkov Sep 12, 2020
2f3228f
Escape field names which coincide with `built_value` methods
dmdashenkov Sep 12, 2020
c6ad00c
Generate immutable types into the standard Proto file
dmdashenkov Sep 12, 2020
0f0e73a
Provide actual field types for message fields
dmdashenkov Sep 17, 2020
dc4949d
Update config
dmdashenkov Sep 17, 2020
671dec8
Add a `Type.toString` impl
dmdashenkov Sep 18, 2020
b297832
Delete commented code
dmdashenkov Sep 18, 2020
c635699
Generate ctor from mutable to immutable type
dmdashenkov Sep 22, 2020
28ff294
Add a doc
dmdashenkov Sep 22, 2020
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
!.idea/misc.xml

# Gradle interim configs
.gradle/**
**/.gradle/**

# Generated source code
**/generated/**
Expand Down Expand Up @@ -77,5 +77,7 @@ pubspec.lock
**/*.pbjson.dart
**/types.dart
**/validators.dart
**/*.proto.dart
**/*.g.dart

**/spine-dev.json
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ script:
deploy:
skip_cleanup: false
provider: script
script: bash config/publish-artifacts.sh
script: bash config/scripts/publish-artifacts.sh
on:
branch: master
condition: $TRAVIS_PULL_REQUEST == "false"
37 changes: 37 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
How to contribute
==================
Thank you for wanting to contribute to Spine. The following links will help you get started:
* [Wiki home][wiki-home] — the home of the framework developer's documentation.
* [Getting started with Spine in Java][quick-start] — this guide will walk you through
a minimal client-server “Hello World!” application in Java.
* [Introduction][docs-intro] — this section of the Spine Documentation will help you understand
the foundation of the framework.

Pull requests
-------------
The work on an improvement starts with creating an issue that describes a bug or a feature. The issue will be used for communications on the proposed improvements.
If code changes are going to be introduced, the issue should also have a link to the corresponding Pull Request.

Code contributions should:
* Be accompanied by tests.
* Be licensed under the Apache v2.0 license with the appropriate copyright header for each file.
* Formatted according to the code style. See [Wiki home][wiki-home] for the links to
style guides of the programming languages used in the framework.

Contributor License Agreement
-----------------------------
Contributions to the code of Spine Event Engine framework and its libraries must be accompanied by
Contributor License Agreement (CLA).

* If you are an individual writing original source code and you're sure you own
the intellectual property, then you'll need to sign an individual CLA.

* If you work for a company which wants you to contribute your work,
then an authorized person from your company will need to sign a corporate CLA.

Please [contact us][legal-email] for arranging the paper formalities.

[wiki-home]: https://github.com/SpineEventEngine/SpineEventEngine.github.io/wiki
[quick-start]: https://spine.io/docs/quick-start
[docs-intro]: https://spine.io/docs/introduction
[legal-email]: mailto:legal@teamdev.com
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019, TeamDev. All rights reserved.
* Copyright 2020, TeamDev. All rights reserved.
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
Expand Down
47 changes: 37 additions & 10 deletions buildSrc/src/main/kotlin/codegen.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,24 @@ if (!file(command).exists()) {
logger.warn("Cannot locate `dart_code_gen` under `$command`.")
}

fun composeCommandLine(descriptor: File, targetDir: String, standardTypesPackage: String) =
listOf(
command,
"--descriptor", "${file(descriptor)}",
"--destination", "$targetDir/types.dart",
"--standard-types", standardTypesPackage,
"--import-prefix", "."
)
fun composeCommandLine(descriptor: File,
targetDir: String,
standardTypesPackage: String,
generateImmutableTypes: Boolean): List<String> {
val args = mutableListOf(
command,
"--descriptor", descriptor.path,
"--destination", "$targetDir/types.dart",
"--standard-types", standardTypesPackage,
"--import-prefix", "."
)
if (generateImmutableTypes) {
args.add("--immutable-types")
args.add(targetDir)
}
return args
}


/**
* Task which launches Dart code generation from Protobuf.
Expand All @@ -59,19 +69,36 @@ open class GenerateDart : Exec() {
var target: String = ""
@Internal
var standardTypesPackage: String = ""
@Internal
var generateImmutableTypes: Boolean = true
}

tasks.create("generateDart", GenerateDart::class) {
val pub = "pub" + if (Os.isFamily(Os.FAMILY_WINDOWS)) ".bat" else ""

val pubGet by tasks.creating(Exec::class) {
commandLine(pub, "get")
}

val generateDart by tasks.creating(GenerateDart::class) {
@Suppress("UNCHECKED_CAST")
descriptor = project.extensions["protoDart"].withGroovyBuilder { getProperty("mainDescriptorSet") } as Property<File>
target = "$projectDir/lib"
standardTypesPackage = "spine_client"
}

val launchBuilder by tasks.creating(Exec::class) {
commandLine(pub, "run", "build_runner", "build")
dependsOn(generateDart, pubGet)
generateDart.finalizedBy(this)
}

afterEvaluate {
tasks.withType(GenerateDart::class) {
inputs.file(descriptor)
commandLine(composeCommandLine(file(descriptor.get()), target, standardTypesPackage))
commandLine(composeCommandLine(file(descriptor.get()),
target,
standardTypesPackage,
generateImmutableTypes))
dependsOn(":codegen:activateLocally")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import java.io.FileNotFoundException
import java.net.URL

/**
Expand All @@ -52,21 +53,21 @@ open class CheckVersionIncrement : DefaultTask() {
val artifact = "${project.artifactPath()}/${MavenMetadata.FILE_NAME}"
val repoUrl = repository.releases
val metadata = fetch(repoUrl, artifact)
val versions = metadata.versioning.versions
val versionExists = versions.contains(version)
val versions = metadata?.versioning?.versions
val versionExists = versions?.contains(version) ?: false
if (versionExists) {
throw GradleException("""
Version `$version` is already published to maven repository `$repoUrl`.
Try incrementing the library version.
All available versions are: ${versions.joinToString(separator = ", ")}.
All available versions are: ${versions?.joinToString(separator = ", ")}.

To disable this check, run Gradle with `-x $name`.
""".trimIndent()
)
}
}

private fun fetch(repository: String, artifact: String): MavenMetadata {
private fun fetch(repository: String, artifact: String): MavenMetadata? {
val url = URL("$repository/$artifact")
return MavenMetadata.fetchAndParse(url)
}
Expand Down Expand Up @@ -94,9 +95,19 @@ private data class MavenMetadata(var versioning: Versioning = Versioning()) {
mapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
}

fun fetchAndParse(url: URL): MavenMetadata {
val metadata = mapper.readValue(url, MavenMetadata::class.java)
return metadata
/**
* Fetches the metadata for the repository and parses the document.
*
* <p>If the document could not be found, assumes that the module was never
* released and thus has no metadata.
*/
fun fetchAndParse(url: URL): MavenMetadata? {
return try {
val metadata = mapper.readValue(url, MavenMetadata::class.java)
metadata
} catch (e: FileNotFoundException) {
null
}
}
}
}
Expand Down
28 changes: 21 additions & 7 deletions buildSrc/src/main/kotlin/io/spine/gradle/internal/deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ object Versions {
val checkerFramework = "3.3.0"
val errorProne = "2.3.4"
val errorProneJavac = "9+181-r4173-1" // taken from here: https://github.com/tbroyer/gradle-errorprone-plugin/blob/v0.8/build.gradle.kts
val errorPronePlugin = "1.1.1"
val pmd = "6.20.0"
val errorPronePlugin = "1.2.1"
val pmd = "6.24.0"
val checkstyle = "8.29"
val protobufPlugin = "0.8.12"
val appengineApi = "1.9.79"
Expand All @@ -94,14 +94,19 @@ object Versions {
val javaPoet = "1.12.1"
val autoService = "1.0-rc6"
val autoCommon = "0.10"
val jackson = "2.9.10.4"
val jackson = "2.9.10.5"
val animalSniffer = "1.18"
val apiguardian = "1.1.0"
val javaxAnnotation = "1.3.2"
val klaxon = "5.4"
val ouathJwt = "3.10.3"
val bouncyCastlePkcs = "1.66"
val assertK = "0.22"

/**
* Version of the SLF4J library.
*
* Spine used to log with SLF4J. Now we use Flogger. Whenever a coice comes up, we recommend to
* Spine used to log with SLF4J. Now we use Flogger. Whenever a choice comes up, we recommend to
* use the latter.
*
* Some third-party libraries may clash with different versions of the library. Thus, we specify
Expand Down Expand Up @@ -158,12 +163,20 @@ object Build {

object AutoService {
val annotations = "com.google.auto.service:auto-service-annotations:${Versions.autoService}"
val processor = "com.google.auto.service:auto-service:${Versions.autoService}"
val processor = "com.google.auto.service:auto-service:${Versions.autoService}"
}
}

object Gen {
val javaPoet = "com.squareup:javapoet:${Versions.javaPoet}"
val javaPoet = "com.squareup:javapoet:${Versions.javaPoet}"
val javaxAnnotation = "javax.annotation:javax.annotation-api:${Versions.javaxAnnotation}"
}

object Publishing {
val klaxon = "com.beust:klaxon:${Versions.klaxon}"
val oauthJwt = "com.auth0:java-jwt:${Versions.ouathJwt}"
val bouncyCastlePkcs = "org.bouncycastle:bcpkix-jdk15on:${Versions.bouncyCastlePkcs}"
val assertK = "com.willowtreeapps.assertk:assertk-jvm:${Versions.assertK}"
}

object Grpc {
Expand Down Expand Up @@ -227,7 +240,7 @@ object Test {
"com.google.truth.extensions:truth-proto-extension:${Versions.truth}"
)
@Deprecated("Use Flogger over SLF4J.",
replaceWith = ReplaceWith("Deps.runtime.floggerSystemBackend"))
replaceWith = ReplaceWith("Deps.runtime.floggerSystemBackend"))
@Suppress("DEPRECATION") // Version of SLF4J.
val slf4j = "org.slf4j:slf4j-jdk14:${Versions.slf4j}"
}
Expand Down Expand Up @@ -273,6 +286,7 @@ object Deps {
val test = Test
val versions = Versions
val scripts = Scripts
val publishing = Publishing
}

object DependencyResolution {
Expand Down
2 changes: 1 addition & 1 deletion client/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019, TeamDev. All rights reserved.
* Copyright 2020, TeamDev. All rights reserved.
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
Expand Down
14 changes: 14 additions & 0 deletions client/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
targets:
$default:
builders:
"built_value":

builders:
built_value:
target: ":client"
import: "package:built_value_generator/builder.dart"
builder_factories:
- "builtValue"
build_extensions:
".proto.dart": [".g.dart"]
build_to: "source"
11 changes: 5 additions & 6 deletions client/lib/actor_request_factory.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019, TeamDev. All rights reserved.
* Copyright 2020, TeamDev. All rights reserved.
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
Expand Down Expand Up @@ -61,14 +61,13 @@ class ActorRequestFactory {
}

ActorContext _context() {
var ctx = ActorContext();
ctx
return ActorContext((b) => b
..actor = this.actor
..timestamp = time.now()
..tenantId = this.tenant ?? TenantId.getDefault()
..tenantId = this.tenant ?? TenantId.defaultInstance
..zoneOffset = zoneOffset ?? time.zoneOffset()
..zoneId = zoneId ?? time.guessZoneId();
return ctx;
..zoneId = zoneId ?? time.guessZoneId()
);
}
}

Expand Down
28 changes: 10 additions & 18 deletions client/lib/backend_client.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019, TeamDev. All rights reserved.
* Copyright 2020, TeamDev. All rights reserved.
*
* Redistribution and use in source and/or binary forms, with or without
* modification, must retain the above copyright notice and the following
Expand All @@ -23,6 +23,7 @@ import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:protobuf/protobuf.dart';
import 'package:spine_client/firebase_client.dart';
import 'package:spine_client/message.dart';
import 'package:spine_client/src/http_endpoint.dart';
import 'package:spine_client/spine/client/query.pb.dart';
import 'package:spine_client/spine/client/subscription.pb.dart' as pb;
Expand Down Expand Up @@ -153,27 +154,18 @@ class BackendClient {
return subscription;
}

Ack _parseAck(http.Response response) {
var ack = Ack();
_parseInto(ack, response);
return ack;
}
Ack _parseAck(http.Response response) =>
_parse(Ack.defaultInstance, response);

FirebaseQueryResponse _parseQueryResponse(http.Response response) {
var queryResponse = FirebaseQueryResponse();
_parseInto(queryResponse, response);
return queryResponse;
}
FirebaseQueryResponse _parseQueryResponse(http.Response response) =>
_parse(FirebaseQueryResponse.defaultInstance, response);

FirebaseSubscription _parseFirebaseSubscription(http.Response response) {
var firebaseSubscription = FirebaseSubscription();
_parseInto(firebaseSubscription, response);
return firebaseSubscription;
}
FirebaseSubscription _parseFirebaseSubscription(http.Response response) =>
_parse(FirebaseSubscription.defaultInstance, response);

void _parseInto(GeneratedMessage message, http.Response response) {
M _parse<M extends Message<M, P>, P extends GeneratedMessage>(M defaultInstance, http.Response response) {
var json = response.body;
parseInto(message, json);
return parseAs(defaultInstance, json);
}

void _keepUpSubscriptions() {
Expand Down
Loading