Skip to content

Commit

Permalink
introduce PathRef for hashed directories
Browse files Browse the repository at this point in the history
  • Loading branch information
majk-p committed Apr 23, 2024
1 parent 70ebc75 commit 45f8628
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import smithy4s.codegen.CodegenArgs
import smithy4s.codegen.FileType

import Options._
import smithy4s.codegen.PathRef

object CodegenCommand {

Expand Down Expand Up @@ -116,7 +117,7 @@ object CodegenCommand {
defaultDependencies ++ dependencies.getOrElse(List.empty)
}
CodegenArgs(
specsArgs,
specsArgs.map(PathRef(_)),
output.getOrElse(os.pwd),
resourseOutput.getOrElse(os.pwd),
skip,
Expand All @@ -126,7 +127,7 @@ object CodegenCommand {
repositories.getOrElse(List.empty),
dependenciesWithDefaults,
transformers.getOrElse(List.empty),
localJars.getOrElse(List.empty)
localJars.getOrElse(List.empty).map(PathRef(_))
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import smithy4s.codegen.FileType
import weaver._

import Defaults.defaultDependencies
import smithy4s.codegen.PathRef

object CommandParsingSpec extends FunSuite {

Expand Down Expand Up @@ -81,7 +82,7 @@ object CommandParsingSpec extends FunSuite {
specs = List(
os.pwd / "sampleSpecs" / "pizza.smithy",
os.pwd / "sampleSpecs" / "example.smithy"
),
).map(PathRef(_)),
output = os.pwd / "target",
resourceOutput = os.pwd / "target" / "openapi",
skip = Set(FileType.Openapi, FileType.Scala),
Expand All @@ -94,7 +95,7 @@ object CommandParsingSpec extends FunSuite {
localJars = List(
os.pwd / "lib1.jar",
os.pwd / "lib2.jar"
)
).map(PathRef(_))
)
)
)
Expand Down
28 changes: 17 additions & 11 deletions modules/codegen-plugin/src/smithy4s/codegen/JsonConverters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,30 @@ private[smithy4s] object JsonConverters {
// This serialises a path by providing a hash of the content it points to.
// Because the hash is part of the Json, this allows SBT to detect when a file
// changes and invalidate its relevant caches, leading to a call to Smithy4s' code generator.
implicit val pathFormat: JsonFormat[os.Path] =
BasicJsonProtocol.projectFormat[os.Path, HashFileInfo](
implicit val pathRefFormat: JsonFormat[PathRef] =
BasicJsonProtocol.projectFormat[PathRef, HashFileInfo](
p => {
if (os.isFile(p)) FileInfo.hash(p.toIO)
if (os.isFile(p.underlying)) FileInfo.hash(p.underlying.toIO)
else
// If the path is a directory, we get the hashes of all files
// then hash the concatenation of the hash's bytes.
FileInfo.hash(
p.toIO,
p.underlying.toIO,
Hash(
os.walk(p)
os.walk(p.underlying)
.map(_.toIO)
.map(Hash(_))
.foldLeft(Array.emptyByteArray)(_ ++ _)
)
)
},
hash => os.Path(hash.file)
hash => PathRef(os.Path(hash.file))
)

implicit val pathFormat: JsonFormat[os.Path] =
BasicJsonProtocol.projectFormat[os.Path, String](
p => p.toString,
str => os.Path(str)
)

implicit val fileTypeFormat: JsonFormat[FileType] =
Expand All @@ -61,7 +67,7 @@ private[smithy4s] object JsonConverters {
)

// format: off
type GenTarget = List[os.Path] :*: String :*: String :*: Set[FileType] :*: Boolean:*: Option[Set[String]] :*: Option[Set[String]] :*: List[String] :*: List[String] :*: List[String] :*: List[os.Path] :*: LNil
type GenTarget = List[PathRef] :*: os.Path :*: os.Path :*: Set[FileType] :*: Boolean:*: Option[Set[String]] :*: Option[Set[String]] :*: List[String] :*: List[String] :*: List[String] :*: List[PathRef] :*: LNil
// format: on

// `output` and `resourceOutput` are intentionally serialized as strings
Expand All @@ -70,8 +76,8 @@ private[smithy4s] object JsonConverters {
implicit val codegenArgsIso = LList.iso[CodegenArgs, GenTarget](
{ ca: CodegenArgs =>
("specs", ca.specs) :*:
("output", ca.output.toString) :*:
("resourceOutput", ca.resourceOutput.toString) :*:
("output", ca.output) :*:
("resourceOutput", ca.resourceOutput) :*:
("skip", ca.skip) :*:
("discoverModels", ca.discoverModels) :*:
("allowedNS", ca.allowedNS) :*:
Expand All @@ -96,8 +102,8 @@ private[smithy4s] object JsonConverters {
(_, localJars) :*: LNil =>
CodegenArgs(
specs,
os.Path(output),
os.Path(resourceOutput),
output,
resourceOutput,
skip,
discoverModels,
allowedNS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,21 +410,23 @@ object Smithy4sCodegenPlugin extends AutoPlugin {
val excludedNamespaces =
(conf / smithy4sExcludedNamespaces).?.value.map(_.toSet)
val localJars =
(conf / smithy4sAllDependenciesAsJars).value.map(os.Path(_)).toList
(conf / smithy4sAllDependenciesAsJars).value.toList.sorted
.map(p => PathRef(os.Path(p)))
val res =
(conf / resolvers).value.toList.collect { case m: MavenRepository =>
m.root
}
val transforms = (conf / smithy4sModelTransformers).value
val transforms = (conf / smithy4sModelTransformers).value.sorted
val s = (conf / streams).value
val skipResources: Set[FileType] =
if ((conf / smithy4sSmithyLibrary).value) Set.empty
else Set(FileType.Resource)
val skipSet = skipResources

val filePaths = inputFiles.map(_.getAbsolutePath())
val specs = filePaths.sorted.map(p => PathRef(os.Path(p))).toList
val codegenArgs = CodegenArgs(
filePaths.sorted.map(os.Path(_)).toList,
specs,
output = os.Path(outputPath),
resourceOutput = os.Path(resourceOutputPath),
skip = skipSet,
Expand All @@ -433,8 +435,8 @@ object Smithy4sCodegenPlugin extends AutoPlugin {
excludedNS = excludedNamespaces,
repositories = res,
dependencies = List.empty,
transformers = transforms.sorted,
localJars = localJars.sorted
transformers = transforms,
localJars = localJars
)

val cached =
Expand Down
5 changes: 3 additions & 2 deletions modules/codegen/src/smithy4s/codegen/CodegenArgs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import cats.data.ValidatedNel
import cats.syntax.all._

final case class CodegenArgs(
specs: List[os.Path],
specs: List[PathRef],
output: os.Path,
resourceOutput: os.Path,
skip: Set[FileType],
Expand All @@ -30,12 +30,13 @@ final case class CodegenArgs(
repositories: List[String],
dependencies: List[String],
transformers: List[String],
localJars: List[os.Path]
localJars: List[PathRef]
) {
def skipScala: Boolean = skip(FileType.Scala)
def skipOpenapi: Boolean = skip(FileType.Openapi)
def skipResources: Boolean = skip(FileType.Resource)
def skipProto: Boolean = skip(FileType.Proto)

}

sealed abstract class FileType(val name: String)
Expand Down
3 changes: 3 additions & 0 deletions modules/codegen/src/smithy4s/codegen/PathRef.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package smithy4s.codegen

final case class PathRef(underlying: os.Path)
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ private[codegen] object CodegenImpl { self =>

def generate(args: CodegenArgs): CodegenResult = {
val (classloader, model): (ClassLoader, Model) = internals.ModelLoader.load(
args.specs.map(_.toIO).toSet,
args.specs.map(_.underlying.toIO).toSet,
args.dependencies,
args.repositories,
withBuiltinTransformers(args.transformers),
args.discoverModels,
args.localJars
args.localJars.map(_.underlying)
)

val (scalaFiles, smithyResources) = if (!args.skipScala) {
Expand All @@ -56,7 +56,7 @@ private[codegen] object CodegenImpl { self =>
val resources = if (!skipResource) {
SmithyResources.produce(
args.resourceOutput,
args.specs,
args.specs.map(_.underlying),
generatedNamespaces
)
} else List.empty[CodegenEntry]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import mill.api.JarManifest
import mill.scalalib.CrossVersion.Binary
import mill.scalalib.CrossVersion.Constant
import mill.scalalib.CrossVersion.Full
import smithy4s.codegen

trait Smithy4sModule extends ScalaModule {

Expand Down Expand Up @@ -190,6 +191,8 @@ trait Smithy4sModule extends ScalaModule {
val specFiles = (smithy4sGeneratedSmithyFiles() ++ smithy4sInputDirs())
.map(_.path)
.filter(os.exists(_))
.toList
.map(codegen.PathRef(_))

val scalaOutput = smithy4sOutputDir().path
val resourcesOutput = smithy4sResourceOutputDir().path
Expand All @@ -205,10 +208,14 @@ trait Smithy4sModule extends ScalaModule {
val skipSet = skipResources ++ skipOpenApi

val allLocalJars =
smithy4sAllDependenciesAsJars().map(_.path).iterator.to(List)
smithy4sAllDependenciesAsJars()
.map(_.path)
.iterator
.to(List)
.map(codegen.PathRef(_))

val args = CodegenArgs(
specs = specFiles.toList,
specs = specFiles,
output = scalaOutput,
resourceOutput = resourcesOutput,
skip = skipSet,
Expand Down

0 comments on commit 45f8628

Please sign in to comment.