Skip to content

Commit a00a28c

Browse files
authored
More predictable handling of trait/validator classes model loader (#1709)
1 parent 5ffea52 commit a00a28c

20 files changed

Lines changed: 270 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ When adding entries, please treat them as if they could end up in a release any
55

66
Thank you!
77

8+
# 0.18.36
9+
10+
* codegen: Pass the correct ClassLoader to prevent validators/transformers from breaking on externally-defined trait classes in [#1709](https://github.com/disneystreaming/smithy4s/pull/1709)
11+
812
# 0.18.35
913

1014
* json, documents: Add support for `@jsonUnknown` in unions (Open Unions) in [#1677](https://github.com/disneystreaming/smithy4s/pull/1677)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
lazy val transformation = project
2+
.settings(
3+
scalaVersion := "2.12.20",
4+
libraryDependencies ++= Seq(
5+
"software.amazon.smithy" % "smithy-build" % "1.57.1",
6+
"ch.epfl.scala" % "spec-traits" % "2.2.0-M2"
7+
)
8+
)
9+
10+
lazy val root = project
11+
.in(file("."))
12+
.enablePlugins(Smithy4sCodegenPlugin)
13+
.settings(
14+
scalaVersion := "3.3.6",
15+
libraryDependencies ++= Seq(
16+
"ch.epfl.scala" % "spec-traits" % "2.2.0-M2" % Smithy4s,
17+
"com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value
18+
),
19+
Compile / smithy4sModelTransformers := List(
20+
"my-transformation"
21+
),
22+
Compile / smithy4sAllowedNamespaces := List("my.input"),
23+
Compile / smithy4sAllDependenciesAsJars += (transformation / Compile / packageBin).value
24+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
sys.props.get("plugin.version") match {
2+
case Some(x) =>
3+
addSbtPlugin("com.disneystreaming.smithy4s" % "smithy4s-sbt-codegen" % x)
4+
case _ =>
5+
sys.error(
6+
"""|The system property 'plugin.version' is not defined.
7+
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin
8+
)
9+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2021-2025 Disney Streaming
3+
*
4+
* Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://disneystreaming.github.io/TOST-1.0.txt
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
object Main extends App {
18+
val hints = my.input.MyShape.schema.hints
19+
20+
require(
21+
hints.has[smithy.api.Documentation],
22+
s"Expected to have the Documentation trait, but it was missing: $hints"
23+
)
24+
25+
require(
26+
hints.get[smithy.api.Documentation].get.value == "what's up doc",
27+
s"Documentation trait mismatch: ${hints.get[smithy.api.Documentation].get.value}"
28+
)
29+
println("all good: " + hints.all)
30+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
$version: "2"
2+
3+
namespace my.input
4+
5+
@traits#data
6+
document MyShape
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# check if the app runs successfully.
2+
# if it doesn't compile, it could be because the transformation wasn't applied.
3+
# if the transformation throws, it's because of a bug like #336.
4+
> run
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MyTransformation
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2021-2025 Disney Streaming
3+
*
4+
* Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://disneystreaming.github.io/TOST-1.0.txt
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import software.amazon.smithy.build.ProjectionTransformer
18+
import software.amazon.smithy.build.TransformContext
19+
import software.amazon.smithy.model.Model
20+
import software.amazon.smithy.model.transform.ModelTransformer
21+
import java.util.function.BiFunction
22+
import software.amazon.smithy.model.traits.Trait
23+
import software.amazon.smithy.model.shapes.Shape
24+
import software.amazon.smithy.model.traits.DocumentationTrait
25+
import software.amazon.smithy.model.shapes.ShapeId
26+
import bsp.traits.DataTrait
27+
28+
class MyTransformation extends ProjectionTransformer {
29+
def getName(): String = "my-transformation"
30+
31+
// Replace traits#jsonRPC with documentation
32+
def transform(context: TransformContext): Model = {
33+
// this would fail if the class wasn't present on the classpath.
34+
35+
// external shape - regression test for #336
36+
context
37+
.getModel()
38+
.expectShape(ShapeId.from("bsp#BuildTargetData"))
39+
.expectTrait(classOf[DataTrait])
40+
41+
// local shape
42+
context
43+
.getModel()
44+
.expectShape(ShapeId.from("my.input#MyShape"))
45+
.expectTrait(classOf[DataTrait])
46+
47+
ModelTransformer
48+
.create()
49+
.mapTraits(
50+
context.getModel(),
51+
{
52+
case (_, _: DataTrait) =>
53+
new DocumentationTrait("what's up doc")
54+
case (_, trt) => trt
55+
}: BiFunction[Shape, Trait, Trait]
56+
)
57+
}
58+
59+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
lazy val externalLibrary = project
2+
.settings(
3+
autoScalaLibrary := false,
4+
crossPaths := false,
5+
libraryDependencies ++= Seq(
6+
"software.amazon.smithy" % "smithy-model" % "1.57.1"
7+
)
8+
)
9+
10+
lazy val root = project
11+
.in(file("."))
12+
.enablePlugins(Smithy4sCodegenPlugin)
13+
.settings(
14+
scalaVersion := "3.3.6",
15+
libraryDependencies ++= Seq(
16+
"com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value
17+
),
18+
Compile / smithy4sAllDependenciesAsJars += (externalLibrary / Compile / packageBin).value
19+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2021-2025 Disney Streaming
3+
*
4+
* Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://disneystreaming.github.io/TOST-1.0.txt
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import software.amazon.smithy.model.SourceLocation;
18+
import software.amazon.smithy.model.shapes.ShapeId;
19+
import software.amazon.smithy.model.traits.StringTrait;
20+
21+
public class ApiVersionTrait extends StringTrait {
22+
23+
public static ShapeId ID = ShapeId.from("my.input#apiVersion");
24+
25+
public ApiVersionTrait(String value, SourceLocation sourceLocation) {
26+
super(ID, value, sourceLocation);
27+
}
28+
29+
public ApiVersionTrait(String value) {
30+
this(value, SourceLocation.NONE);
31+
}
32+
33+
public static final class Provider extends StringTrait.Provider<ApiVersionTrait> {
34+
public Provider() {
35+
super(ID, ApiVersionTrait::new);
36+
}
37+
}
38+
39+
}

0 commit comments

Comments
 (0)