Add preliminary package structure and API (#3)

This commit is contained in:
Marcin Kostrzewa 2019-06-13 11:49:04 +02:00 committed by Ara Adkins
parent 6f84b8a772
commit c23209b078
5 changed files with 176 additions and 6 deletions

View File

@ -5,7 +5,8 @@ scalaVersion := "2.12.8"
lazy val Benchmark = config("bench") extend Test lazy val Benchmark = config("bench") extend Test
lazy val bench = taskKey[Unit]("Run Benchmarks") lazy val bench = taskKey[Unit]("Run Benchmarks")
lazy val enso = (project in file(".")).aggregate(syntax) lazy val enso = (project in file("."))
.aggregate(syntax, pkg)
lazy val syntax = (project in file("syntax")) lazy val syntax = (project in file("syntax"))
.configs(Benchmark) .configs(Benchmark)
@ -18,20 +19,28 @@ lazy val syntax = (project in file("syntax"))
publishArtifact := false, publishArtifact := false,
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"com.storm-enroute" %% "scalameter" % "0.17" % "bench", "com.storm-enroute" %% "scalameter" % "0.17" % "bench",
// "org.typelevel" %% "cats-core" % "1.6.0", "org.typelevel" %% "cats-core" % "1.6.0",
// "org.scalatest" %% "scalatest" % "3.0.5" % Test, "org.scalatest" %% "scalatest" % "3.0.5" % Test,
// "com.lihaoyi" %% "pprint" % "0.5.3" "com.lihaoyi" %% "pprint" % "0.5.3"
), ),
resolvers ++= Seq( resolvers ++= Seq(
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots", "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
"Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases" "Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases"
), ),
testFrameworks += new TestFramework("org.scalameter.ScalaMeterFramework"), testFrameworks += new TestFramework("org.scalameter.ScalaMeterFramework"),
parallelExecution in Benchmark := false, parallelExecution in Benchmark := false,
logBuffered := false logBuffered := false
) )
.settings(SbtJFlexPlugin.jflexSettings) .settings(SbtJFlexPlugin.jflexSettings)
.settings(mainClass in (Compile,run) := Some("org.enso.syntax.Main")) .settings(mainClass in (Compile, run) := Some("org.enso.syntax.Main"))
.settings(bench := { .settings(bench := {
(test in Benchmark).value (test in Benchmark).value
}) })
lazy val pkg = (project in file("pkg"))
.settings(
mainClass in (Compile, run) := Some("org.enso.pkg.Main"),
libraryDependencies ++= Seq("circe-core", "circe-generic", "circe-yaml")
.map("io.circe" %% _ % "0.10.0"),
libraryDependencies += "commons-io" % "commons-io" % "2.6"
)

View File

@ -0,0 +1,2 @@
def Main:
None

View File

@ -0,0 +1,28 @@
package org.enso.pkg
import java.io.File
import java.io.PrintWriter
import io.circe.yaml
import io.circe.generic.auto._
import io.circe.syntax._
import io.circe.yaml.syntax._
import scala.io.Source
import scala.util.Try
case class Config(
author: String,
maintainer: String,
name: String,
version: String,
license: String) {
def toYaml: String = this.asJson.asYaml.spaces4
}
object Config {
def fromYaml(yamlString: String): Option[Config] = {
yaml.parser.parse(yamlString).flatMap(_.as[Config]).toOption
}
}

View File

@ -0,0 +1,15 @@
package org.enso.pkg
import java.io.File
object Main extends App {
override def main(args: Array[String]): Unit = {
Package.getOrCreate(
new File("/Users/marcinkostrzewa/765Luna__$%%$#Project")
)
Package.getOrCreate(
new File("/Users/marcinkostrzewa/proper_%%$##%#project")
)
Package.getOrCreate(new File("/Users/marcinkostrzewa/Properproject"))
}
}

View File

@ -0,0 +1,116 @@
package org.enso.pkg
import java.io.File
import java.io.PrintWriter
import org.apache.commons.io.FileUtils
import scala.io.Source
import scala.util.Try
object CouldNotCreateDirectory extends Exception
case class Package(root: File, config: Config) {
val sourceDir = new File(root, Package.sourceDirName)
val configFile = new File(root, Package.configFileName)
val thumbFile = new File(root, Package.thumbFileName)
def save(): Unit = {
if (!root.exists) createDirectories()
if (!sourceDir.exists) createSourceDir()
saveConfig()
}
def createDirectories() {
val created = Try(root.mkdirs).getOrElse(false)
if (!created) throw CouldNotCreateDirectory
createSourceDir()
}
def rename(newName: String): Package = {
val newPkg = copy(config = config.copy(name = newName))
newPkg.save()
newPkg
}
def remove(): Unit = {
FileUtils.deleteDirectory(root)
}
def move(newRoot: File): Package = {
val newPkg = copyPackage(newRoot)
remove()
newPkg
}
def copyPackage(newRoot: File): Package = {
FileUtils.copyDirectory(root, newRoot)
copy(root = newRoot)
}
def createSourceDir(): Unit = {
if (!Try(sourceDir.mkdir).getOrElse(false)) throw CouldNotCreateDirectory
val lunaCodeSrc = Source.fromResource(Package.mainFileName)
val writer = new PrintWriter(new File(sourceDir, Package.mainFileName))
writer.write(lunaCodeSrc.mkString)
writer.close()
lunaCodeSrc.close()
}
def saveConfig(): Unit = {
val writer = new PrintWriter(configFile)
Try(writer.write(config.toYaml))
writer.close()
}
def hasThumb: Boolean = thumbFile.exists
def name: String = config.name
}
object Package {
val configFileName = "package.yaml"
val sourceDirName = "src"
val mainFileName = "Main.luna"
val thumbFileName = "thumb.png"
def create(root: File, config: Config): Package = {
val pkg = Package(root, config)
pkg.save()
pkg
}
def create(root: File, name: String): Package = {
val config = Config(
author = "",
maintainer = "",
name = name,
version = "",
license = ""
)
create(root, config)
}
def fromDirectory(root: File): Option[Package] = {
if (!root.exists()) return None
val configFile = new File(root, configFileName)
val source = Try(Source.fromFile(configFile))
val result = source.map(_.mkString).toOption.flatMap(Config.fromYaml)
source.foreach(_.close())
result.map(Package(root, _))
}
def getOrCreate(root: File): Package = {
val existing = fromDirectory(root)
existing.getOrElse(create(root, generateName(root)))
}
def generateName(file: File): String = {
val dirname = file.getName
val startingWithLetter =
if (!dirname(0).isLetter) "Project" ++ dirname else dirname
val startingWithUppercase = startingWithLetter.capitalize
val onlyAlphanumeric = startingWithUppercase.filter(_.isLetterOrDigit)
onlyAlphanumeric
}
}