Skip to content

Commit

Permalink
Add preliminary package structure and API (enso-org#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
kustosz authored and iamrecursion committed Jun 13, 2019
1 parent 6f84b8a commit c23209b
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 6 deletions.
21 changes: 15 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ scalaVersion := "2.12.8"
lazy val Benchmark = config("bench") extend Test
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"))
.configs(Benchmark)
Expand All @@ -18,20 +19,28 @@ lazy val syntax = (project in file("syntax"))
publishArtifact := false,
libraryDependencies ++= Seq(
"com.storm-enroute" %% "scalameter" % "0.17" % "bench",
// "org.typelevel" %% "cats-core" % "1.6.0",
// "org.scalatest" %% "scalatest" % "3.0.5" % Test,
// "com.lihaoyi" %% "pprint" % "0.5.3"
"org.typelevel" %% "cats-core" % "1.6.0",
"org.scalatest" %% "scalatest" % "3.0.5" % Test,
"com.lihaoyi" %% "pprint" % "0.5.3"
),
resolvers ++= Seq(
"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"),
parallelExecution in Benchmark := false,
logBuffered := false
)
.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 := {
(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"
)
2 changes: 2 additions & 0 deletions pkg/src/main/resources/Main.luna
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def Main:
None
28 changes: 28 additions & 0 deletions pkg/src/main/scala/org/enso/pkg/Config.scala
Original file line number Diff line number Diff line change
@@ -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
}

}
15 changes: 15 additions & 0 deletions pkg/src/main/scala/org/enso/pkg/Main.scala
Original file line number Diff line number Diff line change
@@ -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"))
}
}
116 changes: 116 additions & 0 deletions pkg/src/main/scala/org/enso/pkg/Package.scala
Original file line number Diff line number Diff line change
@@ -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
}
}

0 comments on commit c23209b

Please sign in to comment.