Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove optional ops from PlatformIO #1328

Merged
merged 3 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 20 additions & 28 deletions cli/src/main/scala/org/bykn/bosatsu/IOPlatformIO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,23 @@ object IOPlatformIO extends PlatformIO[IO, JPath] {
override def pathArg: Argument[Path] =
Argument.readPath

def resolve(base: JPath, p: List[String]): JPath =
p.foldLeft(base)(_.resolve(_))

override def moduleIOMonad: MonadError[IO, Throwable] =
cats.effect.IO.asyncForIO

def readPath(path: Path): IO[String] =
def readUtf8(path: Path): IO[String] =
IO.blocking(new String(java.nio.file.Files.readAllBytes(path), "utf-8"))

val resolvePath: Some[(Path, PackageName) => IO[Option[Path]]] =
Some(
{ (root: Path, pack: PackageName) =>
val dir = pack.parts.init.foldLeft(root)(_.resolve(_))
val filePath = dir.resolve(pack.parts.last + ".bosatsu")
IO.blocking {
// this is a side-effect since file is mutable
// and talks to the file system
val file = filePath.toFile
if (file.exists()) Some(filePath)
else None
}
def fsDataType(p: Path): IO[Option[PlatformIO.FSDataType]] =
IO.blocking {
val f = p.toFile()
if (f.exists()) Some {
if (f.isDirectory()) PlatformIO.FSDataType.Dir
else PlatformIO.FSDataType.File
}
)
else None
}

def resolve(p: Path, c: String): Path = p.resolve(c)

def read[A <: GeneratedMessage](
path: Path
Expand Down Expand Up @@ -106,18 +100,16 @@ object IOPlatformIO extends PlatformIO[IO, JPath] {
IO.fromTry(ProtoConverter.packagesToProto(packages))
.flatMap(write(_, path))

def unfoldDir: Option[Path => IO[Option[IO[List[Path]]]]] = Some {
(path: Path) =>
IO.blocking {
val f = path.toFile
def unfoldDir(path: Path): IO[Option[IO[List[Path]]]] =
IO.blocking {
val f = path.toFile

if (f.isDirectory()) {
Some(IO.blocking {
f.listFiles.iterator.map(_.toPath).toList
})
} else None
}
}
if (f.isDirectory()) {
Some(IO.blocking {
f.listFiles.iterator.map(_.toPath).toList
})
} else None
}

def hasExtension(str: String): Path => Boolean = { (path: Path) =>
path.toString.endsWith(str)
Expand Down
38 changes: 23 additions & 15 deletions cliJS/src/main/scala/org/bykn/bosatsu/Fs2PlatformIO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,21 @@ object Fs2PlatformIO extends PlatformIO[IO, Path] {

private val FilesIO = Files.forIO

def readPath(p: Path): IO[String] =
def readUtf8(p: Path): IO[String] =
FilesIO.readUtf8(p).compile.string

def fsDataType(p: Path): IO[Option[PlatformIO.FSDataType]] =
FilesIO.exists(p, followLinks = true)
.flatMap {
case false => IO.pure(None)
case true =>
FilesIO.isDirectory(p, followLinks = true)
.map {
case true => Some(PlatformIO.FSDataType.Dir)
case false => Some(PlatformIO.FSDataType.File)
}
}

def readPackages(paths: List[Path]): IO[List[Package.Typed[Unit]]] =
paths.parTraverse { path =>
for {
Expand Down Expand Up @@ -66,6 +78,8 @@ object Fs2PlatformIO extends PlatformIO[IO, Path] {
else None
}

def resolve(p: Path, c: String): Path = p.resolve(c)

/** Modules optionally have the capability to combine paths into a tree
*/
val resolvePath: Option[(Path, PackageName) => IO[Option[Path]]] = Some {
Expand All @@ -84,18 +98,15 @@ object Fs2PlatformIO extends PlatformIO[IO, Path] {
*
* if the given path is a directory, return Some and all the first children.
*/
def unfoldDir: Option[Path => IO[Option[IO[List[Path]]]]] = Some {
(path: Path) => {
FilesIO.isDirectory(path, followLinks = true)
.map {
case true => Some {
// create a list of children
FilesIO.list(path).compile.toList
}
case false => None
def unfoldDir(path: Path): IO[Option[IO[List[Path]]]] =
FilesIO.isDirectory(path, followLinks = true)
.map {
case true => Some {
// create a list of children
FilesIO.list(path).compile.toList
}
}
}
case false => None
}

def hasExtension(str: String): Path => Boolean =
{ (path: Path) => path.extName == str }
Expand All @@ -114,9 +125,6 @@ object Fs2PlatformIO extends PlatformIO[IO, Path] {
.compile
.drain

def resolve(base: Path, p: List[String]): Path =
p.foldLeft(base)(_.resolve(_))

// this is println actually
def print(str: String): IO[Unit] =
IO.println(str)
Expand Down
88 changes: 40 additions & 48 deletions core/src/main/scala/org/bykn/bosatsu/MainModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ abstract class MainModule[IO[_], Path](val platformIO: PlatformIO[IO, Path]) {
paths
.traverse { path =>
val defaultPack = packRes.packageNameFor(path)
readPath(path).map { str =>
readUtf8(path).map { str =>
parseStart(Package.headerParser(defaultPack), path, str)
.map { case (_, pp) => (path, pp) }
}
Expand Down Expand Up @@ -189,7 +189,7 @@ abstract class MainModule[IO[_], Path](val platformIO: PlatformIO[IO, Path]) {
packRes
.pathFor(search)
.flatMap(_.traverse { path =>
readPath(path).map((path, _))
readUtf8(path).map((path, _))
})
}

Expand Down Expand Up @@ -299,7 +299,7 @@ abstract class MainModule[IO[_], Path](val platformIO: PlatformIO[IO, Path]) {
p: P0[A],
path: Path
): IO[Either[Throwable, ValidatedNel[ParseError, (LocationMap, A)]]] =
readPath(path).attempt
readUtf8(path).attempt
.map(_.map(parseString(p, path, _)))

/** like typecheck, but a no-op for empty lists
Expand Down Expand Up @@ -520,7 +520,7 @@ abstract class MainModule[IO[_], Path](val platformIO: PlatformIO[IO, Path]) {
def read = moduleIOMonad.pure(asString)
}
case class FromPath(path: Path) extends JsonInput {
def read = readPath(path)
def read = readUtf8(path)
}
}

Expand Down Expand Up @@ -666,35 +666,31 @@ abstract class MainModule[IO[_], Path](val platformIO: PlatformIO[IO, Path]) {
.orEmpty
.map(paths => paths.foldMap(PathGen.Direct[IO, Path](_): PathGen))

unfoldDir match {
case None => direct
case Some(unfold) =>
val select = hasExtension(ext)
val child1 = Opts
.options[Path](arg + "_dir", help = s"all $help in directory")
.orEmpty
.map { paths =>
paths.foldMap(
PathGen
.ChildrenOfDir[IO, Path](_, select, false, unfold): PathGen
)
}
val childMany = Opts
.options[Path](
arg + "_all_subdir",
help = s"all $help recursively in all directories"
)
.orEmpty
.map { paths =>
paths.foldMap(
PathGen
.ChildrenOfDir[IO, Path](_, select, true, unfold): PathGen
)
}
val select = hasExtension(ext)
val child1 = Opts
.options[Path](arg + "_dir", help = s"all $help in directory")
.orEmpty
.map { paths =>
paths.foldMap(
PathGen
.ChildrenOfDir[IO, Path](_, select, false, unfoldDir(_)): PathGen
)
}
val childMany = Opts
.options[Path](
arg + "_all_subdir",
help = s"all $help recursively in all directories"
)
.orEmpty
.map { paths =>
paths.foldMap(
PathGen
.ChildrenOfDir[IO, Path](_, select, true, unfoldDir(_)): PathGen
)
}

(direct, child1, childMany).mapN { (a, b, c) =>
(a :: b :: c :: Nil).combineAll
}
(direct, child1, childMany).mapN { (a, b, c) =>
(a :: b :: c :: Nil).combineAll
}
}
private val srcs =
Expand All @@ -712,21 +708,17 @@ abstract class MainModule[IO[_], Path](val platformIO: PlatformIO[IO, Path]) {
help = "for implicit package names, consider these paths as roots"
)
private val packSearch =
resolvePath match {
case None => Opts(None)
case some @ Some(_) =>
Opts
.flag(
"search",
help =
"if set, we search the package_roots for imports not explicitly given"
)
.orFalse
.map {
case true => some
case false => None
}
}
Opts
.flag(
"search",
help =
"if set, we search the package_roots for imports not explicitly given"
)
.orFalse
.map {
case true => Some((p, pn) => resolveFile(p, pn))
case false => None
}

private val packRes: Opts[PackageResolver] =
(packRoot
Expand Down Expand Up @@ -774,7 +766,7 @@ abstract class MainModule[IO[_], Path](val platformIO: PlatformIO[IO, Path]) {
for {
pn <- inputs.packMap(this, Nil, errColor)
(packs, names) = pn
optString <- generator.traverse(readPath)
optString <- generator.traverse(readUtf8)
dataTry = optString.transpiler.renderAll(packs, optString.args)
data <- moduleIOMonad.fromTry(dataTry)
} yield Output.TranspileOut(data, outDir)
Expand Down
Loading
Loading