Skip to content

Commit

Permalink
Rename ModuleRef to Target
Browse files Browse the repository at this point in the history
  • Loading branch information
propensive committed Mar 7, 2024
1 parent 13d97e4 commit 8341cbb
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 59 deletions.
3 changes: 2 additions & 1 deletion fury
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ repo propensive/anthology 0000000000000000000000000000000000000000
repo propensive/acyclicity 0000000000000000000000000000000000000000
repo propensive/superlunary 0000000000000000000000000000000000000000
repo propensive/hallucination 0000000000000000000000000000000000000000
repo propensive/zeppelin 0000000000000000000000000000000000000000

project fury
module model
Expand All @@ -29,7 +30,7 @@ project fury

module engine
compiler scala
include fury/model feudalism/core anthology/scala dendrology/dag
include fury/model feudalism/core anthology/scala dendrology/dag zeppelin/core
sources src/engine

module cli
Expand Down
4 changes: 2 additions & 2 deletions src/cli/actions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ object actions:
info(msg"Creating a new build in $directory")
ExitStatus.Ok

def run(ref: ModuleRef)
def run(target: Target)
(using FrontEnd,
WorkingDirectory,
Monitor,
Expand All @@ -171,7 +171,7 @@ object actions:
given universe: Universe = workspace.universe()

val builder = Builder()
val hash = builder.build(ref).await()
val hash = builder.build(target).await()
info(builder.buildGraph(hash))
builder.run(hash).await()
ExitStatus.Ok
Expand Down
10 changes: 5 additions & 5 deletions src/cli/cli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,15 @@ def main(): Unit =
given (UserError fixes ExecError) = accede

safely(internet(false)(Workspace().locals())).let: map =>
val refs = map.values.map(_.source).flatMap:
val targets = map.values.map(_.source).flatMap:
case workspace: Workspace => workspace.build.projects.flatMap: project =>
project.modules.map: module =>
ModuleRef(project.id, module.id)
Target(project.id, module.id)


target.let: target =>
if target().contains(t"/") then target.suggest(previous ++ refs.map(_.suggestion))
else target.suggest(previous ++ refs.map(_.partialSuggestion))
if target().contains(t"/") then target.suggest(previous ++ targets.map(_.suggestion))
else target.suggest(previous ++ targets.map(_.partialSuggestion))

execute:
given (UserError fixes InvalidRefError) = error => UserError(error.message)
Expand All @@ -195,7 +195,7 @@ def main(): Unit =
terminal:
frontEnd:
val buildAsync = async:
actions.build.run(target().decodeAs[ModuleRef])
actions.build.run(target().decodeAs[Target])

daemon:
terminal.events.each:
Expand Down
40 changes: 20 additions & 20 deletions src/engine/build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import serpentine.*, hierarchies.unixOrWindows
import spectacular.*
import turbulence.*
import vacuous.*
import zeppelin.*

import scala.collection.concurrent as scc

Expand All @@ -61,22 +62,23 @@ case class BuildError() extends Error(msg"the build could not run")

class Builder():
private val phases: scc.TrieMap[Hash, Phase] = scc.TrieMap()
private val builds: scc.TrieMap[ModuleRef, Async[Hash]] = scc.TrieMap()
private val builds: scc.TrieMap[Target, Async[Hash]] = scc.TrieMap()
private val tasks: scc.TrieMap[Hash, Async[Optional[Directory]]] = scc.TrieMap()

given expandable: Expandable[Phase] = _.dependencies.map(phases(_))

def buildGraph(digest: Hash): DagDiagram[Phase] =
DagDiagram(Dag.create(phases(digest))(_.dependencies.to(Set).map(phases(_))))

def build(moduleRef: ModuleRef)(using Universe)
def build(target: Target)(using Universe)
(using Monitor, Clock, Log[Display], WorkingDirectory, Internet, Installation, GitCommand)
: Async[Hash] raises BuildError =

builds.synchronized:
builds.getOrElseUpdate
(moduleRef,
(target,
async:
Log.info(msg"Starting computation of $moduleRef")
Log.info(msg"Starting computation of $target")

given (BuildError fixes GitError) = error => BuildError()
given (BuildError fixes ExecError) = error => BuildError()
Expand All @@ -87,29 +89,27 @@ class Builder():
given (BuildError fixes StreamError) = error => BuildError()
given (BuildError fixes CancelError) = error => BuildError()

val workspace = universe(moduleRef.projectId).source match
val workspace = universe(target.projectId).source match
case workspace: Workspace => workspace

case vault: Vault =>
Workspace(Cache(vault.index.releases(moduleRef.projectId).repo).await().path)
Workspace(Cache(vault.index.releases(target.projectId).repo).await().path)

val project: Project = workspace(moduleRef.projectId)
val module = project(moduleRef.moduleId)
val project: Project = workspace(target.projectId)
val module = project(target.moduleId)

val sourceFiles: List[File] = module.sources.flatMap: directory =>
workspace(directory).descendants.filter(_.is[File]).filter(_.name.ends(t".scala")).map(_.as[File])

val includes = module.includes.map(build(_)).map(_.await())
val classpath = includes.map(phases(_)).flatMap(_.runtimeClasspath).to(Set).to(List)
val phase = Phase(moduleRef, sourceFiles, includes, classpath, Nil)
val phase = Phase(target, sourceFiles, includes, classpath, Nil)

phases(phase.digest) = phase

Log.info(msg"Computed $moduleRef")
Log.info(msg"Computed $target")
phase.digest)

private val tasks: scc.TrieMap[Hash, Async[Optional[Directory]]] = scc.TrieMap()

def run(hash: Hash)(using Log[Display], Installation, FrontEnd, Monitor, SystemProperties)
: Async[Optional[Directory]] raises CancelError raises IoError raises PathError raises ScalacError =

Expand All @@ -128,7 +128,7 @@ class Builder():
else
if inputs.exists(_.absent) then abort(CancelError()) else
val additions = inputs.compact.map(_.path)
info(msg"Starting to build ${phase.ref} in ${hash.bytes.encodeAs[Base32]}")
info(msg"Starting to build ${phase.target} in ${hash.bytes.encodeAs[Base32]}")

val work = (installation.work / PathName(Uuid().show)).as[Directory]

Expand All @@ -154,7 +154,7 @@ class Builder():
val classpath2 = additions.foldLeft(classpath)(_ + _)
if phase.sources.isEmpty then output.as[Directory] else
val process: ScalacProcess =
Log.envelop(phase.ref):
Log.envelop(phase.target):
import scalacOptions.*
Scalac[3.4]
(List(language.experimental.fewerBraces,
Expand Down Expand Up @@ -183,7 +183,7 @@ class Builder():

async:
process.notices.each: notice =>
info(e"$Bold(${phase.ref})")
info(e"$Bold(${phase.target})")
info(e"${notice.importance}: $Italic(${notice.message})")
info(e"${colors.Silver}(${notice.code})")

Expand All @@ -192,7 +192,7 @@ class Builder():
val errorCount = process.notices.count(_.importance == Importance.Error)
val warnCount = process.notices.count(_.importance == Importance.Warning)

info(msg"Finished building ${phase.ref} with $errorCount errors and $warnCount warnings")
info(msg"Finished building ${phase.target} with $errorCount errors and $warnCount warnings")

if process.cancelled then Unset
else if errorCount == 0 then
Expand Down Expand Up @@ -265,7 +265,7 @@ enum Compiler:
case Kotlin => name.ends(t".kt")

object Phase:
def apply(ref: ModuleRef, sources: List[File], dependencies: List[Hash], classpath: List[Hash], binaries: List[Hash])(using Monitor)
def apply(target: Target, sources: List[File], dependencies: List[Hash], classpath: List[Hash], binaries: List[Hash])(using Monitor)
: Phase raises BuildError =

given (BuildError fixes CancelError) = error => BuildError()
Expand All @@ -274,10 +274,10 @@ object Phase:

val sourceMap = sources.map { file => file.path.name -> Cache.file(file.path).text.await() }.to(Map)

Phase(ref, sourceMap, dependencies, classpath, binaries)
Phase(target, sourceMap, dependencies, classpath, binaries)

given show: Show[Phase] = _.ref.show
given show: Show[Phase] = _.target.show

case class Phase(ref: ModuleRef, sources: Map[Text, Text], dependencies: List[Hash], classpath: List[Hash], binaries: List[Hash]):
case class Phase(target: Target, sources: Map[Text, Text], dependencies: List[Hash], classpath: List[Hash], binaries: List[Hash]):
lazy val digest = (sources.values.to(List), dependencies, binaries).digest[Sha2[256]]
def runtimeClasspath = digest :: classpath
19 changes: 13 additions & 6 deletions src/model/ids.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,18 @@ trait RefType(val name: Text)

object Ids:
opaque type EcosystemId = Text
opaque type StreamId = Text
opaque type ProjectId = Text
opaque type ModuleId = Text
opaque type StreamId = Text
opaque type ProjectId = Text
opaque type ModuleId = Text
opaque type ArtifactId = Text

@targetName("Pkg")
opaque type Package = Text

opaque type ClassName = Text
opaque type ClassName = Text
opaque type ActionName = Text
opaque type Keyword = Text
opaque type LicenseId = Text
opaque type Keyword = Text
opaque type LicenseId = Text

class Id[IdType]() extends RefType(t"ID"):
def apply(value: Text)(using Raises[InvalidRefError]): IdType = value match
Expand All @@ -68,6 +69,7 @@ object Ids:
object StreamId extends Id[StreamId]()
object ProjectId extends Id[ProjectId]()
object ModuleId extends Id[ModuleId]()
object ArtifactId extends Id[ArtifactId]()
object Keyword extends Id[Keyword]()
object ActionName extends Id[ActionName]()

Expand Down Expand Up @@ -155,3 +157,8 @@ object Ids:
given keywordEncoder: Encoder[Keyword] = identity(_)
given keywordDecoder(using Raises[InvalidRefError]): Decoder[Keyword] = Keyword(_)
given keywordDigestible: Digestible[Keyword] = (acc, keyword) => acc.append(keyword.bytes)

given artifactIdShow: Show[ArtifactId] = identity(_)
given artifactIdEncoder: Encoder[ArtifactId] = identity(_)
given artifactIdDecoder(using Raises[InvalidRefError]): Decoder[ArtifactId] = ArtifactId(_)
given artifactIdDigestible: Digestible[ArtifactId] = (acc, ecosystemId) => acc.append(ecosystemId.bytes)
58 changes: 33 additions & 25 deletions src/model/model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,17 @@ case class Prelude(terminator: Text, comment: List[Text]) derives Debug


object Project:
given relabelling: CodlRelabelling[Project] = () => Map(t"modules" -> t"module")
given relabelling: CodlRelabelling[Project] = () =>
Map
(t"modules" -> t"module",
t"artifacts" -> t"artifact")

case class Project
(id: ProjectId,
name: Text,
description: InlineMd,
modules: List[Module],
artifacts: List[Artifact],
website: HttpUrl,
license: Optional[LicenseId],
keywords: List[Keyword])
Expand All @@ -139,57 +143,61 @@ derives Debug:
def definition(workspace: Workspace): Definition =
Definition(name, description, website, license, keywords, workspace)

case class Assist(ref: ModuleRef, module: ModuleId) derives Debug
case class Assist(target: Target, module: ModuleId) derives Debug

object Artifact:
given relabelling: CodlRelabelling[Artifact] = () => Map(t"kind" -> t"type")

case class Artifact(id: ArtifactId, path: WorkPath) derives Debug

object Module:
given relabelling: CodlRelabelling[Module] = () =>
Map
(t"includes" -> t"include",
t"packages" -> t"provide",
t"requirements" -> t"require",
t"usages" -> t"use",
t"omissions" -> t"omit",
t"assists" -> t"assist")
(t"includes" -> t"include",
t"packages" -> t"provide",
t"requirements" -> t"require",
t"usages" -> t"use",
t"omissions" -> t"omit",
t"assists" -> t"assist")

case class Module
(id: ModuleId,
includes: List[ModuleRef],
requirements: List[ModuleRef],
includes: List[Target],
requirements: List[Target],
sources: List[WorkPath],
packages: List[Package],
usages: List[ModuleRef],
omissions: List[ModuleRef],
usages: List[Target],
omissions: List[Target],
assists: List[Assist],
compiler: Optional[Text],
main: Optional[ClassName],
coverage: Optional[ModuleRef])
coverage: Optional[Target])
derives Debug

object ModuleRef extends RefType(t"module ref"):
given moduleRefEncoder: Encoder[ModuleRef] = _.show
given moduleRefDebug: Debug[ModuleRef] = _.show
given moduleRefMessage: Communicable[ModuleRef] = ref => Message(ref.show)
given moduleRefDecoder(using Raises[InvalidRefError]): Decoder[ModuleRef] = ModuleRef(_)
object Target extends RefType(t"target"):
given moduleRefEncoder: Encoder[Target] = _.show
given moduleRefDebug: Debug[Target] = _.show
given moduleRefMessage: Communicable[Target] = target => Message(target.show)
given moduleRefDecoder(using Raises[InvalidRefError]): Decoder[Target] = Target(_)

given Show[ModuleRef] = ref =>
t"${ref.projectId.let { projectId => t"$projectId/" }.or(t"")}${ref.moduleId}"
given Show[Target] = target =>
t"${target.projectId.let { projectId => t"$projectId/" }.or(t"")}${target.moduleId}"

def apply(value: Text)(using Raises[InvalidRefError]): ModuleRef = value match
def apply(value: Text)(using Raises[InvalidRefError]): Target = value match
case r"${ProjectId(project)}([^/]+)\/${ModuleId(module)}([^/]+)" =>
ModuleRef(project, module)
Target(project, module)

case _ =>
raise(InvalidRefError(value, this))(ModuleRef(ProjectId(t"unknown"), ModuleId(t"unknown")))
raise(InvalidRefError(value, this))(Target(ProjectId(t"unknown"), ModuleId(t"unknown")))

case class ModuleRef(projectId: ProjectId, moduleId: ModuleId):
case class Target(projectId: ProjectId, moduleId: ModuleId):
def suggestion: Suggestion = Suggestion(this.show, Unset)
def partialSuggestion: Suggestion = Suggestion(t"${projectId}/", Unset, incomplete = true)

object Action:
given relabelling: CodlRelabelling[Action] = () => Map(t"actions" -> t"action")

case class Action(name: ActionName, modules: List[ModuleRef], description: Optional[Text])
case class Action(name: ActionName, modules: List[Target], description: Optional[Text])
derives Debug:
def suggestion: Suggestion = Suggestion(name.show, description.let { text => e"${colors.Khaki}($text)"} )

Expand Down

0 comments on commit 8341cbb

Please sign in to comment.