From c1c1aa832c09dda3e455eb15ed71aeedcff86cbb Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Tue, 6 Mar 2018 18:41:48 -0500 Subject: [PATCH 01/10] Updated Exclude Code w/Tests --- .../sourcegear/project/OpticProject.scala | 11 +++--- .../project/config/ProjectFile.scala | 6 ++-- .../project/config/ProjectFileInterface.scala | 10 +++--- .../project/monitoring/ShouldWatch.scala | 26 ++++++++++++++ .../sourcegear/project/ProjectFileSpec.scala | 8 ++--- .../project/monitoring/ShouldWatchSpec.scala | 36 +++++++++++++++++++ .../example_project_files/empty.yaml | 2 +- .../example_project_files/project.yaml | 2 +- .../example_project_files/project2.yaml | 2 +- .../example_project_files/project3.yaml | 2 +- .../example_project_files/project4.yaml | 2 +- .../resources/example_source/optic.yaml | 2 +- 12 files changed, 85 insertions(+), 24 deletions(-) create mode 100644 core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatch.scala create mode 100644 core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatchSpec.scala diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala index 4cf55c2225..d3c55ec3e6 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala @@ -13,7 +13,7 @@ import com.opticdev.core.sourcegear.SourceGear import com.opticdev.core.sourcegear.actors.ActorCluster import com.opticdev.core.sourcegear.graph.{ProjectGraph, ProjectGraphWrapper} import com.opticdev.core.sourcegear.project.config.ProjectFile -import com.opticdev.core.sourcegear.project.monitoring.{FileStateMonitor} +import com.opticdev.core.sourcegear.project.monitoring.{FileStateMonitor, ShouldWatch} import com.opticdev.core.sourcegear.project.status.ProjectStatus import com.opticdev.opm.providers.ProjectKnowledgeSearchPaths import net.jcazevedo.moultingyaml.YamlString @@ -132,11 +132,10 @@ abstract class OpticProject(val name: String, val baseDirectory: File)(implicit /* Control logic for watching files */ - def shouldWatchFile(file: File) : Boolean = { - file.isRegularFile && - file.extension.isDefined && - projectSourcegear.validExtensions.contains(file.extension.get) - } + def shouldWatchFile(file: File) : Boolean = + ShouldWatch.file(file, + projectSourcegear.validExtensions, + projectFile.interface.get.exclude.value.map(i=> File(i.value))) def filesToWatch : Set[File] = baseDirectory.listRecursively.toVector.filter(shouldWatchFile).toSet } diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFile.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFile.scala index e76be93703..affba413b4 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFile.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFile.scala @@ -46,11 +46,11 @@ class ProjectFile(val file: File, createIfDoesNotExist : Boolean = true, onChang val knowledgePaths =PFListInterface.forKey[YamlString]("knowledge_paths", YamlArray(Vector()), yaml) - val ignored_files =PFListInterface.forKey[YamlString]("ignored_files", YamlArray(Vector()), yaml) + val exclude =PFListInterface.forKey[YamlString]("exclude", YamlArray(Vector()), yaml) lastHash = Crypto.createSha1(contents) // val relationships =PFListInterface.forKey[YamlString]("relationships", YamlArray(Vector()), yaml) - PFRootInterface(name, parsers, knowledge, knowledgePaths, ignored_files) + PFRootInterface(name, parsers, knowledge, knowledgePaths, exclude) } def interface = interfaceStore @@ -74,7 +74,7 @@ class ProjectFile(val file: File, createIfDoesNotExist : Boolean = true, onChang YamlString("parsers") -> interface.get.parsers.yamlValue, YamlString("knowledge") -> interface.get.knowledge.yamlValue, YamlString("knowledge_paths") -> interface.get.knowledgePaths.yamlValue, - YamlString("ignored_files") -> interface.get.ignored_files.yamlValue + YamlString("exclude") -> interface.get.exclude.yamlValue // YamlString("relationships") -> relationships.yamlValue ) diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFileInterface.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFileInterface.scala index 34e0445bb0..44086716f5 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFileInterface.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/config/ProjectFileInterface.scala @@ -9,11 +9,11 @@ trait PFInterface { } case class PFRootInterface( - name: PFFieldInterface[YamlString], - parsers: PFListInterface[YamlString], - knowledge: PFListInterface[YamlString], - knowledgePaths: PFListInterface[YamlString], - ignored_files: PFListInterface[YamlString] + name: PFFieldInterface[YamlString], + parsers: PFListInterface[YamlString], + knowledge: PFListInterface[YamlString], + knowledgePaths: PFListInterface[YamlString], + exclude: PFListInterface[YamlString] ) case class PFListInterface[T <: YamlValue](initialValue: List[T]) extends PFInterface { diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatch.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatch.scala new file mode 100644 index 0000000000..1ec7043a1d --- /dev/null +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatch.scala @@ -0,0 +1,26 @@ +package com.opticdev.core.sourcegear.project.monitoring + +import better.files.File +import com.opticdev.core.sourcegear.SourceGear + +object ShouldWatch { + def file(file: File, validExtensions: Set[String], excludedPaths: Seq[File]) : Boolean = { + val isValidFile = + file.isRegularFile && + file.extension.isDefined && + validExtensions.contains(file.extension.get) + + if (isValidFile) { + + excludedPaths.filter(_.exists).foldLeft(true) { + case (bool, path) => { + if (!bool) bool else { + !( path.isSameFileAs(file) || path.isParentOf(file)) + } + } + } + + } else false + + } +} diff --git a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectFileSpec.scala b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectFileSpec.scala index 0b9cfa8017..bd338e032b 100644 --- a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectFileSpec.scala +++ b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectFileSpec.scala @@ -63,10 +63,10 @@ class ProjectFileSpec extends TestBase { assert(f.empty.interface.get.knowledgePaths.value.isEmpty) } - it("includes ignored files") { + it("includes excluded files") { val f = fixture - assert(f.defined.interface.get.ignored_files.value.size == 1) - assert(f.empty.interface.get.ignored_files.value.isEmpty) + assert(f.defined.interface.get.exclude.value.size == 1) + assert(f.empty.interface.get.exclude.value.isEmpty) } } @@ -92,7 +92,7 @@ class ProjectFileSpec extends TestBase { //@todo figure out why this TEST won't pass // it("as yaml") { // assert(f.defined.yamlValue.prettyPrint == -//// "name: new name\nknowledge_paths:\n- /docs\nignored_files:\n- node_modules/\nknowledge:\n- js:express\nparsers:\n- JavaScript") +//// "name: new name\nknowledge_paths:\n- /docs\nexclude:\n- node_modules/\nknowledge:\n- js:express\nparsers:\n- JavaScript") // } it("to a file") { diff --git a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatchSpec.scala b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatchSpec.scala new file mode 100644 index 0000000000..cf9000447e --- /dev/null +++ b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/monitoring/ShouldWatchSpec.scala @@ -0,0 +1,36 @@ +package com.opticdev.core.sourcegear.project.monitoring + +import better.files.File +import com.opticdev.core.Fixture.TestBase +import com.opticdev.core.sourcegear.{GearSet, SourceGear} +import com.opticdev.parsers.{ParserBase, SourceParserManager} + +class ShouldWatchSpec extends TestBase { + + val validExtensions = Set(".js") + val excludedTestPaths = Seq( + File("test-examples/resources/example_source"), + File("test-examples/resources/example_source/LocationPlayground.js") + ) + + it("will accept files with the right extensions") { + assert(ShouldWatch.file(File("test-examples/resources/test_project/app.js"), validExtensions, excludedTestPaths)) + } + + it("will reject files that are children of an excluded path") { + assert(!ShouldWatch.file(File("test-examples/resources/example_source/ImportSource.js"), validExtensions, excludedTestPaths)) + } + + it("will reject files that are excluded explicitly") { + assert(!ShouldWatch.file(File("test-examples/resources/example_source/LocationPlayground.js"), validExtensions, excludedTestPaths)) + } + + it("will reject files with the wrong extensions") { + assert(!ShouldWatch.file(File("build.sbt"), validExtensions, excludedTestPaths)) + } + + it("will reject files that don't exist") { + assert(!ShouldWatch.file(File("notREAL.js"), validExtensions, excludedTestPaths)) + } + +} \ No newline at end of file diff --git a/test-examples/resources/example_project_files/empty.yaml b/test-examples/resources/example_project_files/empty.yaml index 207676006f..531a3f1808 100644 --- a/test-examples/resources/example_project_files/empty.yaml +++ b/test-examples/resources/example_project_files/empty.yaml @@ -2,4 +2,4 @@ parsers: knowledge: -ignored_files: +exclude: diff --git a/test-examples/resources/example_project_files/project.yaml b/test-examples/resources/example_project_files/project.yaml index 8152ba90fb..3a7b14b101 100644 --- a/test-examples/resources/example_project_files/project.yaml +++ b/test-examples/resources/example_project_files/project.yaml @@ -8,5 +8,5 @@ knowledge: knowledge_paths: - /docs -ignored_files: +exclude: - node_modules/ \ No newline at end of file diff --git a/test-examples/resources/example_project_files/project2.yaml b/test-examples/resources/example_project_files/project2.yaml index c64bfa87ac..2b918bdde4 100644 --- a/test-examples/resources/example_project_files/project2.yaml +++ b/test-examples/resources/example_project_files/project2.yaml @@ -7,5 +7,5 @@ knowledge: - optic:express-js@0.1.0 - optic:react-js@1.0.0 -ignored_files: +exclude: - node_modules/ \ No newline at end of file diff --git a/test-examples/resources/example_project_files/project3.yaml b/test-examples/resources/example_project_files/project3.yaml index 690bbfb8a8..48ba64810d 100644 --- a/test-examples/resources/example_project_files/project3.yaml +++ b/test-examples/resources/example_project_files/project3.yaml @@ -8,5 +8,5 @@ knowledge: - optic:express-js@0.1.0 - optic:react-js@1.0.0 -ignored_files: +exclude: - node_modules/ \ No newline at end of file diff --git a/test-examples/resources/example_project_files/project4.yaml b/test-examples/resources/example_project_files/project4.yaml index 480282fd5e..4fd4ce6874 100644 --- a/test-examples/resources/example_project_files/project4.yaml +++ b/test-examples/resources/example_project_files/project4.yaml @@ -7,5 +7,5 @@ knowledge: - optic:express-js@0.1.0 - optic:react-js@@@1.0.0 -ignored_files: +exclude: - node_modules/ \ No newline at end of file diff --git a/test-examples/resources/example_source/optic.yaml b/test-examples/resources/example_source/optic.yaml index b7a672a85e..e94112116a 100644 --- a/test-examples/resources/example_source/optic.yaml +++ b/test-examples/resources/example_source/optic.yaml @@ -1,4 +1,4 @@ name: Unnamed Project parsers: [] knowledge: [] -ignored_files: [] +exclude: [] From acb6694a3d4ab1513f3c34a58543e44757ffabe1 Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Tue, 6 Mar 2018 22:26:17 -0500 Subject: [PATCH 02/10] Added Exclude paths from parsers to ShouldWatch rules --- config.yaml | 2 +- .../opticdev/core/sourcegear/SourceGear.scala | 1 + .../sourcegear/project/OpticProject.scala | 4 ++-- project/dependencies.scala | 2 +- ...{es7_2.12-0.1.0.jar => es7_2.12-0.1.1.jar} | Bin 135984 -> 135240 bytes 5 files changed, 5 insertions(+), 4 deletions(-) rename server/src/main/resources/{es7_2.12-0.1.0.jar => es7_2.12-0.1.1.jar} (88%) diff --git a/config.yaml b/config.yaml index 3916f0aa79..180b371737 100644 --- a/config.yaml +++ b/config.yaml @@ -1 +1 @@ -testParser: "server/src/main/resources/es7_2.12-0.1.0.jar" \ No newline at end of file +testParser: "server/src/main/resources/es7_2.12-0.1.1.jar" \ No newline at end of file diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/SourceGear.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/SourceGear.scala index 5222cc7535..e34ac28a9c 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/SourceGear.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/SourceGear.scala @@ -30,6 +30,7 @@ abstract class SourceGear { def findParser(parserRef: ParserRef) = parsers.find(_.languageName == parserRef.languageName) lazy val validExtensions: Set[String] = parsers.flatMap(_.fileExtensions) + lazy val excludedPaths: Seq[String] = parsers.flatMap(_.excludedPaths).toSeq def parseFile(file: File) (implicit project: OpticProject) : Try[FileParseResults] = Try(file.contentAsString).flatMap(i=> parseString(i)) diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala index d3c55ec3e6..d7f62bf816 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala @@ -131,11 +131,11 @@ abstract class OpticProject(val name: String, val baseDirectory: File)(implicit } /* Control logic for watching files */ - + //@todo profile this. Seems liable to cause big slowdowns with many files running through it def shouldWatchFile(file: File) : Boolean = ShouldWatch.file(file, projectSourcegear.validExtensions, - projectFile.interface.get.exclude.value.map(i=> File(i.value))) + projectFile.interface.get.exclude.value.map(i=> File(i.value)) ++ projectSourcegear.excludedPaths.map(i=> File(i))) def filesToWatch : Set[File] = baseDirectory.listRecursively.toVector.filter(shouldWatchFile).toSet } diff --git a/project/dependencies.scala b/project/dependencies.scala index ce1d920b1d..66e05a1608 100644 --- a/project/dependencies.scala +++ b/project/dependencies.scala @@ -8,7 +8,7 @@ object Dependencies { "org.scalactic" %% "scalactic" % "3.0.1", "org.scalatest" %% "scalatest" % "3.0.1" % "test", - "com.opticdev" %% "parser-foundation" % "0.1.0", + "com.opticdev" %% "parser-foundation" % "0.1.1", //file library "com.github.pathikrit" % "better-files_2.12" % "2.17.1", diff --git a/server/src/main/resources/es7_2.12-0.1.0.jar b/server/src/main/resources/es7_2.12-0.1.1.jar similarity index 88% rename from server/src/main/resources/es7_2.12-0.1.0.jar rename to server/src/main/resources/es7_2.12-0.1.1.jar index a002344a112d8324177e7177e6f3b431cba7d626..e9b6d69c40d0f0d0381a9bdcf09aaad288bda51d 100644 GIT binary patch delta 7908 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 Ws>-iel{k`t9?C>qa{vwl$o~OnAjpsa delta 8809 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 bIY1z>O9?}+U%-V>LKF}>eAFq>@Ie0$%D^a9 From 1d4a2521bbe85d35e43e1eecbef0f9ae3b10baca Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Mon, 12 Mar 2018 13:58:45 -0400 Subject: [PATCH 03/10] Updated Project Status to include a catch-all callback --- .../project/status/ProjectStatus.scala | 22 ++++++++++++++----- .../project/status/ProjectStatusSpec.scala | 20 ++++++++++++++++- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala index 23f0b15659..6a4ef09c4d 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala @@ -78,12 +78,22 @@ class ProjectStatus(private var _loadedStatus: LoadedStatusCase = Loaded, firstPassChangedCallbacks = firstPassChangedCallbacks + callback } - private def notify(status: ProjectStatusCase) = status match { - case a: SourceGearStatus => sgChangedCallbacks.foreach(i=> i(a)) - case a: MonitoringStatus => monitoringChangedCallbacks.foreach(i=> i(a)) - case a: ConfigStatus => configChangedCallbacks.foreach(i=> i(a)) - case a: FirstPassStatus => firstPassChangedCallbacks.foreach(i=> i(a)) - case _ => + private var statusChangedCallbacks = Set[(ProjectStatusCase)=> Unit]() + def statusChanged(callback: (ProjectStatusCase)=> Unit) = { + statusChangedCallbacks = statusChangedCallbacks + callback + } + + private def notify(status: ProjectStatusCase) = { + //send to specific callbacks + status match { + case a: SourceGearStatus => sgChangedCallbacks.foreach(i=> i(a)) + case a: MonitoringStatus => monitoringChangedCallbacks.foreach(i=> i(a)) + case a: ConfigStatus => configChangedCallbacks.foreach(i=> i(a)) + case a: FirstPassStatus => firstPassChangedCallbacks.foreach(i=> i(a)) + case _ => + } + //send to any status changed callbacks + statusChangedCallbacks.foreach(_.apply(status)) } lazy val immutable : ImmutableProjectStatus = new ImmutableProjectStatus(this) diff --git a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala index c5da4293f0..b06f16ddc2 100644 --- a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala +++ b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala @@ -38,11 +38,12 @@ class ProjectStatusSpec extends FunSpec { } describe("callbacks") { - val projectStatus = new ProjectStatus() describe("register") { it("for sourcegear") { + val projectStatus = new ProjectStatus() + var didRun = false projectStatus.sourcegearChanged((a) => { didRun = true @@ -52,6 +53,8 @@ class ProjectStatusSpec extends FunSpec { } it("for file monitoring") { + val projectStatus = new ProjectStatus() + var didRun = false projectStatus.monitoringChanged((a) => { didRun = true @@ -61,6 +64,8 @@ class ProjectStatusSpec extends FunSpec { } it("for config") { + val projectStatus = new ProjectStatus() + var didRun = false projectStatus.configChanged((a) => { didRun = true @@ -70,6 +75,8 @@ class ProjectStatusSpec extends FunSpec { } it("for firstpass") { + val projectStatus = new ProjectStatus() + var didRun = false projectStatus.firstPassChanged((a) => { didRun = true @@ -78,6 +85,17 @@ class ProjectStatusSpec extends FunSpec { assert(didRun) } + it("for any") { + val projectStatus = new ProjectStatus() + + var didRun = false + projectStatus.statusChanged((a) => { + didRun = true + }) + projectStatus.firstPassStatus = Complete + assert(didRun) + } + } it("will not be called if no actual change") { From a01f1585a2af38169419da05d3fa9b8d9a5d9ee5 Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Mon, 12 Mar 2018 14:15:08 -0400 Subject: [PATCH 04/10] Added Socket Event for Project Status Changes --- .../core/sourcegear/project/OpticProject.scala | 1 - .../project/status/ImmutableProjectStatus.scala | 1 + .../sourcegear/project/status/ProjectStatus.scala | 6 +++--- .../sourcegear/project/status/ProjectStatusSpec.scala | 2 +- .../server/http/routes/socket/agents/package.scala | 11 +++++++++++ .../com/opticdev/server/state/ProjectsManager.scala | 6 ++++++ 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala index d7f62bf816..19b0c1c80e 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala @@ -37,7 +37,6 @@ abstract class OpticProject(val name: String, val baseDirectory: File)(implicit val projectStatus = projectStatusInstance.immutable def projectInfo : ProjectInfo = ProjectInfo(name, baseDirectory.pathAsString, projectStatus) - /* Normal Disk Monitoring */ val watcher: ActorRef = baseDirectory.newWatcher(recursive = true) diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala index 539e15ff9a..2a51e95af8 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala @@ -16,6 +16,7 @@ class ImmutableProjectStatus(projectStatus: ProjectStatus) { def monitoringChanged(callback: (MonitoringStatus)=> Unit) = projectStatus.monitoringChanged(callback) def configChanged(callback: (ConfigStatus)=> Unit) = projectStatus.configChanged(callback) def firstPassChanged(callback: (FirstPassStatus)=> Unit) = projectStatus.firstPassChanged(callback) + def statusChanged(callback: (ProjectStatusCase, ImmutableProjectStatus)=> Unit) = projectStatus.statusChanged(callback) def isValid: Boolean = projectStatus.isValid def isReady: Boolean = projectStatus.isReady diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala index 6a4ef09c4d..79a85b0268 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala @@ -78,8 +78,8 @@ class ProjectStatus(private var _loadedStatus: LoadedStatusCase = Loaded, firstPassChangedCallbacks = firstPassChangedCallbacks + callback } - private var statusChangedCallbacks = Set[(ProjectStatusCase)=> Unit]() - def statusChanged(callback: (ProjectStatusCase)=> Unit) = { + private var statusChangedCallbacks = Set[(ProjectStatusCase, ImmutableProjectStatus)=> Unit]() + def statusChanged(callback: (ProjectStatusCase, ImmutableProjectStatus)=> Unit) = { statusChangedCallbacks = statusChangedCallbacks + callback } @@ -93,7 +93,7 @@ class ProjectStatus(private var _loadedStatus: LoadedStatusCase = Loaded, case _ => } //send to any status changed callbacks - statusChangedCallbacks.foreach(_.apply(status)) + statusChangedCallbacks.foreach(_.apply(status, immutable)) } lazy val immutable : ImmutableProjectStatus = new ImmutableProjectStatus(this) diff --git a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala index b06f16ddc2..b8019c99ec 100644 --- a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala +++ b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatusSpec.scala @@ -89,7 +89,7 @@ class ProjectStatusSpec extends FunSpec { val projectStatus = new ProjectStatus() var didRun = false - projectStatus.statusChanged((a) => { + projectStatus.statusChanged((a, s) => { didRun = true }) projectStatus.firstPassStatus = Complete diff --git a/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/package.scala b/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/package.scala index a08b1596fe..ecf0199707 100644 --- a/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/package.scala +++ b/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/package.scala @@ -3,8 +3,10 @@ package com.opticdev.server.http.routes.socket import akka.actor.ActorRef import better.files.{File, Files} import com.opticdev.arrow.changes.ChangeGroup +import com.opticdev.core.sourcegear.project.status.ImmutableProjectStatus import play.api.libs.json._ import com.opticdev.server.data.ToJsonImplicits._ +import com.opticdev.server.http.routes.socket.agents.Protocol.UpdateAgentEvent import com.opticdev.server.http.routes.socket.editors.Protocol.EditorEvents package object agents { @@ -21,6 +23,7 @@ package object agents { case class AgentSearch(query: String, lastProjectName: Option[String], file: Option[File], range: Option[Range], contents: Option[String]) extends AgentEvents + //Sends trait UpdateAgentEvent extends OpticEvent case class ContextFound(filePath: String, range: Range, results: JsValue, isError: Boolean = false) extends OpticEvent with UpdateAgentEvent { @@ -51,4 +54,12 @@ package object agents { } + case class StatusUpdate(projectName: String, immutableProjectStatus: ImmutableProjectStatus) extends OpticEvent with UpdateAgentEvent { + def asJson = JsObject(Seq( + "event"-> JsString("status-update"), + "projectName"-> JsString(projectName), + "status"-> immutableProjectStatus.asJson + )) + } + } diff --git a/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala b/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala index cba4fd3069..4f4224a81c 100644 --- a/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala +++ b/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala @@ -10,6 +10,7 @@ import com.opticdev.server import com.opticdev.core.actorSystem import com.opticdev.core.sourcegear.project.status.ProjectStatus import com.opticdev.core.sourcegear.project.{OpticProject, Project, ProjectInfo} +import com.opticdev.server.http.routes.socket.agents.{AgentConnection, StatusUpdate} import scala.collection.mutable import scala.util.{Success, Try} @@ -33,6 +34,11 @@ class ProjectsManager { arrowStore = arrowStore + (project -> new Arrow(project)) }) + //attach a project status changed callback + project.projectStatus.statusChanged((changed, status)=> { + AgentConnection.broadcastUpdate(StatusUpdate(project.name, status)) + }) + projectsStore = projectsStore :+ project arrowStore = arrowStore + (project -> new Arrow(project)) if (projectsStore.size > MAX_PROJECTS) { From 889885828c17059e7fdd224e00d87e41b8484d5a Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Mon, 12 Mar 2018 21:27:12 -0400 Subject: [PATCH 05/10] Loading status events --- .../core/sourcegear/project/Project.scala | 2 ++ .../status/ImmutableProjectStatus.scala | 28 ++++++++++++++++++- .../project/status/ProjectStatus.scala | 1 + .../sourcegear/project/status/package.scala | 1 + .../socket/agents/AgentConnectionActor.scala | 16 +++++------ .../server/state/ProjectsManager.scala | 7 ++++- .../com/opticdev/server/Scratch.scala | 13 ++++++--- 7 files changed, 53 insertions(+), 15 deletions(-) diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/Project.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/Project.scala index 7b75a4a055..acf562a321 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/Project.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/Project.scala @@ -14,6 +14,7 @@ import scala.util.Try class Project(name: String, baseDirectory: File)(implicit logToCli: Boolean = false, actorCluster: ActorCluster) extends OpticProject(name, baseDirectory) { private var sourceGear: SourceGear = { + projectStatusInstance.sourceGearStatus = Building projectFileChanged(projectFile) SourceGear.unloaded } @@ -23,6 +24,7 @@ class Project(name: String, baseDirectory: File)(implicit logToCli: Boolean = fa override def projectFileChanged(newPf: ProjectFile): Unit = { super.projectFileChanged(newPf) if (newPf.interface.isSuccess) { + projectStatusInstance.sourceGearStatus = Building SGConstructor.fromProjectFile(newPf).onComplete(i => { if (i.isSuccess) { sourceGear = i.get.inflate diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala index 2a51e95af8..2107038877 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ImmutableProjectStatus.scala @@ -1,6 +1,6 @@ package com.opticdev.core.sourcegear.project.status -import play.api.libs.json.{JsObject, JsString} +import play.api.libs.json.{JsArray, JsBoolean, JsObject, JsString} class ImmutableProjectStatus(projectStatus: ProjectStatus) { @@ -19,9 +19,11 @@ class ImmutableProjectStatus(projectStatus: ProjectStatus) { def statusChanged(callback: (ProjectStatusCase, ImmutableProjectStatus)=> Unit) = projectStatus.statusChanged(callback) def isValid: Boolean = projectStatus.isValid + def isLoading: Boolean = projectStatus.isLoading def isReady: Boolean = projectStatus.isReady def asJson = { + val errors = errorsAsJson JsObject(Seq( "loaded" -> JsString(loadedStatus.toString), "sourcegear" -> JsString(sourceGearStatus.toString), @@ -29,7 +31,31 @@ class ImmutableProjectStatus(projectStatus: ProjectStatus) { "config" -> JsString(configStatus.toString), "firstPass" -> JsString(firstPassStatus.toString), "lastUpdate" -> JsString(lastUpdate.time.toString), + + "isValid"-> JsBoolean(isValid), + "isLoading"-> JsBoolean(isLoading), + "hasErrors"-> JsBoolean(errors.value.nonEmpty), + "errors" -> errors )) } + def errorsAsJson : JsArray = { + var seq = Seq[JsString]() + + configStatus match { + case config: InvalidConfig => + seq = seq :+ JsString(config.error) + case _ => + } + + sourceGearStatus match { + case status: Invalid => + seq = seq :+ JsString(status.error) + case _ => + } + + JsArray(seq) + } + + override def toString: String = asJson.toString() } \ No newline at end of file diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala index 79a85b0268..c8671b2c91 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/ProjectStatus.scala @@ -56,6 +56,7 @@ class ProjectStatus(private var _loadedStatus: LoadedStatusCase = Loaded, def touch : Unit = lastUpdate = LastUpdateDate(Calendar.getInstance().getTime) def isValid: Boolean = configStatus == ValidConfig && sourceGearStatus == Valid + def isLoading: Boolean = configStatus == ValidConfig && sourceGearStatus == Building def isReady: Boolean = isValid && firstPassStatus == Complete private var sgChangedCallbacks = Set[(SourceGearStatus)=> Unit]() diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/package.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/package.scala index cb49959dd9..9c7a5aa336 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/package.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/status/package.scala @@ -13,6 +13,7 @@ package object status { sealed trait SourceGearStatus extends ProjectStatusCase case object Empty extends SourceGearStatus case object Valid extends SourceGearStatus + case object Building extends SourceGearStatus case class Invalid(error: String) extends SourceGearStatus sealed trait MonitoringStatus extends ProjectStatusCase diff --git a/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/AgentConnectionActor.scala b/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/AgentConnectionActor.scala index ce53d1918e..7b1ebc9d2c 100644 --- a/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/AgentConnectionActor.scala +++ b/server/src/main/scala-2.12/com/opticdev/server/http/routes/socket/agents/AgentConnectionActor.scala @@ -19,8 +19,10 @@ class AgentConnectionActor(slug: String, projectsManager: ProjectsManager) exten override def receive: Receive = { case Registered(actorRef) => { - println("worked correctly") +// println("worked correctly") connection = actorRef + //trigger a status update to send to Agent + projectsManager.sendMostRecentUpdate } case Terminated => { Status.Success(Unit) @@ -32,14 +34,6 @@ class AgentConnectionActor(slug: String, projectsManager: ProjectsManager) exten connection ! ErrorResponse("Invalid Request") } - case contextUpdate: ContextFound => { - connection ! contextUpdate - } - - case searchResults: SearchResults => { - connection ! searchResults - } - case search: AgentSearch => { ArrowQuery(search, projectsManager.lastProjectName)(projectsManager).executeToApiResponse.foreach(i=> { AgentConnection.broadcastUpdate( SearchResults(search.query, i.data, ignoreQueryUpdate = true) ) @@ -79,6 +73,10 @@ class AgentConnectionActor(slug: String, projectsManager: ProjectsManager) exten }) } + case updateAgentEvent: UpdateAgentEvent => { + connection ! updateAgentEvent + } + } } diff --git a/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala b/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala index 4f4224a81c..f3cb911757 100644 --- a/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala +++ b/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala @@ -8,7 +8,7 @@ import com.opticdev.core.sourcegear.actors.ActorCluster import com.opticdev.server.storage.ServerStorage import com.opticdev.server import com.opticdev.core.actorSystem -import com.opticdev.core.sourcegear.project.status.ProjectStatus +import com.opticdev.core.sourcegear.project.status.{ImmutableProjectStatus, ProjectStatus} import com.opticdev.core.sourcegear.project.{OpticProject, Project, ProjectInfo} import com.opticdev.server.http.routes.socket.agents.{AgentConnection, StatusUpdate} @@ -131,4 +131,9 @@ class ProjectsManager { private var _lastProjectName : Option[String] = None def lastProjectName = _lastProjectName + def sendMostRecentUpdate = Try { + val project = lookupProject(_lastProjectName.get).get + AgentConnection.broadcastUpdate(StatusUpdate(_lastProjectName.get, project.projectStatus)) + } + } diff --git a/server/src/test/scala-2.12/com/opticdev/server/Scratch.scala b/server/src/test/scala-2.12/com/opticdev/server/Scratch.scala index 708965a9d9..d3148f9700 100644 --- a/server/src/test/scala-2.12/com/opticdev/server/Scratch.scala +++ b/server/src/test/scala-2.12/com/opticdev/server/Scratch.scala @@ -12,7 +12,8 @@ import net.jcazevedo.moultingyaml.YamlString import net.jcazevedo.moultingyaml._ import scala.util.Try - +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.duration._ object Scratch extends TestBase with TestPackageProviders { installProviders @@ -28,9 +29,13 @@ object Scratch extends TestBase with TestPackageProviders { implicit val projectsManager: ProjectsManager = new ProjectsManager() implicit val actorCluster = projectsManager.actorCluster - //manually adding projects for testing - val project = Project.fromProjectFile(new ProjectFile(File("test-examples/resources/tmp/test_project/optic.yaml"))).get - projectsManager.loadProject(project) + + + com.opticdev.core.actorSystem.scheduler.scheduleOnce(5 seconds) { + //manually adding projects for testing + val project = Project.fromProjectFile(new ProjectFile(File("test-examples/resources/tmp/test_project/optic.yaml"))).get + projectsManager.loadProject(project) + } def main(args: Array[String]): Unit = { Server.start() From 0bddc2e69bc15623deb41058e2c99b5190131e16 Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Tue, 13 Mar 2018 12:38:06 -0400 Subject: [PATCH 06/10] Refactored Storage from Common Added Platform Specific executable paths Added Tasks to SBT to download latest optic-markdown process --- build.sbt | 11 ++++++++++- .../{storage => }/PlatformConstants.scala | 17 ++++++++++++++++- .../opticdev/common/storage/DataDirectory.scala | 6 +++++- .../{storage => }/PlatformConstantsSpec.scala | 5 +++-- .../common/storage/DataDirectorySpec.scala | 1 + .../opticdev/opm/packages/OpticMDPackage.scala | 2 +- .../com/opticdev/opm/packages/package.scala | 2 +- project/Constants.scala | 6 ++++++ .../sdk/{ => markdown}/MarkdownParser.scala | 4 ++-- .../sdk/markdown/OpticMarkdownInstaller.scala | 12 ++++++++++++ .../sdk/{ => markdown}/MarkdownParserSpec.scala | 2 +- 11 files changed, 58 insertions(+), 10 deletions(-) rename common/src/main/scala-2.12/com/opticdev/common/{storage => }/PlatformConstants.scala (71%) rename common/src/test/scala-2.12/com/opticdev/common/{storage => }/PlatformConstantsSpec.scala (88%) create mode 100644 project/Constants.scala rename sdk/src/main/scala-2.12/com.opticdev/sdk/{ => markdown}/MarkdownParser.scala (96%) create mode 100644 sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala rename sdk/src/test/scala-2.12/com/opticdev/sdk/{ => markdown}/MarkdownParserSpec.scala (93%) diff --git a/build.sbt b/build.sbt index de4a25f9e2..586345479d 100644 --- a/build.sbt +++ b/build.sbt @@ -70,4 +70,13 @@ lazy val server = (project in file("server")). .enablePlugins(AssemblyPlugin) -concurrentRestrictions in Global += Tags.limit(Tags.Test, 1) \ No newline at end of file +concurrentRestrictions in Global += Tags.limit(Tags.Test, 1) + +lazy val hello = taskKey[Unit]("Prints 'Hello World'") +hello := { + import sys.process._ + import java.net.URL + import java.io.File + new URL(Constants.opticMDTar) #> new File("Output.tgz") !! + +} \ No newline at end of file diff --git a/common/src/main/scala-2.12/com/opticdev/common/storage/PlatformConstants.scala b/common/src/main/scala-2.12/com/opticdev/common/PlatformConstants.scala similarity index 71% rename from common/src/main/scala-2.12/com/opticdev/common/storage/PlatformConstants.scala rename to common/src/main/scala-2.12/com/opticdev/common/PlatformConstants.scala index fe61cc4b45..58305649ce 100644 --- a/common/src/main/scala-2.12/com/opticdev/common/storage/PlatformConstants.scala +++ b/common/src/main/scala-2.12/com/opticdev/common/PlatformConstants.scala @@ -1,6 +1,7 @@ -package com.opticdev.common.storage +package com.opticdev.common import better.files.File +import com.opticdev.common.storage.{Linux, Mac, OS, Windows} import org.apache.commons.lang3.SystemUtils object PlatformConstants { @@ -22,4 +23,18 @@ object PlatformConstants { .createIfNotExists(asDirectory = true, createParents = false) } + + + + + + //Exec paths + val bashPath: String = platform match { + case Mac => "/bin/bash" + } + + val nodePath: String = platform match { + case Mac => "/usr/local/bin/node" + } + } \ No newline at end of file diff --git a/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala b/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala index 5f758aa5fb..e8d78f4d16 100644 --- a/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala +++ b/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala @@ -1,5 +1,7 @@ package com.opticdev.common.storage +import com.opticdev.common.PlatformConstants + object DataDirectory { val root = PlatformConstants.dataDirectory @@ -7,7 +9,7 @@ object DataDirectory { val parsers = PlatformConstants.dataDirectory / "parsers" val compiled = PlatformConstants.dataDirectory / "compiled" val sourcegear = PlatformConstants.dataDirectory / "sourcegear" - + val bin = PlatformConstants.dataDirectory / "bin" def hasValidStructure = { root.isDirectory && @@ -15,6 +17,7 @@ object DataDirectory { packages.isDirectory && compiled.isDirectory && sourcegear.isDirectory + bin.isDirectory } def buildDirectoryStructure = { @@ -23,6 +26,7 @@ object DataDirectory { packages.createIfNotExists(asDirectory = true) compiled.createIfNotExists(asDirectory = true) sourcegear.createIfNotExists(asDirectory = true) + bin.createIfNotExists(asDirectory = true) } def delete = root.delete(true) diff --git a/common/src/test/scala-2.12/com/opticdev/common/storage/PlatformConstantsSpec.scala b/common/src/test/scala-2.12/com/opticdev/common/PlatformConstantsSpec.scala similarity index 88% rename from common/src/test/scala-2.12/com/opticdev/common/storage/PlatformConstantsSpec.scala rename to common/src/test/scala-2.12/com/opticdev/common/PlatformConstantsSpec.scala index c7474e4aed..e8cc5adc20 100644 --- a/common/src/test/scala-2.12/com/opticdev/common/storage/PlatformConstantsSpec.scala +++ b/common/src/test/scala-2.12/com/opticdev/common/PlatformConstantsSpec.scala @@ -1,8 +1,9 @@ -package com.opticdev.common.storage +package com.opticdev.common import better.files.File -import org.scalatest.FunSpec +import com.opticdev.common.storage.{Mac, OS} import org.apache.commons.lang3.SystemUtils +import org.scalatest.FunSpec class PlatformConstantsSpec extends FunSpec { diff --git a/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala b/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala index 91237e09c5..95b261d261 100644 --- a/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala +++ b/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala @@ -1,6 +1,7 @@ package com.opticdev.common.storage import better.files.File +import com.opticdev.common.PlatformConstants import org.scalatest.FunSpec class DataDirectorySpec extends FunSpec { diff --git a/opm/src/main/scala-2.12/com/opticdev/opm/packages/OpticMDPackage.scala b/opm/src/main/scala-2.12/com/opticdev/opm/packages/OpticMDPackage.scala index ade6c6e4c8..8ca4131bc4 100644 --- a/opm/src/main/scala-2.12/com/opticdev/opm/packages/OpticMDPackage.scala +++ b/opm/src/main/scala-2.12/com/opticdev/opm/packages/OpticMDPackage.scala @@ -2,12 +2,12 @@ package com.opticdev.opm.packages import better.files.File import com.opticdev.common.PackageRef -import com.opticdev.sdk.MarkdownParser import com.opticdev.sdk.descriptions._ import play.api.libs.json.{JsArray, JsObject, JsString, JsValue} import scala.util.Try import com.opticdev.opm.helpers.MDPackageResolveHelper._ +import com.opticdev.sdk.markdown.MarkdownParser case class OpticMDPackage(description: JsObject, dependencyMapping: DependencyMapping) extends OpticPackage{ private def objectValueForKey(key: String): Map[String, JsObject] = { diff --git a/opm/src/main/scala-2.12/com/opticdev/opm/packages/package.scala b/opm/src/main/scala-2.12/com/opticdev/opm/packages/package.scala index 61ad2b1fd6..e6278b46f1 100644 --- a/opm/src/main/scala-2.12/com/opticdev/opm/packages/package.scala +++ b/opm/src/main/scala-2.12/com/opticdev/opm/packages/package.scala @@ -2,7 +2,7 @@ package com.opticdev.opm.packages import better.files.File import com.opticdev.common.PackageRef -import com.opticdev.sdk.MarkdownParser +import com.opticdev.sdk.markdown.MarkdownParser import play.api.libs.json.{JsArray, JsObject, JsString, JsValue} import scala.util.{Success, Try} diff --git a/project/Constants.scala b/project/Constants.scala new file mode 100644 index 0000000000..8e3528b431 --- /dev/null +++ b/project/Constants.scala @@ -0,0 +1,6 @@ + +object Constants { + val opticMDVersion = "0.1.2" + val opticMDTar = s"https://registry.npmjs.org/optic-markdown/-/optic-markdown-${opticMDVersion}.tgz" + val opticMDShasum = "764f6cf924fdd8a899e26b8eb982d3a497878656" +} diff --git a/sdk/src/main/scala-2.12/com.opticdev/sdk/MarkdownParser.scala b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/MarkdownParser.scala similarity index 96% rename from sdk/src/main/scala-2.12/com.opticdev/sdk/MarkdownParser.scala rename to sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/MarkdownParser.scala index 3665ccbad1..411617c34d 100644 --- a/sdk/src/main/scala-2.12/com.opticdev/sdk/MarkdownParser.scala +++ b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/MarkdownParser.scala @@ -1,11 +1,11 @@ -package com.opticdev.sdk +package com.opticdev.sdk.markdown import better.files.File import com.opticdev.sdk.descriptions.Schema import play.api.libs.json.{JsArray, JsObject, Json} +import scala.sys.process._ import scala.util.Try -import sys.process._ object MarkdownParser { diff --git a/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala new file mode 100644 index 0000000000..f703c95926 --- /dev/null +++ b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala @@ -0,0 +1,12 @@ +package com.opticdev.sdk.markdown + +import scala.util.Try +object OpticMarkdownInstaller { + + def getOrInstall : Try[String] = { + + + + } + +} diff --git a/sdk/src/test/scala-2.12/com/opticdev/sdk/MarkdownParserSpec.scala b/sdk/src/test/scala-2.12/com/opticdev/sdk/markdown/MarkdownParserSpec.scala similarity index 93% rename from sdk/src/test/scala-2.12/com/opticdev/sdk/MarkdownParserSpec.scala rename to sdk/src/test/scala-2.12/com/opticdev/sdk/markdown/MarkdownParserSpec.scala index 7382c8353c..763cd800c0 100644 --- a/sdk/src/test/scala-2.12/com/opticdev/sdk/MarkdownParserSpec.scala +++ b/sdk/src/test/scala-2.12/com/opticdev/sdk/markdown/MarkdownParserSpec.scala @@ -1,4 +1,4 @@ -package com.opticdev.sdk +package com.opticdev.sdk.markdown import better.files.File import org.scalatest.FunSpec From f797e27fdd4d47202641bc72aff6cdb321c7e068 Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Wed, 14 Mar 2018 13:19:43 -0400 Subject: [PATCH 07/10] Included a local Optic Markdown installer --- .gitignore | 3 +- build.sbt | 25 ++-- .../sourcegear/project/OpticProject.scala | 2 +- .../core/sourcegear/project/ProjectSpec.scala | 2 +- .../opm/providers/LocalProviderSpec.scala | 4 +- .../opm/storage/ParserStorageSpec.scala | 21 ++- project/Constants.scala | 2 +- project/dependencies.scala | 3 +- project/plugins.sbt | 2 +- .../sdk/markdown/MarkdownParser.scala | 24 ++-- .../sdk/markdown/OpticMarkdownInstaller.scala | 91 ++++++++++++- .../markdown/OpticMarkdownInstallerSpec.scala | 126 ++++++++++++++++++ server/src/main/resources/es7_2.12-0.1.1.jar | Bin 135240 -> 135243 bytes .../com/opticdev/server/http/Lifecycle.scala | 5 + 14 files changed, 261 insertions(+), 49 deletions(-) create mode 100644 sdk/src/test/scala-2.12/com/opticdev/sdk/markdown/OpticMarkdownInstallerSpec.scala diff --git a/.gitignore b/.gitignore index fda1310d78..f3abfa5f80 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ server/target/ sdk/target/ core/target/ -test-examples/resources/tmp/ \ No newline at end of file +test-examples/resources/tmp/ + diff --git a/build.sbt b/build.sbt index 586345479d..952540c4f0 100644 --- a/build.sbt +++ b/build.sbt @@ -27,8 +27,16 @@ lazy val common = (project in file("common")). .settings(libraryDependencies ++= Dependencies.commonDependencies) lazy val sdk = (project in file("sdk")). + enablePlugins(BuildInfoPlugin). settings(commonSettings: _*) - .settings(libraryDependencies ++= Dependencies.sdkDependencies) + .settings( + libraryDependencies ++= Dependencies.sdkDependencies, + buildInfoKeys := Seq[BuildInfoKey]( + "opticMDTar" -> Constants.opticMDTar, + "opticMDTarSum" -> Constants.opticMDTarSum, + ), + buildInfoPackage := "com.opticdev.sdk" + ) .dependsOn(common) lazy val opm = (project in file("opm")). @@ -64,19 +72,10 @@ lazy val server = (project in file("server")). .dependsOn(arrow % "compile->compile;test->test") .settings( test in assembly := {}, + assemblyJarName in assembly := "server-assembly.jar", mainClass in assembly := Some("com.opticdev.server.http.Lifecycle"), mainClass in packageBin := Some("com.opticdev.server.http.Lifecycle") - ) + ) .enablePlugins(AssemblyPlugin) - -concurrentRestrictions in Global += Tags.limit(Tags.Test, 1) - -lazy val hello = taskKey[Unit]("Prints 'Hello World'") -hello := { - import sys.process._ - import java.net.URL - import java.io.File - new URL(Constants.opticMDTar) #> new File("Output.tgz") !! - -} \ No newline at end of file +concurrentRestrictions in Global += Tags.limit(Tags.Test, 1) \ No newline at end of file diff --git a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala index 19b0c1c80e..e414dced0f 100644 --- a/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala +++ b/core/src/main/scala-2.12/com/opticdev/core/sourcegear/project/OpticProject.scala @@ -94,7 +94,7 @@ abstract class OpticProject(val name: String, val baseDirectory: File)(implicit implicit val sourceGear = projectSourcegear projectStatusInstance.touch filesStateMonitor.markUpdated(file) - if (file === projectFile.file) { + if (file.isSameFileAs(projectFile.file)) { projectFile.reload } else { if (shouldWatchFile(file)) projectActor ! FileUpdated(file, this) diff --git a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectSpec.scala b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectSpec.scala index 8415848fef..73bc424832 100644 --- a/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectSpec.scala +++ b/core/src/test/scala-2.12/com/opticdev/core/sourcegear/project/ProjectSpec.scala @@ -118,7 +118,7 @@ class ProjectSpec extends AkkaTestFixture("ProjectTest") with GearUtils with Eve assert(status.firstPassStatus == NotStarted) assert(status.configStatus == ValidConfig) assert(status.monitoringStatus == NotWatching) - assert(status.sourceGearStatus == Empty) + assert(status.sourceGearStatus == Building) } it("creates a sourcegear instance from config") { diff --git a/opm/src/test/scala-2.12/com/opticdev/opm/providers/LocalProviderSpec.scala b/opm/src/test/scala-2.12/com/opticdev/opm/providers/LocalProviderSpec.scala index 85c5f8ff6f..ab09ab2719 100644 --- a/opm/src/test/scala-2.12/com/opticdev/opm/providers/LocalProviderSpec.scala +++ b/opm/src/test/scala-2.12/com/opticdev/opm/providers/LocalProviderSpec.scala @@ -19,12 +19,12 @@ class LocalProviderSpec extends FunSpec { } it("can resolve a local package") { - val r = Await.result(localProvider.resolvePackages(PackageRef("optic:rest")), 5 seconds) + val r = Await.result(localProvider.resolvePackages(PackageRef("optic:rest")), 10 seconds) assert(r.foundAll) } it("will not resolve a non-existent local package") { - val r = Await.result(localProvider.resolvePackages(PackageRef("optic:dadasd")), 5 seconds) + val r = Await.result(localProvider.resolvePackages(PackageRef("optic:dadasd")), 10 seconds) assert(!r.foundAll) } diff --git a/opm/src/test/scala-2.12/com/opticdev/opm/storage/ParserStorageSpec.scala b/opm/src/test/scala-2.12/com/opticdev/opm/storage/ParserStorageSpec.scala index 0a17dfe2fa..42fa95f93c 100644 --- a/opm/src/test/scala-2.12/com/opticdev/opm/storage/ParserStorageSpec.scala +++ b/opm/src/test/scala-2.12/com/opticdev/opm/storage/ParserStorageSpec.scala @@ -7,39 +7,38 @@ import org.scalatest.FunSpec class ParserStorageSpec extends FunSpec { - lazy val fakeParserJar = File("test-examples/resources/example_parsers/fake-parser-0.1.0.jar") + lazy val parserJar = File("server/src/main/resources/es7_2.12-0.1.1.jar") it("can save parsers to local") { - val parserSaved = ParserStorage.writeToStorage(fakeParserJar) - println(parserSaved) + val parserSaved = ParserStorage.writeToStorage(parserJar) assert(parserSaved.isSuccess) } it("can lookup items from local") { - val parserLoad = ParserStorage.loadFromStorage(ParserRef("Fake", "0.1.0")) + val parserLoad = ParserStorage.loadFromStorage(ParserRef("es7", "0.1.1")) assert(parserLoad.isSuccess) - assert(parserLoad.get.languageName == "Fake") + assert(parserLoad.get.languageName == "es7") } it("can load parser by version 'latest'") { - val parserLoad = ParserStorage.loadFromStorage(ParserRef("Fake", "latest")) + val parserLoad = ParserStorage.loadFromStorage(ParserRef("es7", "latest")) assert(parserLoad.isSuccess) - assert(parserLoad.get.languageName == "Fake") - assert(parserLoad.get.parserVersion == "0.1.0") + assert(parserLoad.get.languageName == "es7") + assert(parserLoad.get.parserVersion == "0.1.1") } it("can clear all local parsers") { - ParserStorage.writeToStorage(fakeParserJar) + ParserStorage.writeToStorage(parserJar) ParserStorage.clearLocalParsers assert(ParserStorage.listAllParsers.isEmpty) } it("can load all parsers") { ParserStorage.clearLocalParsers - ParserStorage.writeToStorage(fakeParserJar) + ParserStorage.writeToStorage(parserJar) val listAll = ParserStorage.listAllParsers .mapValues(_.map(_.parserRef)) - assert(listAll == Map("Fake" -> Vector(ParserRef("Fake", "0.1.0")))) + assert(listAll == Map("es7" -> Vector(ParserRef("es7", "0.1.1")))) } } diff --git a/project/Constants.scala b/project/Constants.scala index 8e3528b431..29f031ecb0 100644 --- a/project/Constants.scala +++ b/project/Constants.scala @@ -2,5 +2,5 @@ object Constants { val opticMDVersion = "0.1.2" val opticMDTar = s"https://registry.npmjs.org/optic-markdown/-/optic-markdown-${opticMDVersion}.tgz" - val opticMDShasum = "764f6cf924fdd8a899e26b8eb982d3a497878656" + val opticMDTarSum = "764f6cf924fdd8a899e26b8eb982d3a497878656" } diff --git a/project/dependencies.scala b/project/dependencies.scala index 66e05a1608..b3a657797e 100644 --- a/project/dependencies.scala +++ b/project/dependencies.scala @@ -32,7 +32,8 @@ object Dependencies { val sdkDependencies: Seq[ModuleID] = sharedDependencies ++ Seq( "com.typesafe.play" %% "play-json" % "2.6.2", "com.github.fge" % "json-schema-validator" % "2.2.6", - "org.gnieh" %% "diffson-play-json" % "2.2.1" + "org.gnieh" %% "diffson-play-json" % "2.2.1", + "org.apache.commons" % "commons-compress" % "1.16.1" ) val serverDependencies : Seq[ModuleID] = sharedDependencies ++ Seq( diff --git a/project/plugins.sbt b/project/plugins.sbt index 442c8a4933..b26c76edbb 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,4 +2,4 @@ logLevel := Level.Warn addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") -addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.3") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.8.0") diff --git a/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/MarkdownParser.scala b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/MarkdownParser.scala index 411617c34d..2a55e61c5c 100644 --- a/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/MarkdownParser.scala +++ b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/MarkdownParser.scala @@ -29,22 +29,16 @@ object MarkdownParser { def noErrors = errors.value.isEmpty } - private val pathToExecutable = "/usr/local/bin/node /usr/local/lib/node_modules/optic-markdown/lib/cli.js" - def parseMarkdown(file: File) = Try[MDParseOutput] { - //check the version eventually - val version = pathToExecutable+ " --version" !! - - if (version.contains("not found")) throw new Error("optic-md is not installed. Run npm install optic-md -g") - - val result = pathToExecutable+ " " + file.pathAsString !! - - val parsedJson = Try(Json.parse(result)) - - if (parsedJson.isFailure || !outputSchema.validate(parsedJson.get)) { - throw new Error("Invalid output from markdown parser") - } else - MDParseOutput(parsedJson.get.as[JsObject]) + def parseMarkdown(file: File) : Try[MDParseOutput] = { + OpticMarkdownInstaller.getOrInstall + .map(i=> { + val result = i.parseFile(file.pathAsString) + if (!outputSchema.validate(result)) { + throw new Error("Invalid output from markdown parser") + } else + MDParseOutput(result) + }) } } diff --git a/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala index f703c95926..673516ed56 100644 --- a/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala +++ b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala @@ -1,12 +1,99 @@ package com.opticdev.sdk.markdown -import scala.util.Try +import better.files.File +import com.opticdev.common.storage.DataDirectory +import com.opticdev.sdk.BuildInfo +import com.opticdev.common.PlatformConstants +import play.api.libs.json.{JsObject, Json} + +import scala.util.{Failure, Success, Try} +import sys.process._ + object OpticMarkdownInstaller { + def getOrInstall : Try[CallOpticMarkdown.type] = { + synchronized { + if (CallOpticMarkdown.isInstalled) { + Success(CallOpticMarkdown) + } else { + download(BuildInfo.opticMDTar, BuildInfo.opticMDTarSum) + .flatMap(unzip) + .flatMap(npmInstall) match { + case Success(a) => Success(CallOpticMarkdown) + case Failure(f) => { + cleanupOnFail + Failure(f) + } + } + } + } + } + + protected case object CallOpticMarkdown { + + val script = DataDirectory.bin / "optic-markdown" / "lib" / "cli.js" + + def isInstalled : Boolean = Try { + val cmd = Seq(PlatformConstants.nodePath, script.pathAsString, "--version") + val result = cmd.!!(ProcessLogger(stdout append _, stderr append _)) + } match { + case Success(a) => true + case Failure(a) => false + } + + def parseFile(filePath: String) : JsObject = { + val cmd = Seq(PlatformConstants.nodePath, script.pathAsString, filePath) + val result = cmd.!!(ProcessLogger(stdout append _, stderr append _)) + Json.parse(result).as[JsObject] + } + +// def parseString : JsObject = { +// +// } + } - def getOrInstall : Try[String] = { + private def download(opticMDTar: String, opticMDTarSum: String) : Try[File] = Try { + import java.net.URL + val target = DataDirectory.bin / "optic-markdown.tgz" + target.delete(true) + + //will throw if doesn't work + new URL(opticMDTar) #> target.toJava !! + + assert(target.sha1.toLowerCase == opticMDTarSum.toLowerCase, "optic-markdown sha does not match. Download failed") + + target + } + + private def unzip(file: File) : Try[File] = Try { + val mdDirectory: File = DataDirectory.bin / "optic-markdown" + val unzip: Seq[String] = Seq( + "tar", + "-xzf", + file.pathAsString, + "-C", + DataDirectory.bin.pathAsString, + ) + + unzip.!! + + val mv: Seq[String] = Seq( + "mv", + (DataDirectory.bin / "package").pathAsString, + mdDirectory.pathAsString + ) + mv.!! + + file.delete(true) + assert(mdDirectory.isDirectory, "Optic Markdown could not be unzipped.") + mdDirectory + } + private def npmInstall(directory: File) : Try[Unit] = Try { + val process = sys.process.Process(Seq("npm", "install"), directory.toJava) + process.!(ProcessLogger(stdout append _, stderr append _)) } + private def cleanupOnFail = DataDirectory.bin.list.foreach(_.delete(true)) } diff --git a/sdk/src/test/scala-2.12/com/opticdev/sdk/markdown/OpticMarkdownInstallerSpec.scala b/sdk/src/test/scala-2.12/com/opticdev/sdk/markdown/OpticMarkdownInstallerSpec.scala new file mode 100644 index 0000000000..46c20abc83 --- /dev/null +++ b/sdk/src/test/scala-2.12/com/opticdev/sdk/markdown/OpticMarkdownInstallerSpec.scala @@ -0,0 +1,126 @@ +package com.opticdev.sdk.markdown + +import akka.dispatch.Futures +import better.files.File +import com.opticdev.common.storage.DataDirectory +import org.scalatest.concurrent.Eventually +import org.scalatest.time.{Seconds, Span} +import org.scalatest.{BeforeAndAfterEach, FunSpec, PrivateMethodTester} +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.{Await, Future} +import scala.concurrent.duration._ +import scala.util.Try + +/* +This test is long running. It's really important to cover all these cases and make sure its threadsafe. + */ + +class OpticMarkdownInstallerSpec extends FunSpec with PrivateMethodTester with BeforeAndAfterEach with Eventually { + + override protected def beforeEach(): Unit = { + DataDirectory.bin.list.foreach(_.delete(true)) + } + + def download(tar: String, sum: String) = { + val download = PrivateMethod[Try[File]]('download) + OpticMarkdownInstaller invokePrivate download(tar, sum) + } + + describe("download") { + + it("works with valid url & checksum") { + val result = download( + "https://registry.npmjs.org/optic-markdown/-/optic-markdown-0.1.2.tgz", + "764f6cf924fdd8a899e26b8eb982d3a497878656" + ) + assert(result.isSuccess) + } + + it("fails if url is invalid") { + val result = download( + "NOT REAL", + "764f6cf924fdd8a899e26b8eb982d3a497878656" + ) + assert(result.isFailure) + } + + it("fails if checksum is wrong") { + val result = download( + "https://registry.npmjs.org/optic-markdown/-/optic-markdown-0.1.2.tgz", + "FAKE_WRONG" + ) + assert(result.isFailure) + } + + } + + def unzip(file: File) = { + val download = PrivateMethod[Try[File]]('unzip) + OpticMarkdownInstaller invokePrivate download(file) + } + + describe("unzip") { + + it("works with valid file piped in") { + val downloadResult = download( + "https://registry.npmjs.org/optic-markdown/-/optic-markdown-0.1.2.tgz", + "764f6cf924fdd8a899e26b8eb982d3a497878656" + ) + + val unzipResult = downloadResult.map(i=> unzip(i)).flatten + + assert(DataDirectory.bin.list.size == 1) + assert(unzipResult.get == (DataDirectory.bin / "optic-markdown")) + + } + + } + + def npmInstall(file: File) = { + val download = PrivateMethod[Try[File]]('npmInstall) + OpticMarkdownInstaller invokePrivate download(file) + } + + it("npm install works") { + val unzippedDirectory = download( + "https://registry.npmjs.org/optic-markdown/-/optic-markdown-0.1.2.tgz", + "764f6cf924fdd8a899e26b8eb982d3a497878656" + ).map(unzip).flatten + + val result = npmInstall(unzippedDirectory.get) + + assert(result.isSuccess) + + } + + describe("Get or install") { + + it("will install instance when none exists") { + assert(OpticMarkdownInstaller.getOrInstall.isSuccess) + } + + it("will get the instance that is already installed next time") { + + assert(OpticMarkdownInstaller.getOrInstall.isSuccess) + + eventually (timeout(Span(5, Seconds))) { + assert(OpticMarkdownInstaller.getOrInstall.isSuccess) + } + + } + + it("is thread safe") { + + val a = Future(OpticMarkdownInstaller.getOrInstall.isSuccess) + val b = Future(OpticMarkdownInstaller.getOrInstall.isSuccess) + val c = Future(OpticMarkdownInstaller.getOrInstall.isSuccess) + + + val result = Await.result(Future.sequence(Seq(a,b,c)), 1 minute) + assert(result.forall(_ == true)) + } + + + } + +} diff --git a/server/src/main/resources/es7_2.12-0.1.1.jar b/server/src/main/resources/es7_2.12-0.1.1.jar index e9b6d69c40d0f0d0381a9bdcf09aaad288bda51d..c3e3232b897f427647e612046f90aa5a6ca484d3 100644 GIT binary patch delta 7478 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 SE`Sgq2hrl!o}i}>;Qs()VRL8z delta 7597 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 Date: Wed, 14 Mar 2018 15:29:36 -0400 Subject: [PATCH 08/10] Updated Lifecycle - inits data directory if missing (this probably ruined some demos) - Installs Optic Markdown --- .../opticdev/common/storage/DataDirectory.scala | 9 +++++++++ .../common/storage/DataDirectorySpec.scala | 14 ++++++++------ .../sdk/markdown/OpticMarkdownInstaller.scala | 6 +++--- .../com/opticdev/server/http/Lifecycle.scala | 16 +++++++++------- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala b/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala index e8d78f4d16..3a296533d9 100644 --- a/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala +++ b/common/src/main/scala-2.12/com/opticdev/common/storage/DataDirectory.scala @@ -1,5 +1,6 @@ package com.opticdev.common.storage +import better.files.File import com.opticdev.common.PlatformConstants object DataDirectory { @@ -36,4 +37,12 @@ object DataDirectory { buildDirectoryStructure } + def init : File = { + if (!hasValidStructure) { + reset + } + + DataDirectory.root + } + } diff --git a/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala b/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala index 95b261d261..7b1f5009ff 100644 --- a/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala +++ b/common/src/test/scala-2.12/com/opticdev/common/storage/DataDirectorySpec.scala @@ -11,12 +11,20 @@ class DataDirectorySpec extends FunSpec { assert(PlatformConstants.dataDirectory.notExists) } + it("can init when missing or corrupt") { + DataDirectory.delete + DataDirectory.init + assert(DataDirectory.hasValidStructure) + } + describe("can detect invalid structure") { it("when empty") { + DataDirectory.root.list.foreach(_.delete(true)) assert(!DataDirectory.hasValidStructure) } it("when a folder is missing") { + DataDirectory.delete DataDirectory.root.createIfNotExists(asDirectory = true) DataDirectory.packages.createIfNotExists(asDirectory = true) DataDirectory.compiled.createIfNotExists(asDirectory = true) @@ -24,11 +32,5 @@ class DataDirectorySpec extends FunSpec { } } - - it("can create the directory with valid structure") { - DataDirectory.delete - DataDirectory.buildDirectoryStructure - assert(DataDirectory.hasValidStructure) - } } diff --git a/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala index 673516ed56..7831e21ad3 100644 --- a/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala +++ b/sdk/src/main/scala-2.12/com.opticdev/sdk/markdown/OpticMarkdownInstaller.scala @@ -59,7 +59,7 @@ object OpticMarkdownInstaller { target.delete(true) //will throw if doesn't work - new URL(opticMDTar) #> target.toJava !! + new URL(opticMDTar) #> target.toJava !!(ProcessLogger(stdout append _, stderr append _)) assert(target.sha1.toLowerCase == opticMDTarSum.toLowerCase, "optic-markdown sha does not match. Download failed") @@ -76,14 +76,14 @@ object OpticMarkdownInstaller { DataDirectory.bin.pathAsString, ) - unzip.!! + unzip.!!(ProcessLogger(stdout append _, stderr append _)) val mv: Seq[String] = Seq( "mv", (DataDirectory.bin / "package").pathAsString, mdDirectory.pathAsString ) - mv.!! + mv.!!(ProcessLogger(stdout append _, stderr append _)) file.delete(true) assert(mdDirectory.isDirectory, "Optic Markdown could not be unzipped.") diff --git a/server/src/main/scala-2.12/com/opticdev/server/http/Lifecycle.scala b/server/src/main/scala-2.12/com/opticdev/server/http/Lifecycle.scala index 68fef3331c..8cd321eecb 100644 --- a/server/src/main/scala-2.12/com/opticdev/server/http/Lifecycle.scala +++ b/server/src/main/scala-2.12/com/opticdev/server/http/Lifecycle.scala @@ -3,6 +3,7 @@ package com.opticdev.server.http import java.io.{BufferedReader, InputStreamReader} import better.files.File +import com.opticdev.common.storage.DataDirectory import com.opticdev.core.sourcegear.project.Project import com.opticdev.core.sourcegear.project.config.ProjectFile import com.opticdev.opm.PackageManager @@ -14,19 +15,20 @@ import com.opticdev.server.state.ProjectsManager import scala.io.Source import scala.util.Try + object Lifecycle extends App { - //tap the OpticMarkdown Installer in case this is a fresh install - OpticMarkdownInstaller.getOrInstall + //init the data directory if missing + DataDirectory.init //@todo load parsers dynamically. - val jar = this.getClass.getClassLoader.getResource("es7_2.12-0.1.0.jar").getFile + val jar = this.getClass.getClassLoader.getResource("es7_2.12-0.1.1.jar").getFile val parserBase = Try { ParserStorage.writeToStorage(File(jar)) SourceParserManager.installParser(jar).get }.getOrElse { val withoutFileExtension = jar.substring(5) - val pathAsString = (File(withoutFileExtension).parent.parent / "es7_2.12-0.1.0.jar").pathAsString + val pathAsString = (File(withoutFileExtension).parent.parent / "es7_2.12-0.1.1.jar").pathAsString ParserStorage.writeToStorage(File(pathAsString)) SourceParserManager.installParser(pathAsString).get } @@ -37,13 +39,13 @@ object Lifecycle extends App { implicit val projectsManager: ProjectsManager = new ProjectsManager() implicit val actorCluster = projectsManager.actorCluster - //manually adding projects for testing -// val project = Project.fromProjectFile(new ProjectFile(File("test-examples/resources/tmp/test_project/optic.yaml"))).get -// projectsManager.loadProject(project) startup def startup = { Server.start() + + //tap the OpticMarkdown Installer in case this is a fresh install + OpticMarkdownInstaller.getOrInstall } From 55867449bdcaa8534524e1b34e2ef7826b01c93a Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Wed, 14 Mar 2018 21:34:51 -0400 Subject: [PATCH 09/10] Fixed issue with loader not sending initial state --- .../com/opticdev/server/state/ProjectsManager.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala b/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala index f3cb911757..b8d3be58f1 100644 --- a/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala +++ b/server/src/main/scala-2.12/com/opticdev/server/state/ProjectsManager.scala @@ -39,6 +39,10 @@ class ProjectsManager { AgentConnection.broadcastUpdate(StatusUpdate(project.name, status)) }) + + //send an initial status update + AgentConnection.broadcastUpdate(StatusUpdate(project.name, project.projectStatus)) + projectsStore = projectsStore :+ project arrowStore = arrowStore + (project -> new Arrow(project)) if (projectsStore.size > MAX_PROJECTS) { From 584d2744b83370b6a8bfdb8d43a1f2a939fc04a6 Mon Sep 17 00:00:00 2001 From: Aidan Cunniffe Date: Wed, 14 Mar 2018 21:42:41 -0400 Subject: [PATCH 10/10] Bumped version to 0.1.2 --- build.sbt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 952540c4f0..5309489599 100644 --- a/build.sbt +++ b/build.sbt @@ -2,9 +2,10 @@ name := "optic-core" organization := "com.opticdev" -version := "0.1.0" +val appVersion = "0.1.1" + +version := appVersion -val appVersion = "0.1.0" val commonSettings: Seq[Def.Setting[_]] = Seq( version := appVersion,