-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Move into morphir from org.morphir * File ops * Reorg and starting to update IR types * Added a Show type class instance for name * Include path support * Added support for all Name variations * Cleanup tests and add AccessControlled * Started work on encoding * Provide a sealed coproduct hiearchy for ExprKind * Rollup common Expr functionality * Add full representation of Value AST * Add remaining types for Type Expressions and normalize attributes parameter order * Add attribute mapping for Types * Encode Name as a Value class * This isn't elm so promote some of these functions to methods * attribute mapping * attribute mapping * Working on the VFile abstraction * Working on the VFile abstraction * Major cleanup * Workspace work * Start of work to integrate Scala backend
- Loading branch information
1 parent
5a76745
commit 91609c1
Showing
20 changed files
with
480 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
morphir/cli/shared/src/main/scala/org/morphir/workspace/Workspace.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.morphir.workspace | ||
|
||
import zio._ | ||
|
||
import org.morphir.workspace.project.model.ProjectDir | ||
|
||
object Workspace { | ||
trait Service { | ||
def resolveProjectDir(maybeProjectDir: Option[ProjectDir]): UIO[ProjectDir] | ||
} | ||
|
||
val live: ULayer[Workspace] = ZLayer.succeed(LiveWorkspace()) | ||
|
||
private case class LiveWorkspace() extends Service { | ||
def resolveProjectDir(maybeProjectDir: Option[ProjectDir]): UIO[ProjectDir] = | ||
UIO.succeed(maybeProjectDir.getOrElse(ProjectDir.fromWorkingDir)) | ||
} | ||
|
||
} |
187 changes: 187 additions & 0 deletions
187
morphir/cli/shared/src/main/scala/org/morphir/workspace/config/ConfigLayer.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
package org.morphir.workspace.config | ||
|
||
import java.io.File | ||
|
||
import com.typesafe.config.ConfigFactory | ||
import izumi.reflect.Tags.Tag | ||
import zio.config.magnolia.DeriveConfigDescriptor.descriptor | ||
import zio.config.typesafe._ | ||
import zio.config.{ ConfigSource, _ } | ||
import zio.{ Has, Task, ZIO, ZLayer } | ||
|
||
/** | ||
* Property resolution order: | ||
* - command line arguments | ||
* - system properties | ||
* - environment variables | ||
* - HOCON file | ||
* - properties file | ||
*/ | ||
object ConfigLayer { | ||
|
||
def createLayer[T: Tag]( | ||
args: List[String], | ||
descriptor: ConfigDescriptor[T] | ||
): ZIO[Any, Throwable, ZLayer[Any, ReadError[String], Has[T]]] = | ||
for { | ||
sources <- createSources(args) | ||
desc = descriptor.from(unifySources(sources)) | ||
l = ZLayer.fromEffect(ZIO.fromEither(read(desc))) | ||
} yield l | ||
|
||
private def unifySources(sources: List[ConfigSource]): ConfigSource = | ||
sources.reduce((s1, s2) => s1.orElse(s2)) | ||
|
||
private def createSources(args: List[String]): ZIO[Any, Throwable, List[ConfigSource]] = { | ||
val NO_PROFILE = "" | ||
val PROD = "prod" | ||
for { | ||
argsConfigSource <- ZIO.succeed(ConfigSource.fromCommandLineArgs(args, Some('.'), Some(','))) | ||
systemPropsSource <- ConfigSource.fromSystemProperties(Some('_'), Some(',')) | ||
envPropsSource <- ConfigSource.fromSystemEnv(Some('_'), Some(',')) | ||
profile = getProfile(unifySources(List(argsConfigSource, systemPropsSource, envPropsSource))) | ||
appHoconSource <- profile.hoconFile match { | ||
case Some(value) => | ||
fromHoconResource(s"/$value") | ||
case None => | ||
fromHoconResourceIfPresent( | ||
profile.profile.map(_.toLowerCase()).getOrElse(NO_PROFILE) match { | ||
case NO_PROFILE => "/morphir-workspace.conf" | ||
case PROD => "/morphir-workspace.conf" | ||
case profile => s"/morphir-workspace-$profile.conf" | ||
} | ||
) | ||
} | ||
appPropsSource <- profile.propertiesFile match { | ||
case Some(value) => | ||
fromPropertiesResource(s"/$value", Some('.'), Some(',')) | ||
case None => | ||
fromPropertiesResourceIfPresent( | ||
profile.profile.map(_.toLowerCase()).getOrElse(NO_PROFILE) match { | ||
case NO_PROFILE => "/morphir-workspace.properties" | ||
case PROD => "/morphir-workspace.properties" | ||
case profile => s"/morphir-workspace-$profile.properties" | ||
}, | ||
Some('.'), | ||
Some(',') | ||
) | ||
} | ||
} yield List(argsConfigSource, systemPropsSource, envPropsSource, appHoconSource, appPropsSource) | ||
} | ||
|
||
/** | ||
* Will fail if the file is not found. | ||
* | ||
* @param file | ||
* @param keyDelimiter | ||
* @param valueDelimiter | ||
* @return | ||
*/ | ||
private def fromPropertiesResource[A]( | ||
file: String, | ||
keyDelimiter: Option[Char], | ||
valueDelimiter: Option[Char] | ||
): Task[ConfigSource] = | ||
for { | ||
properties <- ZIO.bracket( | ||
ZIO.effect(getClass.getResourceAsStream(file)) | ||
)(r => ZIO.effectTotal(r.close())) { inputStream => | ||
ZIO.effect { | ||
val properties = new java.util.Properties() | ||
properties.load(inputStream) | ||
properties | ||
} | ||
} | ||
} yield ConfigSource.fromProperties( | ||
properties, | ||
file, | ||
keyDelimiter, | ||
valueDelimiter | ||
) | ||
|
||
/** | ||
* Will not fail if file is not found. Instead it will create a ConfigSource from an empty java.util.Properties | ||
* | ||
* @param file | ||
* @param keyDelimiter | ||
* @param valueDelimiter | ||
* @return | ||
*/ | ||
private def fromPropertiesResourceIfPresent[A]( | ||
file: String, | ||
keyDelimiter: Option[Char], | ||
valueDelimiter: Option[Char] | ||
): Task[ConfigSource] = | ||
for { | ||
properties <- ZIO.bracket( | ||
ZIO.effect(getClass.getResourceAsStream(file)) | ||
)(r => ZIO.effectTotal(if (r != null) r.close())) { inputStream => | ||
ZIO.effect { | ||
val properties = new java.util.Properties() | ||
if (inputStream != null) { | ||
properties.load(inputStream) | ||
} | ||
properties | ||
} | ||
} | ||
} yield ConfigSource.fromProperties( | ||
properties, | ||
file, | ||
keyDelimiter, | ||
valueDelimiter | ||
) | ||
|
||
/** | ||
* Will fail if the file is not found. | ||
* | ||
* @param file | ||
* @return | ||
*/ | ||
private def fromHoconResource[A](file: String): Task[ConfigSource] = | ||
for { | ||
resourceURI <- ZIO | ||
.fromOption(Option(getClass.getResource(file)).map(_.toURI)) | ||
.mapError(_ => new RuntimeException(s"$file not found in classpath!")) | ||
fileInstance <- Task(new File(resourceURI)) | ||
configSource <- ZIO | ||
.fromEither( | ||
TypesafeConfigSource.fromTypesafeConfig(ConfigFactory.parseFile(fileInstance).resolve) | ||
) | ||
.mapError(error => new RuntimeException(error)) | ||
} yield configSource | ||
|
||
/** | ||
* Will not fail if file is not found. Instead it will create a ConfigSource from an empty HOCON string | ||
* | ||
* @param file | ||
* @return | ||
*/ | ||
private def fromHoconResourceIfPresent[A](file: String): Task[ConfigSource] = | ||
Option(getClass.getResource(file)).map(_.toURI) match { | ||
case Some(uri) => | ||
Task(new File(uri)).flatMap(fileInstance => | ||
TypesafeConfigSource | ||
.fromTypesafeConfig(ConfigFactory.parseFile(fileInstance).resolve) match { | ||
case Left(value) => Task.fail(new RuntimeException(value)) | ||
case Right(value) => Task.succeed(value) | ||
} | ||
) | ||
case None => Task.succeed(ConfigSource.empty) | ||
} | ||
|
||
private final case class Profile( | ||
profile: Option[String], | ||
hoconFile: Option[String], | ||
propertiesFile: Option[String] | ||
) | ||
|
||
private def getProfile(configSource: ConfigSource): Profile = { | ||
val desc = descriptor[Profile] | ||
val params = desc.from(configSource) | ||
read(params) match { | ||
case Left(_) => Profile(None, None, None) | ||
case Right(value) => value | ||
} | ||
} | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
morphir/cli/shared/src/main/scala/org/morphir/workspace/config/WorkspaceProperties.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.morphir.workspace.config | ||
import org.morphir.workspace.config.project.{ ProjectInfo, ProjectSet } | ||
import zio.config._ | ||
|
||
final case class WorkspaceProperties(projects: ProjectSet) { | ||
lazy val projectList: List[ProjectInfo] = projects.toMap.map(ProjectInfo.fromTuple).toList | ||
} | ||
|
||
object WorkspaceProperties { | ||
val config: ConfigDescriptor[WorkspaceProperties] = | ||
ProjectSet.configDescriptor("projects")( | ||
WorkspaceProperties.apply, | ||
WorkspaceProperties.unapply | ||
) | ||
} |
47 changes: 47 additions & 0 deletions
47
morphir/cli/shared/src/main/scala/org/morphir/workspace/config/project.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package org.morphir.workspace.config | ||
|
||
import io.estatico.newtype.macros.newtype | ||
import zio.config._, ConfigDescriptor._ | ||
|
||
import scala.language.implicitConversions | ||
|
||
object project { | ||
|
||
final case class ProjectProperties(sourceDirectory: SourceDirectory) | ||
object ProjectProperties { | ||
implicit val configDescriptor: ConfigDescriptor[ProjectProperties] = | ||
(string("sourceDirectory")(SourceDirectory.apply, (srcDir: SourceDirectory) => Option(srcDir.rawPath)))( | ||
ProjectProperties.apply, | ||
ProjectProperties.unapply | ||
) | ||
} | ||
|
||
@newtype case class SourceDirectory(rawPath: String) | ||
@newtype case class ProjectName(displayName: String) | ||
object ProjectName { | ||
def unapply(projectName: ProjectName): Option[String] = Option(projectName.displayName) | ||
|
||
implicit val configDescriptor: ConfigDescriptor[ProjectName] = | ||
string(ProjectName.apply, ProjectName.unapply) | ||
} | ||
@newtype case class ProjectSet(toMap: Map[String, ProjectProperties]) | ||
object ProjectSet { | ||
def configDescriptor(path: String): ConfigDescriptor[ProjectSet] = | ||
map(path)(ProjectProperties.configDescriptor)(ProjectSet.apply, ProjectSet.unapply) | ||
|
||
def configDescriptor: ConfigDescriptor[ProjectSet] = | ||
map(ProjectProperties.configDescriptor)(ProjectSet.apply, ProjectSet.unapply) | ||
|
||
def unapply(arg: ProjectSet): Option[Map[String, ProjectProperties]] = Option(arg.toMap) | ||
} | ||
|
||
final case class ProjectInfo(name: ProjectName, properties: ProjectProperties) | ||
|
||
object ProjectInfo { | ||
def apply(tuple: (ProjectName, ProjectProperties)): ProjectInfo = | ||
ProjectInfo(tuple._1, tuple._2) | ||
|
||
def fromTuple(tuple: (String, ProjectProperties)): ProjectInfo = | ||
ProjectInfo(ProjectName(tuple._1), tuple._2) | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
morphir/cli/shared/src/main/scala/org/morphir/workspace/package.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.morphir | ||
|
||
import org.morphir.workspace.project.model.ProjectDir | ||
import zio.{ Has, ZIO } | ||
|
||
package object workspace { | ||
type Workspace = Has[Workspace.Service] | ||
|
||
def resolveProjectDir(maybeProjectDir: Option[ProjectDir]): ZIO[Workspace, Nothing, ProjectDir] = | ||
ZIO.accessM[Workspace](_.get.resolveProjectDir(maybeProjectDir)) | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
morphir/cli/shared/src/main/scala/org/morphir/workspace/project/ElmProject.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.morphir.workspace.project | ||
|
||
import io.estatico.newtype.macros.newtype | ||
import org.morphir.workspace.project.ElmProject.{ ExposedModuleNames, PackageName } | ||
import org.morphir.workspace.config.project.SourceDirectory | ||
|
||
import scala.language.implicitConversions | ||
|
||
case class ElmProject(name: PackageName, sourceDirectory: SourceDirectory, exposedModules: ExposedModuleNames) {} | ||
|
||
object ElmProject { | ||
@newtype case class PackageName(name: String) | ||
@newtype case class ModuleName(name: String) | ||
@newtype case class ExposedModuleNames(toList: List[ModuleName]) | ||
} |
Oops, something went wrong.