Skip to content

Commit

Permalink
Merge pull request #300 from INCATools/issue-299
Browse files Browse the repository at this point in the history
hiding stacktrace for DOSDPError instances
  • Loading branch information
balhoff authored Dec 1, 2021
2 parents f62fa9a + bc7faf4 commit 92ef1cc
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 45 deletions.
2 changes: 0 additions & 2 deletions src/main/scala/org/monarchinitiative/dosdp/Utilities.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,4 @@ object Utilities {
} yield ontology
}

def isDirectory(path: String): RIO[Blocking, Boolean] = effectBlocking(Files.isDirectory(Paths.get(path)))

}
5 changes: 4 additions & 1 deletion src/main/scala/org/monarchinitiative/dosdp/cli/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import scala.io.Source
@ProgName("dosdp-tools")
sealed trait Config {

def common: CommonOptions

def run: ZIO[ZEnv, DOSDPError, Unit]

}
Expand Down Expand Up @@ -49,7 +51,8 @@ final case class CommonOptions(
tableFormat: String = "tsv",
@HelpMessage("List of patterns (without file extension) to process in batch (space separated, enclose list in quotes)")
@ValueDescription("names")
batchPatterns: MultiArgList = MultiArgList(Nil)
batchPatterns: MultiArgList = MultiArgList(Nil),
verbose: Boolean = false
) {

def inputDOSDP: IO[DOSDPError, DOSDP] = inputDOSDPFrom(template)
Expand Down
16 changes: 7 additions & 9 deletions src/main/scala/org/monarchinitiative/dosdp/cli/Docs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package org.monarchinitiative.dosdp.cli
import com.github.tototoshi.csv.CSVFormat
import org.geneontology.owl.differ.ManchesterSyntaxOWLObjectRenderer
import org.geneontology.owl.differ.shortform.MarkdownLinkShortFormProvider
import org.monarchinitiative.dosdp.Utilities.isDirectory
import org.monarchinitiative.dosdp.cli.Generate.readFillers
import org.monarchinitiative.dosdp.cli.Prototype.OboInOwlSource
import org.monarchinitiative.dosdp.{DOSDP, DocsMarkdown, ExpandedDOSDP, Prefixes}
Expand All @@ -16,6 +15,7 @@ import zio._
import zio.blocking._

import java.io.{File, PrintWriter}
import java.nio.file.{Files, Paths}
import scala.jdk.CollectionConverters._

object Docs {
Expand All @@ -26,7 +26,7 @@ object Docs {
def run(config: DocsConfig): ZIO[ZEnv, DOSDPError, Unit] = {
for {
sepFormat <- ZIO.fromEither(Config.tabularFormat(config.common.tableFormat))
targets <- determineTargets(config).mapError(e => DOSDPError("Failure to configure input or output", e))
targets <- determineTargets(config)
ontologyOpt <- config.common.ontologyOpt
ontology = ontologyOpt.getOrElse(OWLManager.createOWLOntologyManager().createOntology())
_ <- ZIO.foreach_(targets)(processTarget(_, sepFormat, config, ontology))
Expand Down Expand Up @@ -73,16 +73,14 @@ object Docs {
} yield DocsMarkdown.indexMarkdown(dosdpsAndOutfiles)
}

private def determineTargets(config: DocsConfig): ZIO[Blocking, Throwable, List[DocsTarget]] = {
private def determineTargets(config: DocsConfig): ZIO[Blocking, DOSDPError, List[DocsTarget]] = {
val patternNames = config.common.batchPatterns.items
if (patternNames.nonEmpty) for {
_ <- ZIO.effectTotal(scribe.info("Running in batch mode"))
_ <- ZIO.ifM(isDirectory(config.common.template))(ZIO.unit,
ZIO.fail(DOSDPError("\"--template must be a directory in batch mode\"")))
_ <- ZIO.ifM(isDirectory(config.infile))(ZIO.unit,
ZIO.fail(DOSDPError("\"--infile must be a directory in batch mode\"")))
_ <- ZIO.ifM(isDirectory(config.common.outfile))(ZIO.unit,
ZIO.fail(DOSDPError("\"--outfile must be a directory in batch mode\"")))
_ <- ZIO.foreach_(patternNames)(pattern => ZIO.when(!Files.exists(Paths.get(config.common.template, s"$pattern.yaml")))(ZIO.fail(DOSDPError(s"Pattern doesn't exist: $pattern"))))
_ <- ZIO.when(!Files.isDirectory(Paths.get(config.common.template)))(ZIO.fail(DOSDPError("\"--template must be a directory in batch mode\"")))
_ <- ZIO.when(!Files.isDirectory(Paths.get(config.infile)))(ZIO.fail(DOSDPError("\"--infile must be a directory in batch mode\"")))
_ <- ZIO.when(!Files.isDirectory(Paths.get(config.common.outfile)))(ZIO.fail(DOSDPError("\"--outfile must be a directory in batch mode\"")))
} yield patternNames.map { pattern =>
val templateFileName = s"${config.common.template}/$pattern.yaml"
val dataExtension = config.common.tableFormat.toLowerCase
Expand Down
21 changes: 10 additions & 11 deletions src/main/scala/org/monarchinitiative/dosdp/cli/Generate.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package org.monarchinitiative.dosdp.cli

import java.io.{File, StringReader}

import cats.implicits._
import com.github.tototoshi.csv.{CSVFormat, CSVReader}
import org.monarchinitiative.dosdp.Utilities.isDirectory
import org.monarchinitiative.dosdp.cli.Config.{AllAxioms, AnnotationAxioms, AxiomKind, LogicalAxioms}
import org.monarchinitiative.dosdp.{AxiomType => _, _}
import org.phenoscape.scowl._
import org.semanticweb.owlapi.model._
import org.semanticweb.owlapi.model.parameters.Imports
import zio._
import zio.console._
import zio.blocking._

import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Paths}
import scala.io.Source
import scala.jdk.CollectionConverters._

Expand All @@ -28,7 +29,7 @@ object Generate {
sepFormat <- ZIO.fromEither(Config.tabularFormat(config.common.tableFormat))
axiomSourceProperty <- ZIO.fromOption(Prefixes.idToIRI(config.axiomSourceAnnotationProperty, prefixes).map(AnnotationProperty(_)))
.orElseFail(DOSDPError("Couldn't create IRI for axiom source annotation property."))
targets <- determineTargets(config).mapError(e => DOSDPError("Failure to configure input or output", e))
targets <- determineTargets(config)
_ <- ZIO.foreach_(targets) { target =>
for {
_ <- ZIO.effectTotal(scribe.info(s"Processing pattern ${target.templateFile}"))
Expand Down Expand Up @@ -133,16 +134,14 @@ object Generate {
}
}

private def determineTargets(config: GenerateConfig): ZIO[Blocking, Throwable, List[GenerateTarget]] = {
private def determineTargets(config: GenerateConfig): ZIO[Blocking, DOSDPError, List[GenerateTarget]] = {
val patternNames = config.common.batchPatterns.items
if (patternNames.nonEmpty) for {
_ <- ZIO.effectTotal(scribe.info("Running in batch mode"))
_ <- ZIO.ifM(isDirectory(config.common.template))(ZIO.unit,
ZIO.fail(DOSDPError("\"--template must be a directory in batch mode\"")))
_ <- ZIO.ifM(isDirectory(config.infile))(ZIO.unit,
ZIO.fail(DOSDPError("\"--infile must be a directory in batch mode\"")))
_ <- ZIO.ifM(isDirectory(config.common.outfile))(ZIO.unit,
ZIO.fail(DOSDPError("\"--outfile must be a directory in batch mode\"")))
_ <- ZIO.foreach_(patternNames)(pattern => ZIO.when(!Files.exists(Paths.get(config.common.template, s"$pattern.yaml")))(ZIO.fail(DOSDPError(s"Pattern doesn't exist: $pattern"))))
_ <- ZIO.when(!Files.isDirectory(Paths.get(config.common.template)))(ZIO.fail(DOSDPError("\"--template must be a directory in batch mode\"")))
_ <- ZIO.when(!Files.isDirectory(Paths.get(config.infile)))(ZIO.fail(DOSDPError("\"--infile must be a directory in batch mode\"")))
_ <- ZIO.when(!Files.isDirectory(Paths.get(config.common.outfile)))(ZIO.fail(DOSDPError("\"--outfile must be a directory in batch mode\"")))
} yield patternNames.map { pattern =>
val templateFileName = s"${config.common.template}/$pattern.yaml"
val dataExtension = config.common.tableFormat.toLowerCase
Expand All @@ -155,7 +154,7 @@ object Generate {

def readFillers(file: File, sepFormat: CSVFormat): ZIO[Blocking, DOSDPError, (Seq[String], List[Map[String, String]])] =
for {
cleaned <- effectBlockingIO(Source.fromFile(file, "utf-8")).bracketAuto { source =>
cleaned <- effectBlockingIO(Source.fromFile(file, StandardCharsets.UTF_8.name())).bracketAuto { source =>
effectBlockingIO(source.getLines().filterNot(_.trim.isEmpty).mkString("\n"))
}.mapError(e => DOSDPError("Unable to read input table", e))
columns <- ZIO.effectTotal(CSVReader.open(new StringReader(cleaned))(sepFormat)).bracketAuto { reader =>
Expand Down
34 changes: 23 additions & 11 deletions src/main/scala/org/monarchinitiative/dosdp/cli/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,34 @@ import scribe._
import scribe.filter._
import zio._

import java.time.{Duration, Instant}

object Main extends ZCommandApp[Config] {

override def appName: String = "dosdp-tools"

override def progName: String = "dosdp-tools"

override def run(config: Config, args: RemainingArgs): ZIO[ZEnv, Nothing, ExitCode] =
ZIO.effectTotal(JenaSystem.init()) *>
ZIO.effectTotal(
scribe.Logger.root
.clearHandlers()
.clearModifiers()
.withModifier(select(packageName(DOSDP.getClass.getPackage.getName)).include(level >= Level.Info))
.withHandler(minimumLevel = Some(Level.Warn))
.replace()
) *>
config.run.exitCode
def toHumanReadableDateDiff(start: Long, end: Long): String = {
val seconds = Duration.between(Instant.ofEpochMilli(start), Instant.ofEpochMilli(end)).getSeconds
String.format("%d:%02d:%02d", seconds / 3600, (seconds % 3600) / 60, seconds % 60);
}

override def run(config: Config, args: RemainingArgs): ZIO[ZEnv, Nothing, ExitCode] = {
val program = ZIO.effectTotal(JenaSystem.init()) *> ZIO.effectTotal(
scribe.Logger.root
.clearHandlers()
.clearModifiers()
.withModifier(select(packageName(DOSDP.getClass.getPackage.getName)).include(level >= Level.Info))
.withHandler(minimumLevel = Some(if (config.common.verbose) Level.Info else Level.Warn))
.replace()
) *> config.run
program
.as(ExitCode.success)
.catchAll { case DOSDPError(msg, e) =>
if (config.common.verbose) ZIO.effectTotal(e.printStackTrace()).as(ExitCode.failure)
else ZIO.effectTotal(scribe.error(msg)).as(ExitCode.failure)
}
}

}
16 changes: 9 additions & 7 deletions src/main/scala/org/monarchinitiative/dosdp/cli/Query.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.github.tototoshi.csv.CSVWriter
import org.apache.jena.query.{QueryExecutionFactory, QueryFactory, QuerySolution}
import org.apache.jena.rdf.model.{Model, ModelFactory}
import org.apache.jena.vocabulary.DCTerms
import org.monarchinitiative.dosdp.Utilities.isDirectory
import org.monarchinitiative.dosdp.cli.Config.AxiomKind
import org.monarchinitiative.dosdp.{DOSDP, ExpandedDOSDP, SPARQL, SesameJena}
import org.phenoscape.owlet.Owlet
Expand All @@ -20,6 +19,8 @@ import zio._
import zio.blocking.Blocking

import java.io.{File, PrintWriter}
import java.nio.charset.StandardCharsets
import java.nio.file._
import scala.jdk.CollectionConverters._

object Query {
Expand All @@ -36,7 +37,7 @@ object Query {
}
}
for {
targets <- determineTargets(config).mapError(e => DOSDPError("Failure to configure input or output", e))
targets <- determineTargets(config)
reasonerFactoryOpt <- reasonerFactoryOptZ
ontologyOpt <- config.common.ontologyOpt
modelOpt <- ZIO.foreach(ontologyOpt)(makeModel)
Expand Down Expand Up @@ -104,7 +105,7 @@ object Query {
modelOpt: Option[Model],
patternIRIOpt: Option[String]): IO[DOSDPError, Set[OWLAnnotationAssertionAxiom]] = {
val doPrintQuery = ZIO
.effect(new PrintWriter(new File(target.outputFile), "utf-8"))
.effect(new PrintWriter(new File(target.outputFile), StandardCharsets.UTF_8.name()))
.bracketAuto(w => ZIO.effect(w.print(processedQuery)))
val doPerformQuery = for {
model <- ZIO.fromOption(modelOpt).orElseFail(DOSDPError("Can't run query; no ontology provided."))
Expand All @@ -118,7 +119,7 @@ object Query {
}
_ <-
ZIO
.effect(CSVWriter.open(target.outputFile, "utf-8")(sepFormat))
.effect(CSVWriter.open(target.outputFile, StandardCharsets.UTF_8.name())(sepFormat))
.bracketAuto(w => writeQueryResults(w, columns, results))
} yield conformanceAnnotations.toList.flatten.to(Set)
(if (config.printQuery.bool) doPrintQuery.as(Set.empty[OWLAnnotationAssertionAxiom]) else doPerformQuery).mapError(e => DOSDPError("Failure performing query command", e))
Expand All @@ -129,12 +130,13 @@ object Query {
ZIO.effect(writer.writeRow(columns.map(variable => Option(qs.get(variable)).map(_.toString).getOrElse(""))))
}

private def determineTargets(config: QueryConfig): RIO[Blocking, List[QueryTarget]] = {
private def determineTargets(config: QueryConfig): ZIO[Blocking, DOSDPError, List[QueryTarget]] = {
val patternNames = config.common.batchPatterns.items
if (patternNames.nonEmpty) for {
_ <- ZIO.effectTotal(scribe.info("Running in batch mode"))
_ <- ZIO.ifM(isDirectory(config.common.template))(ZIO.unit, ZIO.fail(DOSDPError("\"--template must be a directory in batch mode\"")))
_ <- ZIO.ifM(isDirectory(config.common.outfile))(ZIO.unit, ZIO.fail(DOSDPError("\"--outfile must be a directory in batch mode\"")))
_ <- ZIO.foreach_(patternNames)(pattern => ZIO.when(!Files.exists(Paths.get(config.common.template, s"$pattern.yaml")))(ZIO.fail(DOSDPError(s"Pattern file doesn't exist: $pattern"))))
_ <- ZIO.when(!Files.exists(Paths.get(config.common.template)))(ZIO.fail(DOSDPError("\"--template must be a directory in batch mode\"")))
_ <- ZIO.when(!Files.exists(Paths.get(config.common.outfile)))(ZIO.fail(DOSDPError("\"--outfile must be a directory in batch mode\"")))
} yield patternNames.map { pattern =>
val templateFileName = s"${config.common.template}/$pattern.yaml"
val suffix =
Expand Down
7 changes: 3 additions & 4 deletions src/main/scala/org/monarchinitiative/dosdp/cli/Terms.scala
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
package org.monarchinitiative.dosdp.cli

import java.nio.charset.StandardCharsets

import better.files._
import com.github.tototoshi.csv.CSVReader
import org.monarchinitiative.dosdp.{DOSDP, ExpandedDOSDP, Prefixes}
import zio._
import zio.console.putStrLn

import scala.jdk.CollectionConverters._

object Terms {

def run(config: TermsConfig): ZIO[ZEnv, DOSDPError, Unit] = {
def run(config: TermsConfig): ZIO[ZEnv, DOSDPError, Unit] =
for {
dosdp <- config.common.inputDOSDP
prefixes <- config.common.prefixesMap
eDOSDP = ExpandedDOSDP(dosdp, prefixes)
sepFormat <- ZIO.fromEither(Config.tabularFormat(config.common.tableFormat))
patternAxioms <- ZIO.fromEither(eDOSDP.filledLogicalAxioms(None, None))
patternTerms = patternAxioms.flatMap(_.getSignature.asScala.map(_.getIRI).filterNot(_.toString.startsWith("urn:dosdp:")))
rows <- ZIO.effect(CSVReader.open(config.infile, "utf-8")(sepFormat)).bracketAuto(csvReader => ZIO.effect(csvReader.iteratorWithHeaders.toList))
rows <- ZIO.effect(CSVReader.open(config.infile, StandardCharsets.UTF_8.name())(sepFormat)).bracketAuto(csvReader => ZIO.effect(csvReader.iteratorWithHeaders.toList))
.mapError(e => DOSDPError(s"Could not read fillers file at ${config.infile}", e))
identifiers = rows.flatMap(identifiersForRow(_, dosdp)).to(Set)
iris = patternTerms ++ identifiers.flatMap(Prefixes.idToIRI(_, prefixes)) //FIXME should we report failure to expand to IRI?
_ <- ZIO.effect(config.common.outfile.toFile.overwrite("").appendLines(iris.map(_.toString).toSeq: _*)(StandardCharsets.UTF_8))
.mapError(e => DOSDPError(s"Failed writing output file at ${config.common.outfile}", e))
} yield ()
}

private def identifiersForRow(row: Map[String, String], dosdp: DOSDP): Set[String] = {
val varFillers = for {
Expand Down

0 comments on commit 92ef1cc

Please sign in to comment.