Skip to content

Commit

Permalink
Merge branch 'release/1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
acunniffe committed May 16, 2018
2 parents 57007d2 + 63fd3ec commit d38c063
Show file tree
Hide file tree
Showing 177 changed files with 3,154 additions and 726 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ package com.opticdev.arrow.changes
import play.api.libs.json.{JsArray, JsObject, JsValue, Json}
import JsonImplicits.changeGroupFormat
import com.opticdev.arrow.changes.evaluation.{BatchedChanges, Evaluation}
import com.opticdev.arrow.state.NodeKeyStore
import com.opticdev.core.sourcegear.SourceGear
import com.opticdev.core.sourcegear.project.OpticProject

import scala.util.Try

case class ChangeGroup(changes: OpticChange*) {

def evaluate(sourcegear: SourceGear, project: Option[OpticProject] = None): BatchedChanges = {
def evaluate(sourcegear: SourceGear, project: Option[OpticProject] = None)(implicit nodeKeyStore: NodeKeyStore): BatchedChanges = {
Evaluation.forChangeGroup(this, sourcegear, project)
}

def evaluateAndWrite(sourcegear: SourceGear, project: Option[OpticProject] = None) : Try[BatchedChanges] = Try {
def evaluateAndWrite(sourcegear: SourceGear, project: Option[OpticProject] = None)(implicit nodeKeyStore: NodeKeyStore) : Try[BatchedChanges] = Try {
val evaluated = evaluate(sourcegear, project)
if (evaluated.isSuccess) {
evaluated.flushToDisk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import com.opticdev.arrow.changes.location.{AsChildOf, InsertLocation, RawPositi
import com.opticdev.arrow.graph.KnowledgeGraphImplicits.{DirectTransformation, TransformationChanges}
import com.opticdev.arrow.results.ModelOption
import com.opticdev.common.PackageRef
import com.opticdev.core.sourcegear.sync.FilePatch
import com.opticdev.sdk.descriptions.transformation.Transformation
import com.opticdev.sdk.descriptions.{Schema, SchemaRef}
import play.api.libs.json._

import com.opticdev.common.fileFormat
import scala.util.{Failure, Success, Try}

object JsonImplicits {
Expand All @@ -17,7 +18,6 @@ object JsonImplicits {
import SchemaRef.schemaRefFormats



implicit val schemaFormat = new Format[Schema] {
override def reads(json: JsValue) = {
val schemaJson = json.as[JsObject]
Expand All @@ -29,17 +29,6 @@ object JsonImplicits {
override def writes(o: Schema) = o.toJson
}

//File
implicit val fileFormat = new Format[File] {
override def reads(json: JsValue) = {
JsSuccess(Try(File(json.as[JsString].value)).get)
}

override def writes(o: File) = {
JsString(o.pathAsString)
}
}

implicit val modelOptionsFormat = Json.format[ModelOption]

//Location
Expand All @@ -66,6 +55,11 @@ object JsonImplicits {
//Clear Search Lines
implicit val clearSearchLinesFormat = Json.format[ClearSearchLines]

//Put Update
implicit val putUpdateFormat = Json.format[PutUpdate]
//File Contents Update
implicit val fileContentsUpdateFormat = Json.format[FileContentsUpdate]

implicit val opticChangeFormat = Json.format[OpticChange]

implicit val changeGroupFormat = new Format[ChangeGroup] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import com.opticdev.sdk.descriptions.{Schema, SchemaRef}
import play.api.libs.json.{JsObject, JsString, JsValue, Json}
import JsonImplicits.opticChangeFormat
import com.opticdev.arrow.results.ModelOption
import com.opticdev.core.sourcegear.graph.model.LinkedModelNode
import com.opticdev.core.sourcegear.sync.{FilePatch, FilePatchTrait, SyncPatch}
import com.opticdev.parsers.graph.CommonAstNode

sealed trait OpticChange {
def asJson = Json.toJson[OpticChange](this)
Expand Down Expand Up @@ -47,9 +50,14 @@ case class RunTransformation(transformationChanges: TransformationChanges,
override def asJson = Json.toJson[OpticChange](this)
}


case class RawInsert(content: String, position: RawPosition) extends OpticChange

case class ClearSearchLines(file: File, prefixPattern: String = "^\\s*\\/\\/\\/.*") extends OpticChange {
import JsonImplicits.clearSearchLinesFormat
val regex = prefixPattern.r
}
}

case class PutUpdate(id: String, newModel: JsObject) extends OpticChange

case class FileContentsUpdate(file: File, originalFileContents: String, newFileContents: String) extends OpticChange with FilePatchTrait
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,41 @@ package com.opticdev.arrow.changes.evaluation

import better.files.File
import com.opticdev.arrow.changes._
import com.opticdev.arrow.state.NodeKeyStore
import com.opticdev.core.sourcegear.{Render, SourceGear}
import com.opticdev.core.sourcegear.project.OpticProject
import com.opticdev.core.sourcegear.project.{OpticProject, ProjectBase}
import com.opticdev.core.sourcegear.project.monitoring.FileStateMonitor
import com.opticdev.marvin.common.helpers.LineOperations
import com.opticdev.sdk.RenderOptions
import com.opticdev.sdk.descriptions.transformation.{SingleModel, StagedNode, TransformationResult}
import play.api.libs.json.JsObject

import scala.util.Try
import scala.util.{Failure, Success, Try}
import com.opticdev.core.sourcegear.context.SDKObjectsResolvedImplicits._
import com.opticdev.core.sourcegear.mutate.MutationSteps.{collectFieldChanges, combineChanges, handleChanges}
import com.opticdev.core.sourcegear.objects.annotations.{NameAnnotation, ObjectAnnotationRenderer, SourceAnnotation}
object Evaluation {

def forChange(opticChange: OpticChange, sourcegear: SourceGear, project: Option[OpticProject] = None)(implicit filesStateMonitor: FileStateMonitor): ChangeResult = opticChange match {
def forChange(opticChange: OpticChange, sourcegear: SourceGear, projectOption: Option[ProjectBase] = None)(implicit filesStateMonitor: FileStateMonitor, nodeKeyStore: NodeKeyStore): ChangeResult = opticChange match {
case im: InsertModel => {

val stagedNode = StagedNode(im.schema.schemaRef, im.value, Some(RenderOptions(
lensId = im.lensId
)))

val renderedTry = Render.fromStagedNode(stagedNode)(sourcegear)

require(renderedTry.isSuccess, "Could not render model "+ renderedTry.failed.get.toString)

val generatedNode = (renderedTry.get._1, renderedTry.get._2)

val resolvedLocation = im.atLocation.get.resolveToLocation(sourcegear).get

val changeResult = InsertCode.atLocation(generatedNode, im.atLocation.get.file, resolvedLocation)

if (changeResult.isSuccess) {
changeResult.asFileChanged.stageContentsIn(filesStateMonitor)
}

changeResult
}
case rt: RunTransformation => {

val schema = sourcegear.findSchema(rt.transformationChanges.transformation.resolvedOutput(sourcegear)).get

require(rt.inputValue.isDefined, "Transformation must have an input value specified")

val transformationTry = rt.transformationChanges.transformation.transformFunction.transform(rt.inputValue.get, rt.answers.getOrElse(JsObject.empty))
Expand All @@ -53,21 +49,69 @@ object Evaluation {
require(schema.validate(stagedNode.value), "Result of transformation did not conform to schema "+ schema.schemaRef.full)

val prefixedFlatContent = sourcegear.flatContext.prefix(rt.transformationChanges.transformation.packageId.packageId)

val generatedNode = Render.fromStagedNode(stagedNode)(sourcegear, prefixedFlatContent).get

val updatedString = if (rt.objectSelection.isDefined) {
val objName = rt.objectSelection.get
ObjectAnnotationRenderer.renderToFirstLine(
generatedNode._3.renderer.parser.get.inlineCommentPrefix,
Vector(SourceAnnotation(objName, rt.transformationChanges.transformation.transformationRef, rt.answers)),
generatedNode._2)
} else generatedNode._2

val resolvedLocation = rt.location.get.resolveToLocation(sourcegear).get
val changeResult = InsertCode.atLocation((generatedNode._1, updatedString), rt.location.get.file, resolvedLocation)
if (changeResult.isSuccess) {
changeResult.asFileChanged.stageContentsIn(filesStateMonitor)
}

changeResult

val changeResult = InsertCode.atLocation((generatedNode._1, generatedNode._2), rt.location.get.file, resolvedLocation)
}
case pu: PutUpdate => {
val changeResult : ChangeResult = Try {
val modelNode = nodeKeyStore.lookupId(pu.id).get
implicit val project = projectOption.get
implicit val actorCluster = project.actorCluster
implicit val sourceGearContext = modelNode.getContext.get
val file = modelNode.fileNode.get.toFile
implicit val fileContents = filesStateMonitor.contentsForFile(file).get
val changes = collectFieldChanges(modelNode, pu.newModel).filter(_.isSuccess).map(_.get)
val astChanges = handleChanges(changes)
val combined = combineChanges(astChanges)
val output = combined.toString()

FileChanged(file, output)
} match {
case s: Success[FileChanged] => s.get
case Failure(ex) => FailedToChange(ex)
}

if (changeResult.isSuccess) {
changeResult.asFileChanged.stageContentsIn(filesStateMonitor)
}

changeResult

}

case fileContentsUpdate: FileContentsUpdate => {

val changeResult = Try {
require(fileContentsUpdate.file.exists, s"File '${fileContentsUpdate.file}' to update must exist")
val currentContents = filesStateMonitor.contentsForFile(fileContentsUpdate.file).get
require(currentContents == fileContentsUpdate.originalFileContents, s"The contents of File '${fileContentsUpdate.file}' have changed since patch was generated. Aborted Patch.")
FileChanged(fileContentsUpdate.file, fileContentsUpdate.newFileContents)
} match {
case s: Success[FileChanged] => s.get
case Failure(ex) => FailedToChange(ex)
}

if (changeResult.isSuccess) {
changeResult.asFileChanged.stageContentsIn(filesStateMonitor)
}

changeResult
}

//cleanup
case cSL: ClearSearchLines => {
Expand All @@ -94,7 +138,7 @@ object Evaluation {
}
}

def forChangeGroup(changeGroup: ChangeGroup, sourcegear: SourceGear, project: Option[OpticProject] = None) = {
def forChangeGroup(changeGroup: ChangeGroup, sourcegear: SourceGear, project: Option[OpticProject] = None)(implicit nodeKeyStore: NodeKeyStore) = {

implicit val filesStateMonitor : FileStateMonitor = {
//hook up to existing in-memory representation of files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import com.opticdev.sdk.descriptions.transformation.Transformation

import scala.util.Try
import com.opticdev.core.sourcegear.context.SDKObjectsResolvedImplicits._
case class TransformationResult(score: Int, transformationChange: TransformationChanges, context : ArrowContextBase, inputValue: Option[JsObject])(implicit sourcegear: SourceGear, project: OpticProject, knowledgeGraph: KnowledgeGraph) extends Result {
case class TransformationResult(score: Int, transformationChange: TransformationChanges, context : ArrowContextBase, inputValue: Option[JsObject], objectSelection: Option[String])(implicit sourcegear: SourceGear, project: OpticProject, knowledgeGraph: KnowledgeGraph) extends Result {

override def changes : ChangeGroup = transformationChange match {
case dt: DirectTransformation => {
Expand All @@ -25,14 +25,14 @@ case class TransformationResult(score: Int, transformationChange: Transformation

def modelOptions = project.projectGraphWrapper.query((node)=> {
node.value match {
case mn: BaseModelNode => mn.schemaId == transformationChange.transformation.resolvedInput
case mn: BaseModelNode => mn.schemaId == transformationChange.transformation.resolvedInput && mn.objectRef.isDefined
case _ => false
}
}).asInstanceOf[Set[BaseModelNode]]
.map(i=> {
implicit val sourceGearContext = TransformationSearch.sourceGearContext(i)
val expandedValue = i.expandedValue()
ModelOption(i.id, expandedValue, ModelOption.nameFromValue(i.schemaId.id, expandedValue))
ModelOption(i.id, expandedValue, i.objectRef.get.name)
}).toSeq.sortBy(_.name)

ChangeGroup(RunTransformation(
Expand All @@ -43,7 +43,7 @@ case class TransformationResult(score: Int, transformationChange: Transformation
if (insertLocationOption.isDefined) Seq(insertLocationOption.get) else Seq(), //@todo add all location options
None,
None,
None,
objectSelection,
if (inputValue.isDefined) None else Some(modelOptions)
))
}
Expand Down
15 changes: 0 additions & 15 deletions arrow/src/main/scala-2.12/com/opticdev/arrow/results/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,4 @@ package object results {
}

case class ModelOption(id: String, value: JsObject, name: String)
object ModelOption {
def nameFromValue(schemaId: String, value: JsObject): String = {

val asStrings = value.fields.sortBy(_._1).map(i=> {
val stringValue = i._2 match {
case o: JsObject => s"{${o.fields.size} fields}"
case a: JsArray => s"{${a.value.size} items}"
case a: JsValue => a.toString()
}
s"${i._1}: ${stringValue}"
})

s"${schemaId}(${asStrings.mkString(", ")})"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package com.opticdev.arrow.search

import com.opticdev.arrow.context.{ArrowContextBase, ModelContext}
import com.opticdev.arrow.graph.KnowledgeGraph
import com.opticdev.arrow.results.{GearResult, Result, TransformationResult}
import com.opticdev.core.sourcegear.project.OpticProject
import com.opticdev.core.sourcegear.{CompiledLens, SGContext, SourceGear}
import me.xdrop.fuzzywuzzy.FuzzySearch
import com.opticdev.arrow.graph.KnowledgeGraphImplicits._
import com.opticdev.arrow.results.TransformationResult
import com.opticdev.core.sourcegear.actors.ParseSupervisorSyncAccess
import com.opticdev.core.sourcegear.graph.model.{BaseModelNode, ModelNode}
import com.opticdev.core.sourcegear.context.SDKObjectsResolvedImplicits._
import com.opticdev.core.sourcegear.graph.model.BaseModelNode
import com.opticdev.core.sourcegear.project.OpticProject
import com.opticdev.core.sourcegear.{SGContext, SourceGear}
import me.xdrop.fuzzywuzzy.FuzzySearch

import scala.util.Try
import com.opticdev.core.sourcegear.context.SDKObjectsResolvedImplicits._
object TransformationSearch {

def search(context: ArrowContextBase)(implicit sourcegear: SourceGear, project: OpticProject, knowledgeGraph: KnowledgeGraph) : Vector[TransformationResult] =
Expand All @@ -25,7 +25,7 @@ object TransformationSearch {
}.getOrElse(c.value)

//@todo rank based on usage over time...
transformations.map(t=> TransformationResult(100, t, context, Some(inputValue)))
transformations.map(t=> TransformationResult(100, t, context, Some(inputValue), c.flatten.objectRef.map(_.name)))
})
case _ => Vector()
}
Expand All @@ -36,6 +36,7 @@ object TransformationSearch {
FuzzySearch.tokenSetPartialRatio(i.yields, query),
DirectTransformation(i, i.resolvedOutput),
context,
None,
None
)
}).toVector
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.opticdev.server.state
package com.opticdev.arrow.state

import better.files.File
import com.opticdev.core.sourcegear.graph.model.LinkedModelNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ object ExampleSourcegears {
override val lensSet = new LensSet()
override val schemas = Set(schemaModel, schemaRoute, schemaForm, schemaFetch)
override val transformations = Set(
Transformation("Model -> Route", transformationPackage, schemaModel.schemaRef, schemaRoute.schemaRef, Transformation.emptyAskSchema, ""),
Transformation("Route -> Form", transformationPackage, schemaRoute.schemaRef, schemaForm.schemaRef, Transformation.emptyAskSchema, ""),
Transformation("Route -> Fetch", transformationPackage, schemaRoute.schemaRef, schemaFetch.schemaRef, Transformation.emptyAskSchema, "")
Transformation("Model -> Route", "m2r", transformationPackage, schemaModel.schemaRef, schemaRoute.schemaRef, Transformation.emptyAskSchema, ""),
Transformation("Route -> Form", "r2f", transformationPackage, schemaRoute.schemaRef, schemaForm.schemaRef, Transformation.emptyAskSchema, ""),
Transformation("Route -> Fetch", "r2fe", transformationPackage, schemaRoute.schemaRef, schemaFetch.schemaRef, Transformation.emptyAskSchema, "")
)
override val flatContext: FlatContext = FlatContext(None, Map(
"optic:test" -> FlatContext(Some(PackageRef("optic:test", "0.1.0")), Map(
Expand Down
Loading

0 comments on commit d38c063

Please sign in to comment.