Skip to content

Commit c23209b

Browse files
kustosziamrecursion
authored andcommitted
Add preliminary package structure and API (enso-org#3)
1 parent 6f84b8a commit c23209b

File tree

5 files changed

+176
-6
lines changed

5 files changed

+176
-6
lines changed

build.sbt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ scalaVersion := "2.12.8"
55
lazy val Benchmark = config("bench") extend Test
66
lazy val bench = taskKey[Unit]("Run Benchmarks")
77

8-
lazy val enso = (project in file(".")).aggregate(syntax)
8+
lazy val enso = (project in file("."))
9+
.aggregate(syntax, pkg)
910

1011
lazy val syntax = (project in file("syntax"))
1112
.configs(Benchmark)
@@ -18,20 +19,28 @@ lazy val syntax = (project in file("syntax"))
1819
publishArtifact := false,
1920
libraryDependencies ++= Seq(
2021
"com.storm-enroute" %% "scalameter" % "0.17" % "bench",
21-
// "org.typelevel" %% "cats-core" % "1.6.0",
22-
// "org.scalatest" %% "scalatest" % "3.0.5" % Test,
23-
// "com.lihaoyi" %% "pprint" % "0.5.3"
22+
"org.typelevel" %% "cats-core" % "1.6.0",
23+
"org.scalatest" %% "scalatest" % "3.0.5" % Test,
24+
"com.lihaoyi" %% "pprint" % "0.5.3"
2425
),
2526
resolvers ++= Seq(
2627
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
27-
"Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases"
28+
"Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases"
2829
),
2930
testFrameworks += new TestFramework("org.scalameter.ScalaMeterFramework"),
3031
parallelExecution in Benchmark := false,
3132
logBuffered := false
3233
)
3334
.settings(SbtJFlexPlugin.jflexSettings)
34-
.settings(mainClass in (Compile,run) := Some("org.enso.syntax.Main"))
35+
.settings(mainClass in (Compile, run) := Some("org.enso.syntax.Main"))
3536
.settings(bench := {
3637
(test in Benchmark).value
3738
})
39+
40+
lazy val pkg = (project in file("pkg"))
41+
.settings(
42+
mainClass in (Compile, run) := Some("org.enso.pkg.Main"),
43+
libraryDependencies ++= Seq("circe-core", "circe-generic", "circe-yaml")
44+
.map("io.circe" %% _ % "0.10.0"),
45+
libraryDependencies += "commons-io" % "commons-io" % "2.6"
46+
)

pkg/src/main/resources/Main.luna

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def Main:
2+
None
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.enso.pkg
2+
3+
import java.io.File
4+
import java.io.PrintWriter
5+
6+
import io.circe.yaml
7+
import io.circe.generic.auto._
8+
import io.circe.syntax._
9+
import io.circe.yaml.syntax._
10+
11+
import scala.io.Source
12+
import scala.util.Try
13+
14+
case class Config(
15+
author: String,
16+
maintainer: String,
17+
name: String,
18+
version: String,
19+
license: String) {
20+
def toYaml: String = this.asJson.asYaml.spaces4
21+
}
22+
23+
object Config {
24+
def fromYaml(yamlString: String): Option[Config] = {
25+
yaml.parser.parse(yamlString).flatMap(_.as[Config]).toOption
26+
}
27+
28+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.enso.pkg
2+
3+
import java.io.File
4+
5+
object Main extends App {
6+
override def main(args: Array[String]): Unit = {
7+
Package.getOrCreate(
8+
new File("/Users/marcinkostrzewa/765Luna__$%%$#Project")
9+
)
10+
Package.getOrCreate(
11+
new File("/Users/marcinkostrzewa/proper_%%$##%#project")
12+
)
13+
Package.getOrCreate(new File("/Users/marcinkostrzewa/Properproject"))
14+
}
15+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package org.enso.pkg
2+
3+
import java.io.File
4+
import java.io.PrintWriter
5+
6+
import org.apache.commons.io.FileUtils
7+
8+
import scala.io.Source
9+
import scala.util.Try
10+
11+
object CouldNotCreateDirectory extends Exception
12+
13+
case class Package(root: File, config: Config) {
14+
15+
val sourceDir = new File(root, Package.sourceDirName)
16+
val configFile = new File(root, Package.configFileName)
17+
val thumbFile = new File(root, Package.thumbFileName)
18+
19+
def save(): Unit = {
20+
if (!root.exists) createDirectories()
21+
if (!sourceDir.exists) createSourceDir()
22+
saveConfig()
23+
}
24+
25+
def createDirectories() {
26+
val created = Try(root.mkdirs).getOrElse(false)
27+
if (!created) throw CouldNotCreateDirectory
28+
createSourceDir()
29+
}
30+
31+
def rename(newName: String): Package = {
32+
val newPkg = copy(config = config.copy(name = newName))
33+
newPkg.save()
34+
newPkg
35+
}
36+
37+
def remove(): Unit = {
38+
FileUtils.deleteDirectory(root)
39+
}
40+
41+
def move(newRoot: File): Package = {
42+
val newPkg = copyPackage(newRoot)
43+
remove()
44+
newPkg
45+
}
46+
47+
def copyPackage(newRoot: File): Package = {
48+
FileUtils.copyDirectory(root, newRoot)
49+
copy(root = newRoot)
50+
}
51+
52+
def createSourceDir(): Unit = {
53+
if (!Try(sourceDir.mkdir).getOrElse(false)) throw CouldNotCreateDirectory
54+
val lunaCodeSrc = Source.fromResource(Package.mainFileName)
55+
val writer = new PrintWriter(new File(sourceDir, Package.mainFileName))
56+
writer.write(lunaCodeSrc.mkString)
57+
writer.close()
58+
lunaCodeSrc.close()
59+
}
60+
61+
def saveConfig(): Unit = {
62+
val writer = new PrintWriter(configFile)
63+
Try(writer.write(config.toYaml))
64+
writer.close()
65+
}
66+
67+
def hasThumb: Boolean = thumbFile.exists
68+
def name: String = config.name
69+
}
70+
71+
object Package {
72+
val configFileName = "package.yaml"
73+
val sourceDirName = "src"
74+
val mainFileName = "Main.luna"
75+
val thumbFileName = "thumb.png"
76+
77+
def create(root: File, config: Config): Package = {
78+
val pkg = Package(root, config)
79+
pkg.save()
80+
pkg
81+
}
82+
83+
def create(root: File, name: String): Package = {
84+
val config = Config(
85+
author = "",
86+
maintainer = "",
87+
name = name,
88+
version = "",
89+
license = ""
90+
)
91+
create(root, config)
92+
}
93+
94+
def fromDirectory(root: File): Option[Package] = {
95+
if (!root.exists()) return None
96+
val configFile = new File(root, configFileName)
97+
val source = Try(Source.fromFile(configFile))
98+
val result = source.map(_.mkString).toOption.flatMap(Config.fromYaml)
99+
source.foreach(_.close())
100+
result.map(Package(root, _))
101+
}
102+
103+
def getOrCreate(root: File): Package = {
104+
val existing = fromDirectory(root)
105+
existing.getOrElse(create(root, generateName(root)))
106+
}
107+
108+
def generateName(file: File): String = {
109+
val dirname = file.getName
110+
val startingWithLetter =
111+
if (!dirname(0).isLetter) "Project" ++ dirname else dirname
112+
val startingWithUppercase = startingWithLetter.capitalize
113+
val onlyAlphanumeric = startingWithUppercase.filter(_.isLetterOrDigit)
114+
onlyAlphanumeric
115+
}
116+
}

0 commit comments

Comments
 (0)