-
Notifications
You must be signed in to change notification settings - Fork 4
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
GSoC Rough plan #62
Comments
Something that might end up in that interoperability ticket is mimicking this: // Find and concatenate all .txt files directly in the working directory using `cat`
os.proc("cat", os.list(wd).filter(_.ext == "txt")).call(stdout = wd / "all.txt")
os.read(wd / "all.txt") ==>
"""I am cowI am cow
|Hear me moo
|I weigh twice as much as you
|And I look good on the barbecue""".stripMargin more or less in this way: for {
textFiles <- wd.listAll.filter(_.ext == "txt")
stdout <- Process.run("cat", textFiles).stdout
_ <- (wd / "all.txt").writeUtf8(stdout)
output <- (wd / "all.txt").readUtf8
} yield output |
Adding another (completely insane) suggestion here. That's what I currently use locally to auto-commit my dotfiles each time a file gets changed (the "watching" functionality is implemented calling this via a launchd macos daemon btw). Ideally (IMHO), with this lib, it should be possible to rewrite it all in 10/15 lines top. //> using scala 3.4.0
//> using platform native
//> using nativeGc none
//> using nativeMode release-full
//> using toolkit typelevel::latest
//> using dep org.typelevel::cats-time::0.5.1
//> using packaging.output dotfiles-watcher
import cats.effect.*
import cats.syntax.all.*
import org.typelevel.cats.time._
import fs2.io.file.*
import fs2.io.process.*
object Main extends IOApp:
def run(args: List[String]): IO[ExitCode] =
git(args.head)("status","--porcelain")
.map(_.isEmpty).ifM(IO.unit, logic(args.head)).as(ExitCode.Success)
.recoverWith {
case ExitException(code, message) => reportToDesktop(code, message)
case t: Throwable => reportToDesktop(1, t.getMessage)
}
def logic(folder: String): IO[Unit] = for {
prevProfile <- ghProfile("show").map(_.trim)
_ <- ghProfile("switch", "personal")
_ <- git(folder)("add", ".")
date <- IO.realTimeInstant.map(_.show)
_ <- git(folder)("-c", "commit.gpgsign=false", "commit", "-m", date)
_ <- git(folder)("push")
_ <- ghProfile("switch", prevProfile)
} yield ()
def ghProfile(command: String*) =
run("/opt/homebrew/bin/gh", ("profile" +: command)*)
def git(folder: String)(command: String*) =
run("/usr/bin/git", ("-C" +: folder +: command)*)
def reportToDesktop(exitCode:Int, message: String): IO[ExitCode] =
fs2.Stream.emit(message).through(
Files[IO].writeUtf8(Path("/Users/toniogela/Desktop/dotfiles_watcher_log"))
).compile.drain.as(ExitCode(exitCode))
def run(command: String, args:String*): IO[String] =
ProcessBuilder(command, args.toList).spawn[IO].use(p =>
(
p.exitValue,
p.stdout.through(fs2.text.utf8.decode).compile.string,
p.stderr.through(fs2.text.utf8.decode).compile.string
).parFlatMapN {
case (0, stdout, stdErr) => IO(stdout)
case (exitCode, stdout, stdErr) =>
val errorMessage: String = List(
Option(stdout).filter(_.nonEmpty).map(s => s"[STDOUT]: $s"),
Option(stdErr).filter(_.nonEmpty).map(s => s"[STDERR]: $s")
).foldLeft(
s"Non zero exit code ($exitCode) for `$command ${args.mkString(" ")}`"
) {
case (summary, Some(err)) => s"$summary\n$err"
case (summary, None) => summary
}
IO.raiseError(new ExitException(exitCode, errorMessage))
}
)
case class ExitException(exitCode:Int, message:String) extends Throwable |
Should we implement the library abstract on |
I just wanted to let you know I haven't answered you here because I did in person. This library aims to make the learning curve less steep and to make life easier for people who want to manipulate files and run external processes, w/o having to worry about tagless final or |
As discussed with Gabriel, Rishad, Micheal and Than, we will probably organise this work by roughly splitting it into three big chunks:
Files
operations #63The idea is to begin importing what's present in the fs2-io's
Files
type class first, then in theProcess
one, and re-expose the stricter version of their methods.I'll begin opening a specific issue to track the progress and ideas about
Files,
and I'll link it here.The text was updated successfully, but these errors were encountered: