smithy4s.codegen.internals.SmithyResources.scala Maven / Gradle / Ivy
/*
* Copyright 2021-2024 Disney Streaming
*
* Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://disneystreaming.github.io/TOST-1.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package smithy4s.codegen.internals
import os.RelPath
import smithy4s.codegen.BuildInfo
import smithy4s.codegen.CodegenEntry
/**
* This construct aims at adding metadata information to the classpath to let Smithy4s
* know about code that may have been generated in upstream modules.
*
* A "smithy4sGenerated" metadata holds a list of all namespaces that will have already
* been generated by smithy4s.
*/
private[smithy4s] object SmithyResources {
def produce(
resourceOutputFolder: os.Path,
specs: List[os.Path],
namespaces: List[String]
): List[CodegenEntry] = {
val localSmithyFiles = specs.flatMap { spec =>
if (os.isDir(spec))
os.walk(spec).filter(f => Set("smithy", "json").contains(f.ext))
else if (Set("smithy", "json").contains(spec.ext)) List(spec)
else Nil
}
val smithyFolder = resourceOutputFolder / "META-INF" / "smithy"
val trackingFile = smithyFolder / s"smithy4s.tracking.smithy"
val smithy4sVersion = BuildInfo.version
val nsString = namespaces.map(ns => s""""$ns"""").mkString(", ")
val content = s"""|$$version: "2.0"
|
|metadata smithy4sGenerated = [{smithy4sVersion: "$smithy4sVersion", namespaces: [$nsString]}]
|""".stripMargin
val trackingFileEntry = CodegenEntry.FromMemory(trackingFile, content)
val metadataFile = smithyFolder / "manifest"
val metadataFileRelPaths =
(trackingFile :: localSmithyFiles).flatMap {
case f if os.isDir(f) =>
os.walk(f).filter(os.isFile(_)).map(_.relativeTo(f))
case f => RelPath(f.last) :: Nil
}.distinct
val metadataFileEntry = CodegenEntry.FromMemory(
metadataFile,
metadataFileRelPaths.mkString(System.lineSeparator())
)
val localSmithyFilesEntries = localSmithyFiles
.map { path =>
CodegenEntry.FromDisk(smithyFolder / path.last, path)
}
localSmithyFilesEntries :+ metadataFileEntry :+ trackingFileEntry
}
}