Skip to content

Commit 7b45aae

Browse files
0.19: feat: Allow to customize generated package name (disneystreaming#1950) (disneystreaming#1967)
* feat: Allow to customize generated package name (disneystreaming#1950) * feat: Allow to customize generated package name * Add change log and documentation * Update changelog * Use information about previous mappings when calculating current mappings * Add remapping example to bootstrapped * Add cross-module reference test * Add missing header * Address review comments --------- Co-authored-by: ghostbuster91 <ghostbuster91@users.noreply.github.com> * Add changelog entry * Fix compilation issues after port * apply scalafix * trigger CI * feat: Add allowedNamespaces to smithy4sCodegen metadata; deprecate build-tool namespace settings Adds `allowedNamespaces` to the `smithy4sCodegen` Smithy metadata key as the counterpart to the existing `excludedNamespaces` field. When the build-tool `allowedNamespaces` / `excludedNamespaces` settings are also set, the two sources are unioned. Deprecates the build-tool surface (sbt `smithy4sAllowedNamespaces` / `smithy4sExcludedNamespaces`, mill equivalents, and CLI `--allowed-ns` / `--excluded-ns`) in favor of the Smithy-metadata-based form so namespace filtering can live with the model rather than the build. * Apply scalafix * fix: Make multimodule-package-prefix scripted test work under sbt 2 Two pre-existing issues left over from porting PR disneystreaming#1950 to the 0.19 series were preventing this scripted test from running on the sbt 2 / Scala 3 plugin: - Missing `excludeDependencies` block in `project/plugins.sbt` for the `_2.13` variants that conflict with `_3` under sbt 2 (other scripted tests have this same workaround). - Path-based `$ exists` / `$ absent` assertions were hardcoded to sbt 1's `target/scala-2.13/src_managed/...` layout. Replaced them with sbt tasks that use `Compile / sourceManaged`, which resolves correctly under both sbt 1 and sbt 2. --------- Co-authored-by: ghostbuster91 <ghostbuster91@users.noreply.github.com>
1 parent c1166ea commit 7b45aae

28 files changed

Lines changed: 1091 additions & 42 deletions

File tree

CHANGELOG.md

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

66
Thank you!
77

8+
# 0.19.5
9+
10+
- Port of [#1950](https://github.com/disneystreaming/smithy4s/pull/1950) to 0.19 series
11+
codegen: Add `smithy4sCodegen` metadata key for render-time package remapping. Supports `packagePrefix` (prepend a prefix to all generated packages), `packageMappings` (per-namespace overrides), and `excludedNamespaces` (skip namespaces from codegen). See [Package Remapping](https://disneystreaming.github.io/smithy4s/docs/codegen/customisation/package-remapping) for details.
12+
- codegen: Add `allowedNamespaces` field to the `smithy4sCodegen` Smithy metadata key — restricts codegen to the listed namespace patterns. When the build-tool `allowedNamespaces` / `excludedNamespaces` settings are also set, the two sources are unioned.
13+
- codegen: Deprecate the build-tool `allowedNamespaces` / `excludedNamespaces` settings (sbt `smithy4sAllowedNamespaces` / `smithy4sExcludedNamespaces`, the equivalent mill targets, and the CLI `--allowed-ns` / `--excluded-ns` flags) in favor of the `smithy4sCodegen` Smithy metadata key.
14+
815
# 0.19.4
916

1017
- Add documentation for `UrlForm` serialization in [#1929](https://github.com/disneystreaming/smithy4s/pull/1929)
@@ -119,6 +126,10 @@ Prevents using it as an implicit conversion in Scala 2
119126

120127
The handwritten Java `TraitService` implementations for all smithy4s meta traits in the protocol module have been removed and are now generated by smithy4s itself. This should not affect users who are not programmatically using those traits directly. (see [#1901](https://github.com/disneystreaming/smithy4s/pull/1901))
121128

129+
# 0.18.53
130+
131+
* codegen: Add `smithy4sCodegen` metadata key for render-time package remapping. Supports `packagePrefix` (prepend a prefix to all generated packages), `packageMappings` (per-namespace overrides), and `excludedNamespaces` (skip namespaces from codegen). See [Package Remapping](https://disneystreaming.github.io/smithy4s/docs/codegen/customisation/package-remapping) for details.
132+
122133
# 0.18.50
123134

124135
* Add effectful `make` overloads to `UnaryClientCompiler` and `UnaryClientEndpoint` accepting `Response => F[Boolean]`

build.sbt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,9 @@ lazy val bootstrapped = projectMatrix
11381138
"weather",
11391139
"smithy4s.example.product",
11401140
"smithy4s.example.reservedNameOverride",
1141-
"smithy4s.example.bincompat"
1141+
"smithy4s.example.bincompat",
1142+
"pkg.remapping",
1143+
"pkg.remapping.nested"
11421144
),
11431145
smithySpecs := IO.listFiles(
11441146
(ThisBuild / baseDirectory).value / "sampleSpecs"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package smithy4s.example.packageremapping
2+
3+
import smithy4s.Hints
4+
import smithy4s.Schema
5+
import smithy4s.ShapeId
6+
import smithy4s.ShapeTag
7+
import smithy4s.example.packageremapping.nested.NestedString
8+
import smithy4s.schema.Schema.struct
9+
10+
final case class PackageRemappingExample(value: NestedString)
11+
12+
object PackageRemappingExample extends ShapeTag.Companion[PackageRemappingExample] {
13+
val id: ShapeId = ShapeId("pkg.remapping", "PackageRemappingExample")
14+
15+
val hints: Hints = Hints.empty
16+
17+
// constructor using the original order from the spec
18+
private def make(value: NestedString): PackageRemappingExample = PackageRemappingExample(value)
19+
20+
implicit val schema: Schema[PackageRemappingExample] = struct[PackageRemappingExample](
21+
NestedString.schema.required[PackageRemappingExample]("value", _.value),
22+
)(make).withId(id).addHints(hints)
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package smithy4s.example.packageremapping.nested
2+
3+
import smithy4s.Hints
4+
import smithy4s.Newtype
5+
import smithy4s.Schema
6+
import smithy4s.ShapeId
7+
import smithy4s.schema.Schema.bijection
8+
import smithy4s.schema.Schema.string
9+
10+
object NestedString extends Newtype[String] {
11+
val id: ShapeId = ShapeId("pkg.remapping.nested", "NestedString")
12+
val hints: Hints = Hints.empty
13+
val underlyingSchema: Schema[String] = string.withId(id).addHints(hints)
14+
implicit val schema: Schema[NestedString] = bijection(underlyingSchema, asBijection)
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package smithy4s.example.packageremapping
2+
3+
package object nested {
4+
5+
type NestedString = smithy4s.example.packageremapping.nested.NestedString.Type
6+
7+
}

modules/codegen-cli/src/smithy4s/codegen/cli/CodegenCommand.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ object CodegenCommand {
7979
Opts
8080
.option[List[String]](
8181
"allowed-ns",
82-
"Comma-delimited list of namespaces that should not be processed. If unset, all namespaces are processed (except stdlib ones)"
82+
"Comma-delimited list of namespaces that should not be processed. If unset, all namespaces are processed (except stdlib ones). DEPRECATED: use the `smithy4sCodegen` Smithy metadata key with `allowedNamespaces` instead."
8383
)
8484
.map(_.toSet)
8585
.orNone
@@ -88,7 +88,7 @@ object CodegenCommand {
8888
Opts
8989
.option[List[String]](
9090
"excluded-ns",
91-
"Comma-delimited list of namespaces that should not be processed. If unset, all namespaces are processed (except stdlib ones)"
91+
"Comma-delimited list of namespaces that should not be processed. If unset, all namespaces are processed (except stdlib ones). DEPRECATED: use the `smithy4sCodegen` Smithy metadata key with `excludedNamespaces` instead."
9292
)
9393
.map(_.toSet)
9494
.orNone
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
$version: "2.0"
2+
3+
metadata smithy4sCodegen = {
4+
packagePrefix: "gen"
5+
}
6+
7+
namespace com.example.first
8+
9+
string MyString
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2021-2026 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+
package example
18+
19+
import com.example.second.Second
20+
import gen.com.example.first.MyString
21+
22+
object BTest {
23+
def main(args: Array[String]): Unit = {
24+
println(Second(MyString("hello")))
25+
}
26+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
$version: "2.0"
2+
3+
namespace com.example.second
4+
5+
use com.example.first#MyString
6+
7+
structure Second {
8+
@required
9+
value: MyString
10+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
ThisBuild / scalaVersion := "2.13.18"
2+
3+
// Module A generates code for `com.example.first` under a custom package prefix
4+
// (`gen`). It carries a smithy4sGenerated manifest entry listing
5+
// the namespace as already-generated AND its `renderedPackages` mapping
6+
// (com.example.first -> gen.com.example.first), so downstream modules can both
7+
// skip regenerating that namespace and resolve cross-namespace references to
8+
// the right Scala package.
9+
lazy val a = (project in file("a"))
10+
.enablePlugins(Smithy4sCodegenPlugin)
11+
.settings(
12+
libraryDependencies += "com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion.value,
13+
TaskKey[Unit]("checkLayout") := {
14+
val src = (Compile / sourceManaged).value / "smithy4s"
15+
val prefixed = src / "gen" / "com" / "example" / "first" / "MyString.scala"
16+
val unprefixed = src / "com" / "example" / "first" / "MyString.scala"
17+
assert(
18+
prefixed.exists,
19+
s"Expected $prefixed to exist"
20+
)
21+
assert(
22+
!unprefixed.exists,
23+
s"Expected $unprefixed to be absent"
24+
)
25+
}
26+
)
27+
28+
// Module B references `com.example.first#MyString` from its own
29+
// `com.example.second` shapes. It must NOT regenerate `com.example.first`, and
30+
// the Scala code it generates for `Second` must import the upstream-rendered
31+
// `gen.com.example.first.MyString` (otherwise compilation would fail).
32+
lazy val b = (project in file("b"))
33+
.enablePlugins(Smithy4sCodegenPlugin)
34+
.dependsOn(a)
35+
.settings(
36+
TaskKey[Unit]("checkLayout") := {
37+
val src = (Compile / sourceManaged).value / "smithy4s"
38+
val ownNs = src / "com" / "example" / "second" / "Second.scala"
39+
val upstreamUnprefixed =
40+
src / "com" / "example" / "first" / "MyString.scala"
41+
val upstreamPrefixed =
42+
src / "gen" / "com" / "example" / "first" / "MyString.scala"
43+
assert(
44+
ownNs.exists,
45+
s"Expected $ownNs to exist"
46+
)
47+
assert(
48+
!upstreamUnprefixed.exists,
49+
s"Expected $upstreamUnprefixed to be absent (upstream namespace must not be regenerated)"
50+
)
51+
assert(
52+
!upstreamPrefixed.exists,
53+
s"Expected $upstreamPrefixed to be absent (upstream namespace must not be regenerated)"
54+
)
55+
}
56+
)

0 commit comments

Comments
 (0)