cats.data.ValidatedNel Scala Examples

The following examples show how to use cats.data.ValidatedNel. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: PortalDataAccessorProvider.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package controllers.repository

import cats.data.ValidatedNel
import cats.implicits._
import vinyldns.core.domain.membership.{UserChangeRepository, UserRepository}
import vinyldns.core.repository.DataStoreLoader.getRepoOf
import vinyldns.core.repository.RepositoryName._
import vinyldns.core.repository.{DataAccessorProvider, DataStore, DataStoreConfig}
import vinyldns.core.task.TaskRepository

// $COVERAGE-OFF$
object PortalDataAccessorProvider extends DataAccessorProvider[PortalDataAccessor] {
  def repoNames: List[RepositoryName] =
    List(user, userChange)

  def create(
      dataStores: List[(DataStoreConfig, DataStore)]
  ): ValidatedNel[String, PortalDataAccessor] =
    (
      getRepoOf[UserRepository](dataStores, user),
      getRepoOf[UserChangeRepository](dataStores, userChange),
      getRepoOf[TaskRepository](dataStores, task)
    ).mapN(PortalDataAccessor)
}
// $COVERAGE-ON$ 
Example 2
Source File: MetadataParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.publish.params

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.publish.options.MetadataOptions
import coursier.core.{ModuleName, Organization}
import coursier.parse.DependencyParser
import coursier.publish.Pom.{Developer, License}

final case class MetadataParams(
  organization: Option[Organization],
  name: Option[ModuleName],
  version: Option[String],
  licenses: Option[Seq[License]],
  homePage: Option[String],
  // TODO Support full-fledged coursier.Dependency?
  dependencies: Option[Seq[(Organization, ModuleName, String)]],
  developersOpt: Option[Seq[Developer]],
  git: Option[Boolean],
  mavenMetadata: Option[Boolean]
) {
  def isEmpty: Boolean =
    organization.isEmpty &&
      name.isEmpty &&
      version.isEmpty &&
      licenses.isEmpty &&
      homePage.isEmpty &&
      dependencies.isEmpty &&
      developersOpt.isEmpty
}

object MetadataParams {
  def apply(options: MetadataOptions, defaultScalaVersion: String): ValidatedNel[String, MetadataParams] = {

    // TODO Check for invalid character? emptiness?
    val organization = options.organization.map(Organization(_))
    val name = options.name.map(ModuleName(_))
    val version = options.version
    val dependenciesV =
      if (options.dependency.forall(_.trim.isEmpty))
        Validated.validNel(None)
      else
        options
          .dependency
          .map(_.trim)
          .filter(_.nonEmpty)
          .traverse { s =>
            DependencyParser.moduleVersion(s, defaultScalaVersion) match {
              case Left(err) =>
                Validated.invalidNel(err)
              case Right((mod, _)) if mod.attributes.nonEmpty =>
                Validated.invalidNel(s"Dependency $s: attributes not supported for now")
              case Right((mod, ver)) =>
                Validated.validNel((mod.organization, mod.name, ver))
            }
          }
          .map(Some(_))

    val licensesV =
      if (options.license.forall(_.trim.isEmpty))
        Validated.validNel(None)
      else
        options
          .license
          .map(_.trim)
          .filter(_.nonEmpty)
          .traverse { s =>
            s.split(":", 2) match {
              case Array(id, url) =>
                Validated.validNel(License(id, url))
              case Array(id) =>
                License.map.get(id) match {
                  case None =>
                    Validated.invalidNel(s"Unrecognized license '$id', please pass an URL for it like --license $id:https://…")
                  case Some(license) =>
                    Validated.validNel(license)
                }
            }
          }
          .map(Some(_))

    val homePageOpt = options.home.map(_.trim).filter(_.nonEmpty)

    (dependenciesV, licensesV).mapN {
      (dependencies, licenses) =>
        MetadataParams(
          organization,
          name,
          version,
          licenses,
          homePageOpt,
          dependencies,
          None, // developer not accepted from the command-line for now
          options.git,
          options.mavenMetadata
        )
    }
  }
} 
Example 3
Source File: SinglePackageParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.publish.params

import java.nio.file.{Files, Path, Paths}

import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.publish.options.SinglePackageOptions
import coursier.core.{Classifier, Extension}

final case class SinglePackageParams(
  jarOpt: Option[Path],
  pomOpt: Option[Path],
  artifacts: Seq[(Classifier, Extension, Path)],
  `package`: Boolean
)

object SinglePackageParams {

  private def q = "\""

  def apply(options: SinglePackageOptions): ValidatedNel[String, SinglePackageParams] = {

    // FIXME This does some I/O (not reflected in return type)

    def fileExtensionV(path: String): ValidatedNel[String, (Path, String)] =
      fileV(path).withEither(_.flatMap { p =>
        val name = p.getFileName.toString
        val idx = name.lastIndexOf('.')
        if (idx < 0)
          Left(NonEmptyList.one(s"$path has no extension, specify one by passing it with classifier:extension:$path"))
        else {
          val ext = name.drop(idx + 1)
          if (ext.isEmpty)
            Left(NonEmptyList.one(s"$path extension is empty, specify one by passing it with classifier:extension:$path"))
          else
            Right((p, ext))
        }
      })

    def fileV(path: String): ValidatedNel[String, Path] = {
      val p = Paths.get(path)
      if (!Files.exists(p))
        Validated.invalidNel(s"not found: $path")
      else if (!Files.isRegularFile(p))
        Validated.invalidNel(s"not a regular file: $path")
      else
        Validated.validNel(p)
    }

    def fileOptV(pathOpt: Option[String]): ValidatedNel[String, Option[Path]] =
      pathOpt match {
        case None =>
          Validated.validNel(None)
        case Some(path) =>
          fileV(path).map(Some(_))
      }

    val jarOptV = fileOptV(options.jar)
    val pomOptV = fileOptV(options.pom)

    val artifactsV = options.artifact.traverse { s =>
      s.split(":", 3) match {
        case Array(strClassifier, strExtension, path) =>
          fileV(path).map((Classifier(strClassifier), Extension(strExtension), _))
        case Array(strClassifier, path) =>
          fileExtensionV(path).map {
            case (p, ext) =>
              (Classifier(strClassifier), Extension(ext), p)
          }
        case _ =>
          Validated.invalidNel(s"Malformed artifact argument: $s (expected: ${q}classifier:/path/to/artifact$q)")
      }
    }

    val packageV = options.`package` match {
      case Some(true) =>
        Validated.validNel(true)
      case Some(false) =>
        if (options.jar.nonEmpty || options.pom.nonEmpty || options.artifact.nonEmpty)
          Validated.invalidNel("Cannot specify --package=false along with --pom or --jar or --artifact")
        else
          Validated.validNel(false)
      case None =>
        val p = options.jar.nonEmpty || options.pom.nonEmpty || options.artifact.nonEmpty
        Validated.validNel(p)
    }

    (jarOptV, pomOptV, artifactsV, packageV).mapN {
      (jarOpt, pomOpt, artifacts, package0) =>
        SinglePackageParams(
          jarOpt,
          pomOpt,
          artifacts,
          package0
        )
    }
  }
} 
Example 4
Source File: Util.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli

import java.io.PrintStream

import cats.data.ValidatedNel

object Util {

  def prematureExit(msg: String): Nothing = {
    Console.err.println(msg)
    sys.exit(255)
  }

  def prematureExitIf(cond: Boolean)(msg: => String): Unit =
    if (cond)
      prematureExit(msg)

  def exit(msg: String): Nothing = {
    Console.err.println(msg)
    sys.exit(1)
  }

  def exitIf(cond: Boolean)(msg: => String): Unit =
    if (cond)
      exit(msg)

  implicit class ValidatedExitOnError[T](private val validated: ValidatedNel[String, T]) extends AnyVal {
    def exitOnError(errStream: PrintStream = System.err, exitCode: Int = 1): T =
      validated.toEither match {
        case Left(errors) =>
          for (err <- errors.toList)
            errStream.println(err)
          sys.exit(exitCode)
        case Right(t) => t
      }
  }

} 
Example 5
Source File: CompleteParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.complete

import caseapp.core.RemainingArgs
import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.params.{CacheParams, OutputParams, RepositoryParams}
import coursier.core.Repository

final case class CompleteParams(
  cache: CacheParams,
  output: OutputParams,
  repositories: Seq[Repository],
  toComplete: String,
  scalaVersion: Option[String],
  scalaBinaryVersion: Option[String]
)

object CompleteParams {
  def apply(options: CompleteOptions, args: RemainingArgs): ValidatedNel[String, CompleteParams] = {

    val cacheV = options.cacheOptions.params
    val outputV = OutputParams(options.outputOptions)
    val repositoriesV = RepositoryParams(options.repositoryOptions)

    val argV = args.all match {
      case Seq() =>
        Validated.invalidNel("No argument to complete passed")
      case Seq(arg) =>
        Validated.validNel(arg)
      case other =>
        Validated.invalidNel(s"Got ${other.length} arguments to complete, expected one.")
    }

    (cacheV, outputV, repositoriesV, argV).mapN {
      (cache, output, repositories, arg) =>
        CompleteParams(
          cache,
          output,
          // TODO Take repositories.channels into account, then auto-complete apps too?
          repositories.repositories,
          arg,
          options.scalaVersion.map(_.trim).filter(_.nonEmpty),
          options.scalaBinaryVersion
        )
    }
  }
} 
Example 6
Source File: FetchParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.fetch

import java.nio.file.{Path, Paths}

import cats.data.ValidatedNel
import cats.implicits._
import coursier.cli.params.ArtifactParams
import coursier.cli.resolve.SharedResolveParams

final case class FetchParams(
  classpath: Boolean,
  jsonOutputOpt: Option[Path],
  resolve: SharedResolveParams,
  artifact: ArtifactParams
)

object FetchParams {
  def apply(options: FetchOptions): ValidatedNel[String, FetchParams] = {

    val classpath = options.classpath

    val jsonOutputOpt =
      if (options.jsonOutputFile.isEmpty)
        None
      else
        Some(Paths.get(options.jsonOutputFile))

    val resolveV = SharedResolveParams(options.resolveOptions)
    val artifactV = ArtifactParams(options.artifactOptions)

    (resolveV, artifactV).mapN {
      (resolve, artifact) =>
        FetchParams(
          classpath,
          jsonOutputOpt,
          resolve,
          artifact
        )
    }
  }
} 
Example 7
Source File: InstallParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.install

import java.io.File
import java.nio.charset.StandardCharsets
import java.nio.file.Files

import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.jvm.SharedJavaParams
import coursier.cli.params.{CacheParams, EnvParams, OutputParams}
import coursier.install.Channel

final case class InstallParams(
  cache: CacheParams,
  output: OutputParams,
  shared: SharedInstallParams,
  sharedChannel: SharedChannelParams,
  sharedJava: SharedJavaParams,
  env: EnvParams,
  addChannels: Seq[Channel],
  installChannels: Seq[String],
  force: Boolean
) {
  lazy val channels: Seq[Channel] =
    (sharedChannel.channels ++ addChannels).distinct
}

object InstallParams {

  def apply(options: InstallOptions, anyArg: Boolean): ValidatedNel[String, InstallParams] = {

    val cacheParamsV = options.cacheOptions.params(None)
    val outputV = OutputParams(options.outputOptions)

    val sharedV = SharedInstallParams(options.sharedInstallOptions)

    val sharedChannelV = SharedChannelParams(options.sharedChannelOptions)
    val sharedJavaV = SharedJavaParams(options.sharedJavaOptions)

    val envV = EnvParams(options.envOptions)

    val addChannelsV = options.addChannel.traverse { s =>
      val e = Channel.parse(s)
        .left.map(NonEmptyList.one)
        .map(c => (s, c))
      Validated.fromEither(e)
    }

    val force = options.force

    val checkNeedsChannelsV =
      if (anyArg && sharedChannelV.toOption.exists(_.channels.isEmpty) && addChannelsV.toOption.exists(_.isEmpty))
        Validated.invalidNel(s"Error: no channels specified")
      else
        Validated.validNel(())

    val flags = Seq(
      options.addChannel.nonEmpty,
      envV.toOption.fold(false)(_.anyFlag)
    )
    val flagsV =
      if (flags.count(identity) > 1)
        Validated.invalidNel("Error: can only specify one of --add-channel, --env, --setup.")
      else
        Validated.validNel(())

    val checkArgsV =
      if (anyArg && flags.exists(identity))
        Validated.invalidNel(s"Error: unexpected arguments passed along --add-channel, --env, or --setup.")
      else
        Validated.validNel(())

    (cacheParamsV, outputV, sharedV, sharedChannelV, sharedJavaV, envV, addChannelsV, checkNeedsChannelsV, flagsV, checkArgsV).mapN {
      (cacheParams, output, shared, sharedChannel, sharedJava, env, addChannels, _, _, _) =>
        InstallParams(
          cacheParams,
          output,
          shared,
          sharedChannel,
          sharedJava,
          env,
          addChannels.map(_._2),
          addChannels.map(_._1),
          force
        )
    }
  }
} 
Example 8
Source File: SharedChannelParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.install

import java.io.File
import java.nio.charset.StandardCharsets
import java.nio.file.Files

import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import coursier.install.Channel
import coursier.install.Channels

final case class SharedChannelParams(
  channels: Seq[Channel]
)

object SharedChannelParams {
  def apply(options: SharedChannelOptions): ValidatedNel[String, SharedChannelParams] = {

    val channelsV = options
      .channel
      .traverse { s =>
        val e = Channel.parse(s)
          .left.map(NonEmptyList.one)
        Validated.fromEither(e)
      }

    val defaultChannels =
      if (options.defaultChannels) Channels.defaultChannels
      else Nil

    val contribChannels =
      if (options.contrib) Channels.contribChannels
      else Nil

    val fileChannelsV =
      if (options.fileChannels) {
        val configDir = coursier.paths.CoursierPaths.configDirectory()
        val channelDir = new File(configDir, "channels")
        val files = Option(channelDir.listFiles())
          .getOrElse(Array.empty[File])
          .filter(f => !f.getName.startsWith("."))
        val rawChannels = files.toList.flatMap { f =>
          val b = Files.readAllBytes(f.toPath)
          val s = new String(b, StandardCharsets.UTF_8)
          s.linesIterator.map(_.trim).filter(_.nonEmpty).toSeq
        }
        rawChannels.traverse { s =>
          val e = Channel.parse(s)
            .left.map(NonEmptyList.one)
          Validated.fromEither(e)
        }
      } else
        Validated.validNel(Nil)

    (channelsV, fileChannelsV).mapN {
      (channels, fileChannels) =>
        SharedChannelParams(
          (channels ++ fileChannels ++ defaultChannels ++ contribChannels).distinct
        )
    }
  }
} 
Example 9
Source File: UninstallParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.install

import java.nio.file.{Path, Paths}

import caseapp.Tag
import cats.data.{Validated, ValidatedNel}

final case class UninstallParams(
  dir: Path,
  all: Boolean,
  verbosity: Int
)

object UninstallParams {
  def apply(options: UninstallOptions): ValidatedNel[String, UninstallParams] = {

    val dir = options.installDir.filter(_.nonEmpty) match {
      case Some(d) => Paths.get(d)
      case None => SharedInstallParams.defaultDir
    }

    val all = options.all

    val verbosityV =
      if (Tag.unwrap(options.quiet) > 0 && Tag.unwrap(options.verbose) > 0)
        Validated.invalidNel("Cannot have both quiet, and verbosity > 0")
      else
        Validated.validNel(Tag.unwrap(options.verbose) - Tag.unwrap(options.quiet))

    verbosityV.map { verbosity =>
      UninstallParams(
        dir,
        all,
        verbosity
      )
    }
  }
} 
Example 10
Source File: UpdateParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.install

import java.nio.file.{Path, Paths}
import java.util.concurrent.TimeUnit

import cats.data.ValidatedNel
import cats.implicits._
import coursier.cli.jvm.SharedJavaParams
import coursier.cli.params.{CacheParams, OutputParams}
import coursier.core.Repository

import scala.concurrent.duration.Duration

final case class UpdateParams(
  cache: CacheParams,
  output: OutputParams,
  shared: SharedInstallParams,
  sharedJava: SharedJavaParams,
  overrideRepositories: Boolean,
  force: Boolean
) {
  def selectedRepositories(initialList: Seq[Repository]): Seq[Repository] =
    if (overrideRepositories) shared.repositories
    else initialList
}

object UpdateParams {
  def apply(options: UpdateOptions): ValidatedNel[String, UpdateParams] = {

    val cacheParamsV = options.cacheOptions.params(Some(Duration(0L, TimeUnit.MILLISECONDS)))
    val outputV = OutputParams(options.outputOptions)

    val sharedV = SharedInstallParams(options.sharedInstallOptions)
    val sharedJavaV = SharedJavaParams(options.sharedJavaOptions)

    val force = options.force

    (cacheParamsV, outputV, sharedV, sharedJavaV).mapN { (cacheParams, output, shared, sharedJava) =>
      UpdateParams(
        cacheParams,
        output,
        shared,
        sharedJava,
        options.overrideRepositories,
        force
      )
    }
  }
} 
Example 11
Source File: SharedInstallParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.install

import java.nio.file.{Path, Paths}

import caseapp.Tag
import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import coursier.cache.{Cache, CacheLogger}
import coursier.cli.params.OutputParams
import coursier.core.Repository
import coursier.install.{GraalvmParams, InstallDir}
import coursier.parse.RepositoryParser
import coursier.util.Task

final case class SharedInstallParams(
  repositories: Seq[Repository],
  dir: Path,
  graalvmParamsOpt: Option[GraalvmParams] = None,
  onlyPrebuilt: Boolean,
  platformOpt: Option[String],
  preferPrebuilt: Boolean
) {

  def installDir(cache: Cache[Task]): InstallDir =
    InstallDir(dir, cache)
      .withGraalvmParamsOpt(graalvmParamsOpt)
      .withCoursierRepositories(repositories)
      .withOnlyPrebuilt(onlyPrebuilt)
      .withPlatform(platformOpt)
      .withPreferPrebuilt(preferPrebuilt)
}

object SharedInstallParams {

  lazy val defaultDir = InstallDir.defaultDir

  private[install] implicit def validationNelToCats[L, R](v: coursier.util.ValidationNel[L, R]): ValidatedNel[L, R] =
    v.either match {
      case Left(h :: t) => Validated.invalid(NonEmptyList.of(h, t: _*))
      case Right(r) => Validated.validNel(r)
    }

  def apply(options: SharedInstallOptions): ValidatedNel[String, SharedInstallParams] = {

    val repositoriesV = validationNelToCats(RepositoryParser.repositories(options.repository))

    val defaultRepositories =
      if (options.defaultRepositories)
        coursier.Resolve.defaultRepositories
      else
        Nil

    val dir = options.installDir.filter(_.nonEmpty) match {
      case Some(d) => Paths.get(d)
      case None => defaultDir
    }

    val graalvmParams = GraalvmParams(
      options.graalvmDefaultVersion.filter(_.nonEmpty),
      options.graalvmOption
    )

    val onlyPrebuilt = options.onlyPrebuilt

    val platformOpt = options.installPlatform.orElse(InstallDir.platform())

    val preferPrebuilt = options.installPreferPrebuilt

    repositoriesV.map { repositories =>
      SharedInstallParams(
        defaultRepositories ++ repositories,
        dir,
        Some(graalvmParams),
        onlyPrebuilt,
        platformOpt,
        preferPrebuilt
      )
    }
  }
} 
Example 12
Source File: BootstrapParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.bootstrap

import cats.data.ValidatedNel
import cats.implicits._
import coursier.cli.params.SharedLaunchParams
import coursier.launcher.Parameters.ScalaNative.ScalaNativeOptions

final case class BootstrapParams(
  sharedLaunch: SharedLaunchParams,
  nativeOptions: ScalaNativeOptions,
  nativeShortVersionOpt: Option[String] = None,
  specific: BootstrapSpecificParams
) {
  lazy val fork: Boolean =
    sharedLaunch.fork.getOrElse(SharedLaunchParams.defaultFork)
}

object BootstrapParams {
  def apply(options: BootstrapOptions): ValidatedNel[String, BootstrapParams] = {
    val sharedLaunchV = SharedLaunchParams(options.sharedLaunchOptions)
    val nativeOptionsV = options.nativeOptions.params
    val nativeVersionOpt = options.nativeOptions.nativeVersion.map(_.trim).filter(_.nonEmpty)
    val specificV = BootstrapSpecificParams(
      options.options,
      sharedLaunchV
        .toOption
        .exists(_.resolve.dependency.native)
    )

    (sharedLaunchV, nativeOptionsV, specificV).mapN {
      case (sharedLaunch, nativeOptions, specific) =>
        BootstrapParams(
          sharedLaunch,
          nativeOptions,
          nativeVersionOpt,
          specific
        )
    }
  }
} 
Example 13
Source File: EpisodeSettingsExtractor.scala    From scalalaz-gen   with Apache License 2.0 5 votes vote down vote up
package ru.scalalaz.gen.parsing

import java.time.LocalDate
import java.time.format.{ DateTimeFormatter, DateTimeParseException }

import cats.Apply
import cats.data.Validated.Valid
import cats.data.{ Validated, ValidatedNel }
import ru.scalalaz.gen.{ Enclosure, EpisodeSettings, SpecialPageSettings }

object EpisodeSettingsExtractor {

  import ru.scalalaz.gen.parsing.EpisodeErrors._

  
  def fromMap(
      map: Map[String, Option[String]]
  ): ValidatedNel[PageParseError, SpecialPageSettings] =
    new SettingsExtractor(map).extract

  class SettingsExtractor(map: Map[String, Option[String]]) {

    def extract: ValidatedNel[PageParseError, SpecialPageSettings] =
      Apply[ValidatedNel[PageParseError, *]].map2(
          read("title").toValidatedNel,
          read("date").andThen(parseDate).toValidatedNel
      ) {
        case (title, date) =>
          //val enc = Enclosure(encUrl, if (encLength != "") encLength.toInt else -1)
          SpecialPageSettings(title, date)
      }

    private def read(key: String): Validated[PageParseError, String] =
      Validated.fromOption(map.get(key).flatten, MissingKey(key))

    private def optRead(key: String): Validated[PageParseError, String] =
      Valid(map.get(key).flatten.getOrElse(""))

    private def parseDate(
        date: String
    ): Validated[PageParseError, LocalDate] = {
      def toDate = LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE)
      Validated
        .catchOnly[DateTimeParseException](toDate)
        .leftMap(e => InvalidDate(e.getMessage))
    }

  }

} 
Example 14
Source File: ConfigReader.scala    From DataQuality   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package com.agilelab.dataquality.common.parsers

import cats.data.ValidatedNel
import cats.implicits._
import com.agilelab.dataquality.common.models.CommonModel
import com.agilelab.dataquality.common.parsers.DQConfig.AllErrorsOr
import com.typesafe.config.Config

trait ConfigReader[A] {
  def read(value: Config, enums: Set[String]*): AllErrorsOr[A]
}

object DQConfig {
  type AllErrorsOr[A] = ValidatedNel[String,A] // Validated[NonEmptyList[String], A]
  def parse[A](conf: Config, enums: Set[String]*)(implicit r: ConfigReader[A]): AllErrorsOr[A] = r.read(conf, enums:_*)
  def traverseResults[A](res: List[AllErrorsOr[A]]): AllErrorsOr[List[A]] = res.sequence
}

trait CommonToUiTransformer[A] {
  def transform(v: CommonModel): A
}

object CommonTransform {
  def toUI[A](v: CommonModel)(implicit tfm: CommonToUiTransformer[A]): A = tfm.transform(v)
} 
Example 15
Source File: ConfigReaderInstances.scala    From DataQuality   with GNU Lesser General Public License v3.0 5 votes vote down vote up
package com.agilelab.dataquality.common.instances

import cats.data.Validated.{Invalid, Valid}
import cats.data.{NonEmptyList, ValidatedNel}
import cats.implicits._
import com.agilelab.dataquality.common.enumerations.DBTypes
import com.agilelab.dataquality.common.models.DatabaseCommon
import com.agilelab.dataquality.common.parsers.ConfigReader
import com.agilelab.dataquality.common.parsers.DQConfig.AllErrorsOr
import com.typesafe.config.Config

import scala.util.{Failure, Success, Try}

object ConfigReaderInstances {

  private def parseString(str: String)(implicit conf: Config): AllErrorsOr[String] = {
    Try(conf.getString(str)) match {
      case Success(v) => Valid(v)
      case Failure(_) => Invalid(NonEmptyList.one(s"Field $str is missing"))
    }
  }

  private def parseStringEnumerated(str: String, enum: Set[String])(implicit conf: Config): AllErrorsOr[String] = {
    Try(conf.getString(str)) match {
      case Success(v) if enum.contains(v) => Valid(v)
      case Success(v) => Invalid(NonEmptyList.one(s"Unsupported value of $str: $v"))
      case Failure(_) => Invalid(NonEmptyList.one(s"Field $str is missing"))
    }
  }

  implicit val databaseReader: ConfigReader[DatabaseCommon] =
    new ConfigReader[DatabaseCommon] {
      def read(conf: Config, enums: Set[String]*): AllErrorsOr[DatabaseCommon] = {
        val id: AllErrorsOr[String] = parseString("id")(conf)
        val subtype: AllErrorsOr[String] = parseStringEnumerated("subtype", DBTypes.names)(conf)

        Try(conf.getConfig("config")) match {
          case Success(innerConf) =>
            val host: AllErrorsOr[String] = parseString("host")(innerConf)

            val port: AllErrorsOr[Option[Int]] = Valid(Try(innerConf.getString("port").toInt).toOption)
            val service: AllErrorsOr[Option[String]] = Valid(Try(innerConf.getString("service")).toOption)
            val user: AllErrorsOr[Option[String]] = Valid(Try(innerConf.getString("user")).toOption)
            val password: AllErrorsOr[Option[String]] = Valid(Try(innerConf.getString("password")).toOption)
            val schema: AllErrorsOr[Option[String]] = Valid(Try(innerConf.getString("schema")).toOption)

            (id, subtype, host, port, service, user, password, schema).mapN(DatabaseCommon.apply _)
          case Failure(_) => Invalid(NonEmptyList.one("Inner config is missing"))
        }
      }
    }

//  implicit val sourceReader: ConfigReader[SourceCommon] =
//    new ConfigReader[SourceCommon] {
//      override def read(value: Config): AllErrorsOr[SourceCommon] = ???
//    }
} 
Example 16
Source File: SignatureParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.publish.params

import cats.data.{Validated, ValidatedNel}
import coursier.cli.publish.options.SignatureOptions

final case class SignatureParams(
  gpg: Boolean,
  gpgKeyOpt: Option[String]
)

object SignatureParams {
  def apply(options: SignatureOptions): ValidatedNel[String, SignatureParams] = {
    // check here that the passed gpg key exists?
    Validated.validNel(
      SignatureParams(
        // TODO Adjust default value if --sonatype is passed
        options.gpg.getOrElse(options.gpgKey.nonEmpty),
        options.gpgKey
      )
    )
  }
} 
Example 17
Source File: ApiDataAccessorProvider.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api.repository

import cats.data.ValidatedNel
import cats.implicits._
import vinyldns.core.domain.batch.BatchChangeRepository
import vinyldns.core.domain.membership._
import vinyldns.core.domain.record.{RecordChangeRepository, RecordSetRepository}
import vinyldns.core.domain.zone.{ZoneChangeRepository, ZoneRepository}
import vinyldns.core.repository.{DataAccessorProvider, DataStore, DataStoreConfig}
import vinyldns.core.repository.DataStoreLoader.getRepoOf
import vinyldns.core.repository.RepositoryName._

object ApiDataAccessorProvider extends DataAccessorProvider[ApiDataAccessor] {
  def repoNames: List[RepositoryName] =
    List(
      user,
      group,
      membership,
      groupChange,
      recordSet,
      recordChange,
      zoneChange,
      zone,
      batchChange
    )

  def create(
      dataStores: List[(DataStoreConfig, DataStore)]
  ): ValidatedNel[String, ApiDataAccessor] =
    (
      getRepoOf[UserRepository](dataStores, user),
      getRepoOf[GroupRepository](dataStores, group),
      getRepoOf[MembershipRepository](dataStores, membership),
      getRepoOf[GroupChangeRepository](dataStores, groupChange),
      getRepoOf[RecordSetRepository](dataStores, recordSet),
      getRepoOf[RecordChangeRepository](dataStores, recordChange),
      getRepoOf[ZoneChangeRepository](dataStores, zoneChange),
      getRepoOf[ZoneRepository](dataStores, zone),
      getRepoOf[BatchChangeRepository](dataStores, batchChange)
    ).mapN(ApiDataAccessor)
} 
Example 18
Source File: ResultHelpers.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package vinyldns.api

import cats.data.Validated.{Invalid, Valid}
import cats.data.ValidatedNel
import cats.effect._
import cats.implicits._
import cats.scalatest.ValidatedMatchers
import org.scalatest.matchers.should.Matchers
import org.scalatest.propspec.AnyPropSpec

import scala.concurrent.ExecutionContext
import scala.concurrent.duration._
import scala.reflect.ClassTag

final case class TimeoutException(message: String) extends Throwable(message)

trait ResultHelpers {
  private implicit val timer: Timer[IO] = IO.timer(ExecutionContext.global)
  private implicit val cs: ContextShift[IO] =
    IO.contextShift(scala.concurrent.ExecutionContext.global)

  def await[T](f: => IO[_], duration: FiniteDuration = 1.second): T =
    awaitResultOf[T](f.map(_.asInstanceOf[T]).attempt, duration).toOption.get

  // Waits for the future to complete, then returns the value as an Either[Throwable, T]
  def awaitResultOf[T](
      f: => IO[Either[Throwable, T]],
      duration: FiniteDuration = 1.second
  ): Either[Throwable, T] = {

    val timeOut = IO.sleep(duration) *> IO(
      TimeoutException("Timed out waiting for result").asInstanceOf[Throwable]
    )

    IO.race(timeOut, f.handleError(e => Left(e))).unsafeRunSync() match {
      case Left(e) => Left(e)
      case Right(ok) => ok
    }
  }

  // Assumes that the result of the future operation will be successful, this will fail on a left disjunction
  def rightResultOf[T](f: => IO[Either[Throwable, T]], duration: FiniteDuration = 1.second): T =
    awaitResultOf[T](f, duration) match {
      case Right(result) => result
      case Left(error) => throw error
    }

  // Assumes that the result of the future operation will fail, this will error on a right disjunction
  def leftResultOf[T](
      f: => IO[Either[Throwable, T]],
      duration: FiniteDuration = 1.second
  ): Throwable = awaitResultOf(f, duration).swap.toOption.get

  def leftValue[T](t: Either[Throwable, T]): Throwable = t.swap.toOption.get

  def rightValue[T](t: Either[Throwable, T]): T = t.toOption.get
}

object ValidationTestImprovements extends AnyPropSpec with Matchers with ValidatedMatchers {

  implicit class ValidatedNelTestImprovements[DomainValidationError, A](
      value: ValidatedNel[DomainValidationError, A]
  ) {

    def failures: List[DomainValidationError] = value match {
      case Invalid(e) => e.toList
      case Valid(_) =>
        fail("should have no failures!") // Will (correctly) cause expected failures to fail upon succeeding
    }

    def failWith[EE <: DomainValidationError](implicit tag: ClassTag[EE]): Unit =
      value.failures.map(_ shouldBe an[EE])
  }
} 
Example 19
Source File: ValidatedMatchersSpec.scala    From cats-scalatest   with Apache License 2.0 5 votes vote down vote up
package cats.scalatest

import cats.data.Validated.{Invalid, Valid}
import cats.data.{NonEmptyList, ValidatedNel}

class ValidatedMatchersSpec extends TestBase with ValidatedMatchers {
  "ValidatedMatchers" should {
    val simpleFailureNel: ValidatedNel[String, Nothing] = Invalid(NonEmptyList.of(thisRecord, thisTobacconist))

    "Match one specific element in an Invalid NEL" in {
      simpleFailureNel should haveInvalid(thisRecord)
    }

    "Match multiple specific elements in an Invalid NEL" in {
      simpleFailureNel should (haveInvalid(thisRecord).and(haveInvalid(thisTobacconist)))
    }

    "Match a specific element of a single Invalid" in {
      Invalid(thisRecord) should beInvalid(thisRecord)
    }

    "Test whether a Validated instance is a Invalid w/o specific element value" in {
      Invalid(thisTobacconist) should be(invalid)
    }

    "By negating 'invalid', test whether a Validated instance is a Valid" in {
      Valid(hovercraft) should not be (invalid)
    }

    "Test whether a Validated instance is a Valid" in {
      Valid(hovercraft) should be(valid)
    }

    "By negating 'valid', test whether a Validated instance is an invalid" in {
      Invalid(thisTobacconist) should not be (valid)
    }

    "Match a specific element of a single Valid" in {
      Valid(hovercraft) should beValid(hovercraft)
    }

    "Match one specific type in an Invalid NEL" in {
      simpleFailureNel should haveAnInvalid[String]

      val nel: ValidatedNel[String, Nothing] = Invalid(NonEmptyList.of("test"))
      nel should haveAnInvalid[String]
      nel should haveAnInvalid[Any]
      nel shouldNot haveAnInvalid[Int]

      val nel2: ValidatedNel[Nothing, Unit] = Valid(())
      nel2 shouldNot haveAnInvalid[String]
      nel2 shouldNot haveAnInvalid[Unit]
    }
  }
} 
Example 20
Source File: MatcherAssertion.scala    From cornichon   with Apache License 2.0 5 votes vote down vote up
package com.github.agourlay.cornichon.matchers

import cats.syntax.validated._
import cats.data.ValidatedNel
import com.github.agourlay.cornichon.steps.regular.assertStep.Assertion
import cats.syntax.either._
import com.github.agourlay.cornichon.core.{ CornichonError, Done }
import com.github.agourlay.cornichon.core.Done._
import com.github.agourlay.cornichon.json.JsonPath
import io.circe.Json

case class MatcherAssertion(negate: Boolean, m: Matcher, input: Json, jsonPath: JsonPath) extends Assertion {

  lazy val validated: ValidatedNel[CornichonError, Done] =
    jsonPath.runStrict(input) match {
      case Left(e) =>
        MatcherAssertionEvaluationError(m, input, e).invalidNel
      case Right(focus) =>
        Either.catchNonFatal(m.predicate(focus))
          .leftMap(e => MatcherAssertionEvaluationError(m, focus, CornichonError.fromThrowable(e)))
          .fold[ValidatedNel[CornichonError, Done]](
            errors => errors.invalidNel,
            matcherResult =>
              // XNOR condition for not negate
              if (matcherResult == !negate) validDone else MatcherAssertionError(m, focus, negate).invalidNel
          )
    }
}

case class MatcherAssertionEvaluationError(m: Matcher, input: Json, error: CornichonError) extends CornichonError {
  val baseErrorMessage = s"evaluation of matcher '${m.key}' (${m.description}) failed for input '${input.spaces2}'"
  override val causedBy = error :: Nil
}

case class MatcherAssertionError(m: Matcher, input: Json, negate: Boolean) extends CornichonError {
  val baseErrorMessage = s"matcher '${m.key}' (${m.description}) ${if (negate) "was expected to fail" else "failed"} for input '${input.spaces2}'"
} 
Example 21
Source File: ScenarioReport.scala    From cornichon   with Apache License 2.0 5 votes vote down vote up
package com.github.agourlay.cornichon.core

import cats.data.Validated.Valid
import cats.data.{ NonEmptyList, ValidatedNel }
import cats.kernel.Monoid
import monix.eval.Task

import scala.concurrent.Future
import scala.concurrent.duration.{ Duration, FiniteDuration }

sealed trait ScenarioReport {
  def isSuccess: Boolean
  def scenarioName: String
  def session: Session
  def logs: List[LogInstruction]
  def duration: FiniteDuration
}

object ScenarioReport {
  def build(scenarioName: String, runState: RunState, result: ValidatedNel[FailedStep, Done], duration: FiniteDuration): ScenarioReport =
    result.fold(
      failedSteps => FailureScenarioReport(scenarioName, failedSteps, runState.session, runState.logStack, duration, runState.randomContext.initialSeed),
      _ => SuccessScenarioReport(scenarioName, runState.session, runState.logStack, duration, runState.randomContext.initialSeed)
    )
}

case class SuccessScenarioReport(scenarioName: String, session: Session, logStack: List[LogInstruction], duration: FiniteDuration, seed: Long) extends ScenarioReport {
  val isSuccess = true

  // keeping it lazy to avoid the reverse in case of no rendering
  lazy val logs = logStack.reverse
  // In case of success, logs are only shown if the scenario contains DebugLogInstruction
  lazy val shouldShowLogs: Boolean = logStack.exists(_.isInstanceOf[DebugLogInstruction])
}

case class IgnoreScenarioReport(scenarioName: String, reason: String, session: Session) extends ScenarioReport {
  val logs = Nil
  val isSuccess = false
  val duration = Duration.Zero
}

case class PendingScenarioReport(scenarioName: String, session: Session) extends ScenarioReport {
  val logs = Nil
  val isSuccess = false
  val duration = Duration.Zero
}

case class FailureScenarioReport(scenarioName: String, failedSteps: NonEmptyList[FailedStep], session: Session, logStack: List[LogInstruction], duration: FiniteDuration, seed: Long) extends ScenarioReport {
  val isSuccess = false

  val msg =
    s"""|Scenario '$scenarioName' failed:
        |${failedSteps.toList.iterator.map(_.messageForFailedStep).mkString("\nand\n")}
        |seed for the run was '$seed'
        |""".stripMargin

  lazy val logs = logStack.reverse
  lazy val renderedColoredLogs = LogInstruction.renderLogs(logs)
  lazy val renderedLogs = LogInstruction.renderLogs(logs, colorized = false)
}

sealed abstract class Done
case object Done extends Done {
  val rightDone = Right(Done)
  val validDone = Valid(Done)
  val futureDone = Future.successful(Done)
  val taskDone = Task.now(Done)
  implicit val monoid = new Monoid[Done] {
    def empty: Done = Done
    def combine(x: Done, y: Done): Done = x
  }
}

case class FailedStep(step: Step, errors: NonEmptyList[CornichonError]) {
  lazy val messageForFailedStep =
    s"""
       |at step:
       |${step.title}
       |
       |with error(s):
       |${errors.toList.iterator.map(_.renderedMessage).mkString("\nand\n")}
       |""".stripMargin

}

object FailedStep {
  def fromSingle(step: Step, error: CornichonError) = FailedStep(step, NonEmptyList.one(error))
} 
Example 22
Source File: LeaseTxValidator.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.validation.impl

import cats.data.ValidatedNel
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.TxValidationError
import com.wavesplatform.transaction.lease.LeaseTransaction
import com.wavesplatform.transaction.validation.TxValidator

object LeaseTxValidator extends TxValidator[LeaseTransaction] {
  override def validate(tx: LeaseTransaction): ValidatedNel[ValidationError, LeaseTransaction] = {
    import tx._
    V.seq(tx)(
      V.fee(fee),
      V.cond(amount > 0, TxValidationError.NonPositiveAmount(amount, "waves")),
      V.noOverflow(amount, fee),
      V.cond(sender.toAddress != recipient, TxValidationError.ToSelf),
      V.addressChainId(recipient, chainId)
    )
  }
} 
Example 23
Source File: PaymentTxValidator.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.validation.impl

import cats.data.ValidatedNel
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.PaymentTransaction
import com.wavesplatform.transaction.validation.TxValidator

object PaymentTxValidator extends TxValidator[PaymentTransaction] {
  override def validate(transaction: PaymentTransaction): ValidatedNel[ValidationError, PaymentTransaction] = {
    import transaction._
    V.seq(transaction)(
      V.fee(fee),
      V.positiveAmount(amount, "waves"),
      V.noOverflow(fee, amount),
      V.addressChainId(recipient, chainId)
    )
  }
} 
Example 24
Source File: ExchangeTxValidator.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.validation.impl

import cats.data.ValidatedNel
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.TxValidationError.{GenericError, OrderValidationError}
import com.wavesplatform.transaction.TxVersion
import com.wavesplatform.transaction.assets.exchange.{ExchangeTransaction, Order, OrderType}
import com.wavesplatform.transaction.validation.TxValidator

object ExchangeTxValidator extends TxValidator[ExchangeTransaction] {
  override def validate(tx: ExchangeTransaction): ValidatedNel[ValidationError, ExchangeTransaction] = {
    import tx._

    V.seq(tx)(
      V.fee(fee),
      V.positiveAmount(amount, "assets"),
      V.cond(amount <= Order.MaxAmount, GenericError("amount too large")),
      V.cond(price > 0, GenericError("price should be > 0")),
      V.cond(price <= Order.MaxAmount, GenericError("price too large")),
      V.cond(sellMatcherFee <= Order.MaxAmount, GenericError("sellMatcherFee too large")),
      V.cond(buyMatcherFee <= Order.MaxAmount, GenericError("buyMatcherFee too large")),
      V.cond(fee <= Order.MaxAmount, GenericError("fee too large")),
      V.cond(isProtobufVersion || order1.orderType == OrderType.BUY, GenericError("order1 should have OrderType.BUY")),
      V.cond(buyOrder.orderType == OrderType.BUY, GenericError("buyOrder should has OrderType.BUY")),
      V.cond(sellOrder.orderType == OrderType.SELL, GenericError("sellOrder should has OrderType.SELL")),
      V.cond(buyOrder.matcherPublicKey == sellOrder.matcherPublicKey, GenericError("buyOrder.matcher should be the same as sellOrder.matcher")),
      V.cond(buyOrder.assetPair == sellOrder.assetPair, GenericError("Both orders should have same AssetPair")),
      V.cond(buyOrder.isValid(timestamp), OrderValidationError(buyOrder, buyOrder.isValid(timestamp).messages())),
      V.cond(sellOrder.isValid(timestamp), OrderValidationError(sellOrder, sellOrder.isValid(timestamp).messages())),
      V.cond(
        version > TxVersion.V1 || (buyOrder.version == Order.V1 && sellOrder.version == Order.V1),
        GenericError("can only contain orders of version 1")
      ),
      V.cond(
        version > TxVersion.V2 || (buyOrder.version < Order.V4 && sellOrder.version < Order.V4),
        GenericError("can only contain orders of version < 4")
      )
    )
  }
} 
Example 25
Source File: TransferTxValidator.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.validation.impl

import cats.data.ValidatedNel
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.transfer.TransferTransaction
import com.wavesplatform.transaction.validation.TxValidator

object TransferTxValidator extends TxValidator[TransferTransaction] {
  override def validate(transaction: TransferTransaction): ValidatedNel[ValidationError, TransferTransaction] = {
    import transaction._
    V.seq(transaction)(
      V.fee(fee),
      V.positiveAmount(amount, assetId.maybeBase58Repr.getOrElse("waves")),
      V.transferAttachment(attachment),
      V.addressChainId(recipient, chainId)
    )
  }
} 
Example 26
Source File: package.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform

import cats.data.ValidatedNel
import com.wavesplatform.account.PrivateKey
import com.wavesplatform.block.{Block, MicroBlock}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.validation.TxValidator
import com.wavesplatform.utils.base58Length

package object transaction {
  val AssetIdLength: Int       = com.wavesplatform.crypto.DigestLength
  val AssetIdStringLength: Int = base58Length(AssetIdLength)

  type DiscardedTransactions = Seq[Transaction]
  type DiscardedBlocks       = Seq[(Block, ByteStr)]
  type DiscardedMicroBlocks  = Seq[MicroBlock]
  type AuthorizedTransaction = Authorized with Transaction

  type TxType = Byte

  type TxVersion = Byte
  object TxVersion {
    val V1: TxVersion = 1.toByte
    val V2: TxVersion = 2.toByte
    val V3: TxVersion = 3.toByte
  }
  type TxAmount    = Long
  type TxTimestamp = Long
  type TxByteArray = Array[Byte]

  implicit class TransactionValidationOps[T <: Transaction: TxValidator](tx: T) {
    def validatedNel: ValidatedNel[ValidationError, T] = implicitly[TxValidator[T]].validate(tx)
    def validatedEither: Either[ValidationError, T]    = this.validatedNel.toEither.left.map(_.head)
  }

  implicit class TransactionSignOps[T](tx: T)(implicit sign: (T, PrivateKey) => T) {
    def signWith(privateKey: PrivateKey): T = sign(tx, privateKey)
  }
} 
Example 27
Source File: ConfigSettingsValidator.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.settings.utils

import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import com.typesafe.config.{Config, ConfigException}
import com.wavesplatform.transaction.assets.exchange.AssetPair
import net.ceedubs.ficus.Ficus._
import net.ceedubs.ficus.readers.ValueReader

import scala.jdk.CollectionConverters._
import scala.util.Try

object ConfigSettingsValidator {

  type ErrorsListOr[A] = ValidatedNel[String, A]

  def apply(config: Config): ConfigSettingsValidator = new ConfigSettingsValidator(config)

  implicit class ErrorListOrOps[A](validatedValue: ErrorsListOr[A]) {
    def getValueOrThrowErrors: A = validatedValue valueOr (errorsAcc => throw new Exception(errorsAcc.mkString_(", ")))
  }

  object AdhocValidation {
    def validateAssetPairKey(key: String): Validated[String, AssetPair] =
      Validated.fromTry(AssetPair.fromString(key)) leftMap (_ => s"Can't parse asset pair '$key'")
  }
}

class ConfigSettingsValidator(config: Config) {

  import ConfigSettingsValidator.ErrorsListOr

  private def createError[T](settingName: String, errorMsg: String, showError: Boolean = true, showValue: Boolean = true): NonEmptyList[String] = {

    lazy val value = config.getValue(settingName).unwrapped

    lazy val msg = (showValue, showError) match {
      case (true, true)  => s"$value ($errorMsg)"
      case (true, false) => s"$value"
      case (false, true) => s"$errorMsg"
      case _             => ""
    }

    NonEmptyList.one(s"Invalid setting $settingName value: $msg")
  }

  def validate[T: ValueReader](settingName: String, showError: Boolean = false): ErrorsListOr[T] = {
    Validated fromTry Try(config.as[T](settingName)) leftMap (ex => createError(settingName, ex.getMessage, showError))
  }

  def validateByPredicate[T: ValueReader](settingName: String)(predicate: T => Boolean, errorMsg: String): ErrorsListOr[T] = {
    validate[T](settingName, showError = true).ensure(createError(settingName, errorMsg))(predicate)
  }

  def validatePercent(settingName: String): ErrorsListOr[Double] = {
    validateByPredicate[Double](settingName)(p => 0 < p && p <= 100, "required 0 < percent <= 100")
  }

  def validateList[T: ValueReader](settingName: String): ErrorsListOr[List[T]] = {
    config
      .getList(settingName)
      .asScala
      .toList
      .zipWithIndex
      .traverse {
        case (cfg, index) =>
          val elemPath = s"$settingName.$index"
          Validated fromTry Try(cfg.atPath(elemPath).as[T](elemPath)) leftMap (ex => List(ex.getMessage))
      }
      .leftMap(errorsInList => createError(settingName, errorsInList.mkString(", "), showValue = false))
  }

  def validateMap[K, V: ValueReader](settingName: String)(keyValidator: String => Validated[String, K]): ErrorsListOr[Map[K, V]] = {
    config
      .getConfig(settingName)
      .root()
      .entrySet()
      .asScala
      .toList
      .traverse { entry =>
        val elemPath = s"$settingName.${entry.getKey}"
        val k        = keyValidator(entry.getKey).leftMap(List(_))
        val v        = Validated fromTry Try(entry.getValue.atPath(elemPath).as[V](elemPath)) leftMap (ex => List(ex.getMessage))
        k.product(v)
      }
      .map(_.toMap)
      .leftMap(errorsInList => createError(settingName, errorsInList.mkString(", "), showValue = false))
  }

  def validateWithDefault[T: ValueReader](settingName: String, defaultValue: T, showError: Boolean = false): ErrorsListOr[T] = {
    Validated
      .fromTry(Try(config.as[T](settingName)).recover { case _: ConfigException.Missing => defaultValue })
      .leftMap(ex => createError(settingName, ex.getMessage, showError))
  }

  def validateByPredicateWithDefault[T: ValueReader](
      settingName: String)(predicate: T => Boolean, errorMsg: String, defaultValue: T): ErrorsListOr[T] = {
    validateWithDefault[T](settingName, defaultValue, showError = true).ensure(createError(settingName, errorMsg))(predicate)
  }
} 
Example 28
Source File: ValidatedMain.scala    From advanced-scala-code   with Apache License 2.0 5 votes vote down vote up
import cats.{Applicative, Foldable, Semigroup}


object ValidatedMain {

  def main(args: Array[String]) {

    case class Person(name: String, email: String)
    val person = Person("Joe", "[email protected]")

    import cats.data.Validated
    def checkName(person: Person): Validated[String, String] =
      Validated.invalid("The user with this name doesn't exist")
    def checkEmail(person: Person): Validated[String, String] =
      Validated.invalid("This email looks suspicious")

    import cats.syntax.apply._
    import cats.instances.string.catsKernelStdMonoidForString
    val emailCheckV = checkEmail(person)
    val nameCheckV = checkName(person)

    val resultV = (emailCheckV, nameCheckV).mapN(_ + _)
    resultV.fold(
      errors => println(errors),
      str => ()
    )

    import cats.data.ValidatedNel
    type ErrorOr[+A] = ValidatedNel[String, A]
    def checkNameNel(person: Person): ErrorOr[String] =
      Validated.invalidNel("The user with this name doesn't exist")
    def checkEmailNel(person: Person): ErrorOr[String] =
      Validated.invalidNel("This email looks suspicious")

    import cats.instances.list.catsKernelStdMonoidForList
    val resultNel = (checkEmailNel(person), checkNameNel(person)).mapN(_ + _)
    resultNel.fold(
      nel => println(nel.toList),
      str => ()
    )
  }
} 
Example 29
Source File: JacksonParser.scala    From circe-jackson   with Apache License 2.0 5 votes vote down vote up
package io.circe.jackson

import cats.data.ValidatedNel
import io.circe.{ Decoder, Error, Json, Parser, ParsingFailure }
import java.io.File
import scala.util.control.NonFatal

trait JacksonParser extends Parser { this: WithJacksonMapper =>
  final def parse(input: String): Either[ParsingFailure, Json] = try {
    Right(mapper.readValue(jsonStringParser(input), classOf[Json]))
  } catch {
    case NonFatal(error) => Left(ParsingFailure(error.getMessage, error))
  }

  final def parseFile(file: File): Either[ParsingFailure, Json] = try {
    Right(mapper.readValue(jsonFileParser(file), classOf[Json]))
  } catch {
    case NonFatal(error) => Left(ParsingFailure(error.getMessage, error))
  }

  final def parseByteArray(bytes: Array[Byte]): Either[ParsingFailure, Json] = try {
    Right(mapper.readValue(jsonBytesParser(bytes), classOf[Json]))
  } catch {
    case NonFatal(error) => Left(ParsingFailure(error.getMessage, error))
  }

  final def decodeByteArray[A: Decoder](bytes: Array[Byte]): Either[Error, A] =
    finishDecode[A](parseByteArray(bytes))

  final def decodeByteArrayAccumulating[A: Decoder](bytes: Array[Byte]): ValidatedNel[Error, A] =
    finishDecodeAccumulating[A](parseByteArray(bytes))

  final def decodeFile[A: Decoder](file: File): Either[Error, A] =
    finishDecode[A](parseFile(file))

  final def decodeFileAccumulating[A: Decoder](file: File): ValidatedNel[Error, A] =
    finishDecodeAccumulating[A](parseFile(file))
} 
Example 30
Source File: ValidatedUtils.scala    From chimney   with Apache License 2.0 5 votes vote down vote up
package io.scalaland.chimney.cats.utils

import cats.InvariantMonoidal
import cats.data.{NonEmptyChain, NonEmptyList, Validated, ValidatedNec, ValidatedNel}

object ValidatedUtils {

  implicit class OptionOps[T](val opt: Option[T]) extends AnyVal {

    def toValidated[EE[_]: InvariantMonoidal](err: => String): Validated[EE[String], T] = {
      opt match {
        case Some(value) => Validated.Valid(value)
        case None        => Validated.Invalid(InvariantMonoidal[EE].point(err))
      }
    }

    def toValidatedNec(err: => String): ValidatedNec[String, T] =
      toValidated[NonEmptyChain](err)(implicitly)

    def toValidatedNel(err: => String): ValidatedNel[String, T] =
      toValidated[NonEmptyList](err)(implicitly)
  }

  implicit class ValidatedOps[+E, +A](val validated: Validated[E, A]) extends AnyVal {

    def getValid: A = {
      validated.valueOr(_ => throw new NoSuchElementException)
    }
  }
} 
Example 31
Source File: Dependencies.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.resolve

import java.net.{URL, URLDecoder}

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.core.{Configuration, Dependency, Exclusions, Module, ModuleName, Organization}
import coursier.parse.{DependencyParser, JavaOrScalaDependency, JavaOrScalaModule}

object Dependencies {


  
  def handleDependencies(
    rawDependencies: Seq[String]
  ): ValidatedNel[String, List[(JavaOrScalaDependency, Map[String, String])]] =
    rawDependencies
      .map { s =>
        DependencyParser.javaOrScalaDependencyParams(s) match {
          case Left(error) => Validated.invalidNel(error)
          case Right(d) => Validated.validNel(List(d))
        }
      }
      .toList
      .flatSequence

  def withExtraRepo(
    rawDependencies: Seq[String],
    extraDependencies: Seq[(JavaOrScalaDependency, Map[String, String])]
  ): Either[Throwable, (List[JavaOrScalaDependency], Map[(JavaOrScalaModule, String), URL])] =
    handleDependencies(rawDependencies) match {
      case Validated.Valid(l) =>

        val l0 = l ++ extraDependencies

        val deps = l0.map(_._1)

        val extraRepo =
          // Any dependencies with URIs should not be resolved with a pom so this is a
          // hack to add all the deps with URIs to the FallbackDependenciesRepository
          // which will be used during the resolve
          l0.flatMap {
            case (dep, extraParams) =>
              extraParams.get("url").map { url =>
                (dep.module, dep.version) -> new URL(URLDecoder.decode(url, "UTF-8"))
              }
          }.toMap

        Right((deps, extraRepo))

      case Validated.Invalid(err) =>
        Left(new ResolveException(
          "Error processing dependencies:\n" +
            err.toList.map("  " + _).mkString("\n")
        ))
    }

  def addExclusions(
    dep: Dependency,
    perModuleExclude: Map[Module, Set[Module]],
  ): Dependency =
    perModuleExclude.get(dep.module) match {
      case None => dep
      case Some(exclusions) =>
        dep.withExclusions(
          Exclusions.minimize(dep.exclusions ++ exclusions.map(m => (m.organization, m.name)))
        )
    }

  def addExclusions(
    deps: Seq[Dependency],
    perModuleExclude: Map[Module, Set[Module]],
  ): Seq[Dependency] =
    deps.map { dep =>
      addExclusions(dep, perModuleExclude)
    }

} 
Example 32
Source File: implicits.scala    From fuuid   with MIT License 5 votes vote down vote up
package io.chrisdavenport.fuuid.http4s

import io.chrisdavenport.fuuid.FUUID
import cats.data.ValidatedNel
import cats.syntax.either._
import org.http4s.QueryParamDecoder
import org.http4s.QueryParameterValue
import org.http4s.ParseFailure

object implicits {
  implicit val fuuidQueryParamDecoder: QueryParamDecoder[FUUID] =
    new QueryParamDecoder[FUUID] {
      def decode(value: QueryParameterValue): ValidatedNel[ParseFailure, FUUID] =
        FUUID
          .fromString(value.value)
          .leftMap(
            _ =>
              ParseFailure(
                "Failed to parse FUUID query parameter",
                s"Could not parse ${value.value} as a FUUID"))
          .toValidatedNel
    }
} 
Example 33
Source File: syntax.scala    From refined   with MIT License 5 votes vote down vote up
package eu.timepit.refined.cats

import cats.data.{NonEmptyList, ValidatedNec, ValidatedNel}
import cats.syntax.either._
import eu.timepit.refined.api.RefinedTypeOps
import eu.timepit.refined.types.numeric.PosInt

object syntax extends CatsRefinedTypeOpsSyntax with CatsNonEmptyListSyntax

trait CatsRefinedTypeOpsSyntax {
  implicit class CatsRefinedTypeOps[FTP, T](rtOps: RefinedTypeOps[FTP, T]) {
    def validate(t: T): ValidatedNel[String, FTP] =
      validateNel(t)

    def validateNec(t: T): ValidatedNec[String, FTP] =
      rtOps.from(t).toValidatedNec

    def validateNel(t: T): ValidatedNel[String, FTP] =
      rtOps.from(t).toValidatedNel
  }
}

trait CatsNonEmptyListSyntax {
  implicit class CatsNonEmptyListRefinedOps[A](nel: NonEmptyList[A]) {
    def refinedSize: PosInt = PosInt.unsafeFrom(nel.size)
  }
} 
Example 34
Source File: PathGroup.scala    From docless   with MIT License 5 votes vote down vote up
package com.timeout.docless.swagger

import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.instances.all._
import cats.syntax.eq._
import cats.syntax.foldable._
import cats.syntax.monoid._
import cats.{Eq, Monoid}
import com.timeout.docless.schema.JsonSchema.{Definition, TypeRef}

trait PathGroup {
  def params: List[OperationParameter] = Nil

  def definitions: List[Definition]

  def paths: List[Path]
}

object PathGroup {
  val Empty = PathGroup(Nil, Nil, Nil)

  def aggregate(
      info: Info,
      groups: List[PathGroup],
      securitySchemes: List[SecurityScheme] = Nil
  ): ValidatedNel[SchemaError, APISchema] = {
    val g          = groups.combineAll
    val allDefs    = g.definitions
    val definedIds = allDefs.map(_.id).toSet
    val securityDefinitions = SecurityDefinitions(securitySchemes: _*)

    def isDefined(ctx: RefWithContext): Boolean =
      allDefs.exists(_.id === ctx.ref.id)

    val missingDefinitions =
      allDefs.foldMap { d =>
        d.relatedRefs.collect {
          case r @ TypeRef(id, _) if !definedIds.exists(_ === id) =>
            SchemaError.missingDefinition(RefWithContext.definition(r, d))
        }
      }

    val errors =
      g.paths
        .foldMap(_.refs.filterNot(isDefined))
        .map(SchemaError.missingDefinition)
        .toList ++ missingDefinitions

    if (errors.nonEmpty)
      Validated.invalid[NonEmptyList[SchemaError], APISchema](
        NonEmptyList.fromListUnsafe(errors)
      )
    else
      Validated.valid {
        APISchema(
          info = info,
          host = "http://example.com/",
          basePath = "/",
          parameters = OperationParameters(g.params),
          paths = Paths(g.paths),
          schemes = Set(Scheme.Http),
          consumes = Set("application/json"),
          produces = Set("application/json"),
          securityDefinitions = securityDefinitions
        ).defining(g.definitions: _*)
      }
  }

  def apply(ps: List[Path],
            defs: List[Definition],
            _params: List[OperationParameter]): PathGroup =
    new PathGroup {

      override val paths       = ps
      override val definitions = defs
      override val params      = _params
    }

  implicit val pgEq: Eq[PathGroup] = Eq.fromUniversalEquals

  implicit def pgMonoid: Monoid[PathGroup] = new Monoid[PathGroup] {
    override def empty: PathGroup = Empty

    override def combine(x: PathGroup, y: PathGroup): PathGroup =
      PathGroup(
        x.paths |+| y.paths,
        x.definitions |+| y.definitions,
        x.params |+| y.params
      )
  }

} 
Example 35
Source File: package.scala    From featherbed   with Apache License 2.0 5 votes vote down vote up
package featherbed

import java.nio.charset.Charset

import cats.data.ValidatedNel
import cats.implicits._
import io.circe._
import io.circe.generic.auto._
import io.circe.parser._
import io.circe.syntax._
import shapeless.Witness

package object circe {

  private val printer = Printer.noSpaces.copy(dropNullValues = true)

  implicit def circeEncoder[A: Encoder]: content.Encoder[A, Witness.`"application/json"`.T] =
    content.Encoder.of("application/json") {
      (value: A, charset: Charset) => content.Encoder.encodeString(printer.pretty(value.asJson), charset)
    }

  implicit def circeDecoder[A: Decoder]: content.Decoder.Aux[Witness.`"application/json"`.T, A] =
    content.Decoder.of("application/json") {
      response =>
        content.Decoder.decodeString(response).andThen {
          str => (parse(str).toValidated.toValidatedNel: ValidatedNel[Throwable, Json]).andThen {
            json: Json => json.as[A].toValidated.toValidatedNel: ValidatedNel[Throwable, A]
          }
        }
    }

} 
Example 36
Source File: package.scala    From featherbed   with Apache License 2.0 5 votes vote down vote up
package featherbed

import java.nio.CharBuffer
import java.nio.charset.{Charset, CodingErrorAction}
import scala.util.Try

import cats.data.{Validated, ValidatedNel}
import com.twitter.finagle.http.Response
import com.twitter.io.Buf
import shapeless.Witness
import sun.nio.cs.ThreadLocalCoders

package object content {
  type ContentType = String

  trait Decoder[ContentType] {
    type Out
    val contentType: String //widened version of ContentType
    def apply(buf: Response): ValidatedNel[Throwable, Out]
  }

  object Decoder extends LowPriorityDecoders {
    type Aux[CT, A1] = Decoder[CT] { type Out = A1 }

    def of[T <: ContentType, A1](t: T)(fn: Response => ValidatedNel[Throwable, A1]): Decoder.Aux[t.type, A1] =
      new Decoder[t.type] {
        type Out = A1
        val contentType = t
        def apply(response: Response) = fn(response)
      }

    def decodeString(response: Response): ValidatedNel[Throwable, String] = {
      Validated.fromTry(Try {
        response.charset.map(Charset.forName).getOrElse(Charset.defaultCharset)
      }).andThen { charset: Charset =>
        val decoder = ThreadLocalCoders.decoderFor(charset)
        Validated.fromTry(
          Try(
            decoder
              .onMalformedInput(CodingErrorAction.REPORT)
              .onUnmappableCharacter(CodingErrorAction.REPORT)
              .decode(Buf.ByteBuffer.Owned.extract(response.content).asReadOnlyBuffer()))).map[String](_.toString)
      }.toValidatedNel
    }
  }

  private[featherbed] trait LowPriorityDecoders {
    implicit val plainTextDecoder: Decoder.Aux[Witness.`"text/plain"`.T, String] = Decoder.of("text/plain") {
      response => Decoder.decodeString(response)
    }

    implicit val anyResponseDecoder: Decoder.Aux[Witness.`"**") {
      response => Validated.Valid(response)
    }
  }

  trait Encoder[A, ForContentType] {
    def apply(value: A, charset: Charset): ValidatedNel[Throwable, Buf]
  }

  object Encoder extends LowPriorityEncoders {
    def of[A, T <: ContentType](t: T)(fn: (A, Charset) => ValidatedNel[Throwable, Buf]): Encoder[A, t.type] =
      new Encoder[A, t.type] {
        def apply(value: A, charset: Charset) = fn(value, charset)
      }

    def encodeString(value: String, charset: Charset): ValidatedNel[Throwable, Buf] = {
      val encoder = ThreadLocalCoders.encoderFor(charset)
      Validated.fromTry(Try(encoder
        .onMalformedInput(CodingErrorAction.REPORT)
        .onUnmappableCharacter(CodingErrorAction.REPORT)
        .encode(CharBuffer.wrap(value)))).toValidatedNel.map[Buf](Buf.ByteBuffer.Owned(_))
    }
  }

  private[featherbed] trait LowPriorityEncoders {
    implicit val plainTextEncoder: Encoder[String, Witness.`"text/plain"`.T] = Encoder.of("text/plain") {
      case (value, charset) => Encoder.encodeString(value, charset)
    }
  }
} 
Example 37
Source File: Schema.scala    From circe-json-schema   with Apache License 2.0 5 votes vote down vote up
package io.circe.schema

import cats.data.{ Validated, ValidatedNel }
import io.circe.{ Json, JsonNumber, JsonObject }
import java.util.HashMap
import org.everit.json.schema.{ Schema => EveritSchema, ValidationException }
import org.everit.json.schema.loader.SchemaLoader
import org.json.{ JSONArray, JSONObject, JSONTokener }
import scala.util.Try

trait Schema {
  def validate(value: Json): ValidatedNel[ValidationError, Unit]
}

object Schema {
  def load(value: Json): Schema = new EveritSchemaImpl(
    SchemaLoader.builder().schemaJson(fromCirce(value)).draftV7Support().build().load().build()
  )

  def loadFromString(value: String): Try[Schema] = Try(
    new EveritSchemaImpl(
      SchemaLoader.builder().schemaJson(new JSONTokener(value).nextValue).draftV7Support().build().load().build()
    )
  )

  private[this] class EveritSchemaImpl(schema: EveritSchema) extends Schema {
    def validate(value: Json): ValidatedNel[ValidationError, Unit] =
      try {
        schema.validate(fromCirce(value))
        Validated.valid(())
      } catch {
        case e: ValidationException => Validated.invalid(ValidationError.fromEverit(e))
      }
  }

  private[this] val fromCirceVisitor: Json.Folder[Object] = new Json.Folder[Object] {
    def onNull: Object = JSONObject.NULL
    def onBoolean(value: Boolean): Object = Predef.boolean2Boolean(value)
    def onString(value: String): Object = value
    def onNumber(value: JsonNumber): Object =
      value.toInt match {
        case Some(asInt) => Predef.int2Integer(asInt)
        case None        => new JSONTokener(value.toString).nextValue
      }
    def onArray(value: Vector[Json]): Object = new JSONArray(value.map(_.foldWith(this)).toArray)
    def onObject(value: JsonObject): Object = {
      val map = new HashMap[String, Object](value.size)
      val iter = value.toIterable.iterator

      while (iter.hasNext) {
        val (k, v) = iter.next
        map.put(k, v.foldWith(this))
      }
      new JSONObject(map)
    }
  }

  private[this] def fromCirce(value: Json): Object = value.foldWith(fromCirceVisitor)
} 
Example 38
Source File: package.scala    From healthchecks   with MIT License 5 votes vote down vote up

package com.github.everpeace

import cats.data.ValidatedNel
import cats.syntax.validated._
import com.github.everpeace.healthchecks.HealthCheck.Severity

import scala.concurrent.Future
import scala.util.Try

package object healthchecks {
  type HealthCheckResult = ValidatedNel[String, Unit]

  def healthy: HealthCheckResult = ().validNel[String]

  def unhealthy(msg: String): HealthCheckResult = msg.invalidNel[Unit]

  def healthCheck(
      name: String,
      severity: Severity = Severity.Fatal
    )(c: => HealthCheckResult
    ): HealthCheck =
    new HealthCheck(name, Future.fromTry(Try(c)), severity)

  def asyncHealthCheck(
      name: String,
      severity: Severity = Severity.Fatal
    )(c: => Future[HealthCheckResult]
    ): HealthCheck =
    new HealthCheck(name, c, severity)
} 
Example 39
Source File: validation.scala    From freestyle   with Apache License 2.0 5 votes vote down vote up
package freestyle.tagless
package effects

import cats.data.{Validated, ValidatedNel}
import cats.mtl.MonadState

object validation {
  final class ValidationProvider[E] {
    type Errors = List[E]

    
    @tagless(true) sealed trait ValidationM {
      def valid[A](x: A): FS[A]

      def invalid(err: E): FS[Unit]

      def errors: FS[Errors]

      def fromEither[A](x: Either[E, A]): FS[Either[E, A]]

      def fromValidatedNel[A](x: ValidatedNel[E, A]): FS[ValidatedNel[E, A]]
    }

    trait Implicits {
      implicit def freeStyleValidationMStateInterpreter[M[_]](
          implicit MS: MonadState[M, Errors]
      ): ValidationM.Handler[M] = new ValidationM.Handler[M] {
        def valid[A](x: A): M[A] = MS.monad.pure(x)

        def errors: M[Errors] = MS.get

        def invalid(err: E): M[Unit] = MS.modify((s: Errors) => s :+ err)

        def fromEither[A](x: Either[E, A]): M[Either[E, A]] =
          x match {
            case Left(err) => MS.monad.as(invalid(err), x)
            case Right(_)  => MS.monad.pure(x)
          }

        def fromValidatedNel[A](x: ValidatedNel[E, A]): M[ValidatedNel[E, A]] =
          x match {
            case Validated.Invalid(errs) =>
              MS.monad.as(MS.modify((s: Errors) => s ++ errs.toList), x)
            case Validated.Valid(_) => MS.monad.pure(x)
          }
      }

      implicit class ValidSyntax[A](private val s: A) {
        def liftValid[F[_]: ValidationM]: F[A] = ValidationM[F].valid(s)
      }
      implicit class InvalidSyntax[A](private val e: E) {
        def liftInvalid[F[_]: ValidationM]: F[Unit] = ValidationM[F].invalid(e)
      }
    }

    object implicits extends Implicits
  }

  def apply[E] = new ValidationProvider[E]

} 
Example 40
Source File: package.scala    From openlaw-core   with Apache License 2.0 5 votes vote down vote up
package org.adridadou.openlaw

import result.Implicits.RichResult
import cats.data.Validated._
import cats.data.{NonEmptyList, ValidatedNel}
import cats.data.NonEmptyList.{of, one}
import cats.implicits._
import org.adridadou.openlaw.result.Implicits.RichTry
import scala.util.Try
import scala.util.control.NonFatal

package object result {

  type ResultNel[+A] = ValidatedNel[FailureCause, A]

  type Result[+A] = Either[FailureCause, A]
  type Failure[Nothing] = Left[FailureCause, Nothing]
  type Success[+A] = Right[FailureCause, A]

  def attempt[A](f: => A): Result[A] = Try(f).toResult

  def handleFatalErrors(t: Throwable): Result[Nothing] = t match {
    case NonFatal(e: Exception) => Failure(e)
    case e                      => throw e
  }
}

package result {

  object Success {
    def unit: Result[Unit] = Success(())
    def apply[A](a: A): Result[A] = Right(a)
    def unapply[A](result: Result[A]): Option[A] = result.toOption
  }

  object ResultNel {
    def apply[A](nel: NonEmptyList[Result[A]]): ResultNel[NonEmptyList[A]] =
      nel.map(_.toResultNel).sequence
    def apply[A](nel: List[Result[A]]): ResultNel[List[A]] =
      nel.map(_.toResultNel).sequence
  }

  object FailureNel {
    def apply[A](e: FailureCause): ResultNel[A] =
      Invalid[NonEmptyList[FailureCause]](one(e))
    def apply[A](head: FailureCause, tail: FailureCause*): ResultNel[A] =
      Invalid[NonEmptyList[FailureCause]](of(head, tail: _*))
  }

  object Failure {
    def apply[A](f: FailureCause): Result[A] = Left(f)
    def apply[A](): Result[A] = apply(new RuntimeException)
    def apply[A](e: Exception): Result[A] = apply(FailureException(e))
    def apply[A](e: Exception, id: String): Result[A] =
      apply(FailureException(e, Some(id)))
    def apply[A](message: String): Result[A] = apply(FailureMessage(message))
    def apply[A](message: String, id: String): Result[A] =
      apply(FailureMessage(message, Some(id)))
    def apply[A](es: NonEmptyList[Exception]): ResultNel[A] =
      Invalid(es.map(FailureException(_)))
    // implicits are necessary here to disambiguate arguments after erasure
    def apply[A](
        es: NonEmptyList[(Exception, String)]
    )(implicit i: DummyImplicit): ResultNel[A] =
      Invalid(es.map { case (e, id) => FailureException(e, Some(id)) })
    def apply[A](
        messages: NonEmptyList[String]
    )(implicit i: DummyImplicit, i2: DummyImplicit): ResultNel[A] =
      Invalid(messages.map(FailureMessage(_)))
    def apply[A](messages: NonEmptyList[(String, String)])(
        implicit i: DummyImplicit,
        i2: DummyImplicit,
        i3: DummyImplicit
    ): ResultNel[A] =
      Invalid(messages.map { case (m, id) => FailureMessage(m, Some(id)) })
    def unapply(result: Result[_]): Option[(Exception, String)] =
      result.swap.toOption.map { f =>
        (f.e, f.id)
      }
  }
} 
Example 41
Source File: Tree.scala    From bosatsu   with Apache License 2.0 5 votes vote down vote up
package org.bykn.bosatsu.graph

import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._

case class Tree[+A](item: A, children: List[Tree[A]])

object Tree {

  def neighborsFn[A](t: Tree[A]): A => List[A] = {
    def toMap(t: Tree[A]): Map[A, Tree[A]] =
      Map(t.item -> t) ++ (t.children.flatMap(toMap(_)))

    val mapToTree: Map[A, Tree[A]] = toMap(t)


    { a: A => mapToTree.get(a).fold(List.empty[A])(_.children.map(_.item)) }
  }

  
  def dagToTree[A](node: A)(nfn: A => List[A]): ValidatedNel[NonEmptyList[A], Tree[A]] = {
    def treeOf(path: NonEmptyList[A], visited: Set[A]): ValidatedNel[NonEmptyList[A], Tree[A]] = {
      val children = nfn(path.head)
      def assumeValid(children: List[A]): ValidatedNel[NonEmptyList[A], Tree[A]] =
        children.traverse { a =>
          // we grow the path out here
          treeOf(a :: path, visited + a)
        }
        .map(Tree(path.head, _))

      NonEmptyList.fromList(children.filter(visited)) match {
        case Some(loops) =>
          val paths = loops.map(_ :: path)
          val invalid = Validated.invalid(paths)
          // also search all the valid cases
          invalid *> assumeValid(children.filterNot(visited))
        case None => assumeValid(children)
      }
    }
    treeOf(NonEmptyList(node, Nil), Set(node))
      .leftMap { nelnel =>
        // remove depulicate paths
        val withSet = nelnel.map { nel => (nel, nel.toList.toSet) }
        distinctBy(withSet)(_._2).map(_._1)
      }
  }

  def distinctBy[A, B](nel: NonEmptyList[A])(fn: A => B): NonEmptyList[A] = {
    @annotation.tailrec
    def remove(seen: Set[B], items: List[A], acc: List[A]): List[A] =
      items match {
        case Nil => acc.reverse
        case h :: t =>
          val b = fn(h)
          if (seen(b)) remove(seen, t, acc)
          else remove(seen + b, t, h :: acc)
      }

    NonEmptyList(nel.head, remove(Set(fn(nel.head)), nel.tail, Nil))
  }

  def distinctBy[A, B](nel: List[A])(fn: A => B): List[A] =
    NonEmptyList.fromList(nel) match {
      case None => Nil
      case Some(nel) => distinctBy(nel)(fn).toList
    }
} 
Example 42
Source File: MergeDeps.scala    From bazel-deps   with MIT License 5 votes vote down vote up
package com.github.johnynek.bazel_deps

import cats.data.{ NonEmptyList, Validated, ValidatedNel }
import cats.Foldable
import cats.implicits._
import io.circe.jawn.JawnParser
import java.io.{ File, PrintWriter }
import scala.util.{ Failure, Success }
import java.nio.file.Path

object MergeDeps {
  private def load(f: Path): ValidatedNel[String, Model] =
    FormatDeps.readModel(f.toFile) match {
      case Right(m) => Validated.valid(m)
      case Left(err) => Validated.invalidNel(err)
    }

  def fail(errs: NonEmptyList[String]): Nothing = {
    errs.toList.foreach(System.err.println)
    System.exit(1)
    sys.error("unreachable")
  }

  def apply(models: NonEmptyList[Path], out: Option[Path]): Unit = {

    type A[T] = ValidatedNel[String, T]
    val mod = models.traverse[A, Model](load).toEither.right.flatMap {
      Model.combine(_)
    }

    mod match {
      case Left(errs) => fail(errs)
      case Right(m) =>
        val stream = m.toDoc.renderStream(100)
        out match {
          case None => stream.foreach(System.out.print)
          case Some(path) =>
            val pw = new PrintWriter(path.toFile)
            stream.foreach(pw.print(_))
            pw.flush
            pw.close
        }
      }
  }

  def addDep(model: Path, lang: Language, coords: NonEmptyList[MavenCoordinate]): Unit =
    load(model) match {
      case Validated.Invalid(errs) => fail(errs)
      case Validated.Valid(m) =>
        val realLang = m.getOptions.replaceLang(lang)
        val deps = coords.map(realLang.unmangle(_).toDependencies(realLang))

        def combine(d1: Dependencies, d2: Dependencies): Either[NonEmptyList[String], Dependencies] =
          Dependencies.combine(m.getOptions.getVersionConflictPolicy, d1, d2).toEither

        type E[T] = Either[NonEmptyList[String], T]
        Foldable[NonEmptyList].foldM[E, Dependencies, Dependencies](deps, m.dependencies)(combine) match {
          case Left(errs) => fail(errs)
          case Right(resDep) =>
            val stream = m.copy(dependencies = resDep).toDoc.renderStream(100)
            val pw = new PrintWriter(model.toFile)
            stream.foreach(pw.print(_))
            pw.flush
            pw.close
        }
  }
} 
Example 43
Source File: CliOpts.scala    From nexus   with Apache License 2.0 5 votes vote down vote up
package ch.epfl.bluebrain.nexus.cli

import java.nio.file.{Path, Paths}

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import ch.epfl.bluebrain.nexus.cli.sse.{BearerToken, Offset}
import com.monovore.decline.{Argument, Opts}
import org.http4s.Uri

import scala.util.Try


object CliOpts extends OptsInstances {

  val token: Opts[Option[BearerToken]] = Opts
    .option[String](
      long = "token",
      help = "The token to use when interacting with the Nexus API; " +
        "a 'none' string value will remove any preconfigured token."
    )
    .validate("Token must be a non empty string") { !_.isBlank }
    .map {
      case "none" => None
      case value  => Some(BearerToken(value))
    }

  val offset: Opts[Option[Offset]] = Opts
    .option[String](
      long = "offset",
      help = "The offset to use when starting the event replay; " +
        "a 'none' string value will discard any saved offset."
    )
    .map(_.trim)
    .mapValidated {
      case "none" => Validated.validNel(None)
      case value  => Offset(value).toRight("Offset is not valid").map(o => Some(o)).toValidatedNel
    }

  val endpoint: Opts[Uri] = Opts
    .option[Uri](
      long = "endpoint",
      help = "The base address of the Nexus API"
    )

  val envConfig: Opts[Path] = Opts
    .option[Path](
      long = "env",
      help = "The environment configuration file"
    )

  val postgresConfig: Opts[Path] = Opts
    .option[Path](
      long = "config",
      help = "The postgres configuration file"
    )

  val influxConfig: Opts[Path] = Opts
    .option[Path](
      long = "config",
      help = "The influx configuration file"
    )

}

trait OptsInstances {
  implicit protected val uriArgument: Argument[Uri] = new Argument[Uri] {
    override def read(string: String): ValidatedNel[String, Uri] =
      Uri
        .fromString(string)
        .leftMap(_ => s"Invalid Uri: '$string'")
        .ensure(s"Invalid Uri: '$string'")(uri => uri.scheme.isDefined)
        .toValidatedNel
    override val defaultMetavar: String                          = "http://..."
  }

  implicit protected val pathArgument: Argument[Path] = new Argument[Path] {
    override def read(string: String): ValidatedNel[String, Path] =
      Try(Paths.get(string)).toOption.toRight(s"Invalid file path '$string'").toValidatedNel
    override val defaultMetavar: String                           = "../file.conf"
  }
} 
Example 44
Source File: RawSource.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.install

import argonaut.{DecodeJson, EncodeJson, Parse}
import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import coursier.parse.RepositoryParser
import dataclass.data


@data class RawSource(
  repositories: List[String],
  channel: String,
  id: String
) {
  def source: ValidatedNel[String, Source] = {

    import RawAppDescriptor.validationNelToCats

    val repositoriesV = validationNelToCats(RepositoryParser.repositories(repositories))

    val channelV = Validated.fromEither(
      Channel.parse(channel)
        .left.map(NonEmptyList.one)
    )

    (repositoriesV, channelV).mapN {
      (repositories, channel) =>
        Source(
          repositories,
          channel,
          id
        )
    }
  }
  def repr: String =
    RawSource.encoder.encode(this).nospaces
}

object RawSource {

  import argonaut.ArgonautShapeless._

  implicit val encoder = EncodeJson.of[RawSource]
  implicit val decoder = DecodeJson.of[RawSource]

  def parse(input: String): Either[String, RawSource] =
    Parse.decodeEither(input)(decoder)

} 
Example 45
Source File: SharedResolveParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.resolve

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.params.{CacheParams, DependencyParams, OutputParams, RepositoryParams}
import coursier.params.ResolutionParams
import coursier.parse.{JavaOrScalaModule, ModuleParser}

final case class SharedResolveParams(
  cache: CacheParams,
  output: OutputParams,
  repositories: RepositoryParams,
  dependency: DependencyParams,
  resolution: ResolutionParams,
  classpathOrder: Option[Boolean]
) {
  def updatedResolution(scalaVersionOpt: Option[String]): ResolutionParams =
    resolution
      .withScalaVersionOpt(resolution.scalaVersionOpt.flatMap(_ => scalaVersionOpt))
      .withExclusions(
        dependency.exclude
          .map { m =>
            val m0 = m.module(scalaVersionOpt.getOrElse(""))
            (m0.organization, m0.name)
          }
      )
}

object SharedResolveParams {
  def apply(options: SharedResolveOptions): ValidatedNel[String, SharedResolveParams] = {

    val cacheV = options.cacheOptions.params
    val outputV = OutputParams(options.outputOptions)
    val repositoriesV = RepositoryParams(options.repositoryOptions, options.dependencyOptions.sbtPlugin.nonEmpty)
    val resolutionV = options.resolutionOptions.params
    val dependencyV = DependencyParams(options.dependencyOptions, resolutionV.toOption.flatMap(_.scalaVersionOpt))

    val classpathOrder = options.classpathOrder

    (cacheV, outputV, repositoriesV, dependencyV, resolutionV).mapN {
      (cache, output, repositories, dependency, resolution) =>
        SharedResolveParams(
          cache,
          output,
          repositories,
          dependency,
          resolution,
          classpathOrder
        )
    }
  }
} 
Example 46
Source File: SimulatePlanApp.scala    From Scala-Programming-Projects   with MIT License 5 votes vote down vote up
package retcalc

import cats.data.Validated._
import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import retcalc.RetCalcError.{InvalidArgument, InvalidNumber, RetCalcResult}

object SimulatePlanApp extends App {
  strMain(args) match {
    case Invalid(err) =>
      println(err)
      sys.exit(1)

    case Valid(result) =>
      println(result)
      sys.exit(0)
  }

  def parseInt(name: String, value: String): RetCalcResult[Int] =
    Validated
      .catchOnly[NumberFormatException](value.toInt)
      .leftMap(_ => NonEmptyList.of(InvalidNumber(name, value)))

  def parseParams(args: Array[String]): RetCalcResult[RetCalcParams] =
    (
      parseInt("nbOfYearsRetired", args(2)),
      parseInt("netIncome", args(3)),
      parseInt("currentExpenses", args(4)),
      parseInt("initialCapital", args(5))
    ).mapN { case (nbOfYearsRetired, netIncome, currentExpenses, initialCapital) =>
      RetCalcParams(
        nbOfMonthsInRetirement = nbOfYearsRetired * 12,
        netIncome = netIncome,
        currentExpenses = currentExpenses,
        initialCapital = initialCapital)
    }

  def parseFromUntil(fromUntil: String): RetCalcResult[(String, String)] = {
    val array = fromUntil.split(",")
    if (array.length != 2)
      InvalidArgument(name = "fromUntil", value = fromUntil, expectedFormat = "from,until"
      ).invalidNel
    else
      (array(0), array(1)).validNel
  }

  def strSimulatePlan(returns: Returns, nbOfYearsSaving: Int, params: RetCalcParams)
  : RetCalcResult[String] = {
    RetCalc.simulatePlan(
      returns = returns,
      params = params,
      nbOfMonthsSavings = nbOfYearsSaving * 12
    ).map {
      case (capitalAtRetirement, capitalAfterDeath) =>
        val nbOfYearsInRetirement = params.nbOfMonthsInRetirement / 12
        s"""
           |Capital after $nbOfYearsSaving years of savings:    ${capitalAtRetirement.round}
           |Capital after $nbOfYearsInRetirement years in retirement: ${capitalAfterDeath.round}
           |""".stripMargin
    }.toValidatedNel
  }


  def strMain(args: Array[String]): Validated[String, String] = {
    if (args.length != 6)
      """Usage:
        |simulatePlan from,until nbOfYearsSaving nbOfYearsRetired netIncome currentExpenses initialCapital
        |
        |Example:
        |simulatePlan 1952.09,2017.09 25 40 3000 2000 10000
        |""".stripMargin.invalid
    else {
      val allReturns = Returns.fromEquityAndInflationData(
        equities = EquityData.fromResource("sp500.tsv"),
        inflations = InflationData.fromResource("cpi.tsv"))

      val vFromUntil = parseFromUntil(args(0))
      val vNbOfYearsSaving = parseInt("nbOfYearsSaving", args(1))
      val vParams = parseParams(args)

      (vFromUntil, vNbOfYearsSaving, vParams)
        .tupled
        .andThen { case ((from, until), nbOfYearsSaving, params) =>
          strSimulatePlan(allReturns.fromUntil(from, until), nbOfYearsSaving, params)
        }
        .leftMap(nel => nel.map(_.message).toList.mkString("\n"))
    }
  }
}

case class SimulatePlanArgs(fromMonth: String,
                            untilMonth: String,
                            retCalcParams: RetCalcParams,
                            nbOfMonthsSavings: Int) 
Example 47
Source File: JavaHomeParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.jvm

import java.nio.file.{Path, Paths}

import cats.data.ValidatedNel
import cats.implicits._
import coursier.cli.params.{CacheParams, EnvParams, OutputParams}

final case class JavaHomeParams(
  shared: SharedJavaParams,
  cache: CacheParams,
  output: OutputParams,
  env: EnvParams
)

object JavaHomeParams {
  def apply(options: JavaHomeOptions): ValidatedNel[String, JavaHomeParams] = {
    val sharedV = SharedJavaParams(options.sharedJavaOptions)
    val cacheV = options.cacheOptions.params
    val outputV = OutputParams(options.outputOptions)
    val envV = EnvParams(options.envOptions)
    (sharedV, cacheV, outputV, envV).mapN { (shared, cache, output, env) =>
      JavaHomeParams(
        shared,
        cache,
        output,
        env
      )
    }
  }
} 
Example 48
Source File: SharedJavaParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.jvm

import java.io.File
import java.nio.file.{Path, Paths}

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.cache.Cache
import coursier.jvm.{JvmCache, JvmCacheLogger}
import coursier.util.Task

final case class SharedJavaParams(
  jvm: Option[String],
  jvmDir: Path,
  allowSystemJvm: Boolean,
  requireSystemJvm: Boolean
) {
  def id: String =
    jvm.getOrElse(coursier.jvm.JavaHome.defaultId)

  def cacheAndHome(cache: Cache[Task], verbosity: Int): (JvmCache, coursier.jvm.JavaHome) = {
    val jvmCache = JvmCache()
      .withBaseDirectory(jvmDir.toFile)
      .withCache(cache)
      .withDefaultIndex
    val javaHome = coursier.jvm.JavaHome()
      .withCache(jvmCache)
      .withJvmCacheLogger(jvmCacheLogger(verbosity))
      .withAllowSystem(allowSystemJvm)
    (jvmCache, javaHome)
  }
  def javaHome(cache: Cache[Task], verbosity: Int): coursier.jvm.JavaHome = {
    val (_, home) = cacheAndHome(cache, verbosity)
    home
  }

  def jvmCacheLogger(verbosity: Int): JvmCacheLogger =
    if (verbosity >= 0)
      new JvmCacheLogger {
        def extracting(id: String, origin: String, dest: File): Unit =
          System.err.println(
            s"""Extracting
               |  $origin
               |in
               |  $dest""".stripMargin
          )
        def extracted(id: String, origin: String, dest: File): Unit =
          System.err.println("Done")
        def extractionFailed(id: String, origin: String, dest: File, error: Throwable): Unit =
          System.err.println(s"Extraction failed: $error")
      }
    else
      JvmCacheLogger.nop
}

object SharedJavaParams {
  def apply(options: SharedJavaOptions): ValidatedNel[String, SharedJavaParams] = {
    val jvm = options.jvm.map(_.trim).filter(_.nonEmpty)
    val jvmDir = options.jvmDir.filter(_.nonEmpty).map(Paths.get(_)).getOrElse {
      JvmCache.defaultBaseDirectory.toPath
    }
    val (allowSystem, requireSystem) = options.systemJvm match {
      case None => (true, false)
      case Some(false) => (false, false)
      case Some(true) => (true, true)
    }

    val checkSystemV =
      if (options.systemJvm.contains(true) && jvm.exists(_ != coursier.jvm.JavaHome.systemId))
        Validated.invalidNel("Cannot specify both --system-jvm and --jvm")
      else
        Validated.validNel(())

    checkSystemV.map { _ =>
      SharedJavaParams(
        jvm,
        jvmDir,
        allowSystem,
        requireSystem
      )
    }
  }
} 
Example 49
Source File: JavaParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.jvm

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.params.{CacheParams, EnvParams, OutputParams}

final case class JavaParams(
  installed: Boolean,
  available: Boolean,
  shared: SharedJavaParams,
  cache: CacheParams,
  output: OutputParams,
  env: EnvParams
)

object JavaParams {
  def apply(options: JavaOptions, anyArg: Boolean): ValidatedNel[String, JavaParams] = {
    val sharedV = SharedJavaParams(options.sharedJavaOptions)
    val cacheV = options.cacheOptions.params
    val outputV = OutputParams(options.outputOptions)
    val envV = EnvParams(options.envOptions)

    val flags = Seq(
      options.installed,
      options.available,
      envV.toOption.fold(false)(_.anyFlag)
    )
    val flagsV =
      if (flags.count(identity) > 1)
        Validated.invalidNel("Error: can only specify one of --env, --setup, --installed, --available.")
      else
        Validated.validNel(())

    val checkArgsV =
      if (anyArg && flags.exists(identity))
        Validated.invalidNel(s"Error: unexpected arguments passed along --env, --setup, --installed, or --available")
      else
        Validated.validNel(())

    (sharedV, cacheV, outputV, envV, flagsV, checkArgsV).mapN { (shared, cache, output, env, _, _) =>
      JavaParams(
        options.installed,
        options.available,
        shared,
        cache,
        output,
        env
      )
    }
  }
} 
Example 50
Source File: SetupParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.setup

import java.nio.file.{Path, Paths}

import cats.data.ValidatedNel
import cats.implicits._
import coursier.cli.install.{SharedChannelParams, SharedInstallParams}
import coursier.cli.jvm.SharedJavaParams
import coursier.cli.params.{CacheParams, EnvParams, OutputParams}

final case class SetupParams(
  sharedJava: SharedJavaParams,
  sharedInstall: SharedInstallParams,
  sharedChannel: SharedChannelParams,
  cache: CacheParams,
  output: OutputParams,
  env: EnvParams,
  banner: Boolean,
  yes: Boolean,
  tryRevert: Boolean,
  apps: Seq[String]
)

object SetupParams {
  def apply(options: SetupOptions): ValidatedNel[String, SetupParams] = {
    val sharedJavaV = SharedJavaParams(options.sharedJavaOptions)
    val sharedInstallV = SharedInstallParams(options.sharedInstallOptions)
    val sharedChannelV = SharedChannelParams(options.sharedChannelOptions)
    val cacheV = options.cacheOptions.params
    val outputV = OutputParams(options.outputOptions)
    val envV = EnvParams(options.envOptions)
    val banner = options.banner.getOrElse(false)
    val yes = options.yes.getOrElse(envV.toOption.exists(_.env))
    val tryRevert = options.tryRevert
    val apps = Some(options.apps.flatMap(_.split(',').toSeq).map(_.trim).filter(_.nonEmpty))
      .filter(_.nonEmpty)
      .getOrElse(DefaultAppList.defaultAppList)
    (sharedJavaV, sharedInstallV, sharedChannelV, cacheV, outputV, envV).mapN { (sharedJava, sharedInstall, sharedChannel, cache, output, env) =>
      SetupParams(
        sharedJava,
        sharedInstall,
        sharedChannel,
        cache,
        output,
        env,
        banner,
        yes,
        tryRevert,
        apps
      )
    }
  }
} 
Example 51
Source File: LaunchParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.launch

import cats.data.ValidatedNel
import cats.implicits._
import coursier.cache.{Cache, CacheLogger}
import coursier.cli.jvm.SharedJavaParams
import coursier.cli.params.SharedLaunchParams
import coursier.env.EnvironmentUpdate
import coursier.util.Task

final case class LaunchParams(
  shared: SharedLaunchParams,
  sharedJava: SharedJavaParams,
  javaOptions: Seq[String],
  jep: Boolean,
  fetchCacheIKnowWhatImDoing: Option[String],
  execve: Option[Boolean]
) {
  lazy val fork: Boolean =
    shared.fork.getOrElse(jep || javaOptions.nonEmpty || sharedJava.jvm.nonEmpty || SharedLaunchParams.defaultFork)

  def javaPath(cache: Cache[Task]): Task[(String, EnvironmentUpdate)] =
    sharedJava.jvm match {
      case None => Task.point(("java", EnvironmentUpdate.empty))
      case Some(id) =>
        val logger = cache.loggerOpt.getOrElse(CacheLogger.nop)
        for {
          _ <- Task.delay(logger.init())
          cache0 = coursier.jvm.JvmCache()
            .withCache(cache)
            .withDefaultLogger(sharedJava.jvmCacheLogger(shared.resolve.output.verbosity))
            .withDefaultIndex
          handle = coursier.jvm.JavaHome()
            .withCache(cache0)
          javaExe <- handle.javaBin(id)
          envUpdate <- handle.environmentFor(id)
          _ <- Task.delay(logger.stop()) // FIXME Run even if stuff above fails
        } yield (javaExe.toAbsolutePath.toString, envUpdate)
    }
}

object LaunchParams {
  def apply(options: LaunchOptions): ValidatedNel[String, LaunchParams] = {

    val sharedV = SharedLaunchParams(options.sharedOptions)
    val sharedJavaV = SharedJavaParams(options.sharedJavaOptions)

    (sharedV, sharedJavaV).mapN { (shared, sharedJava) =>
      LaunchParams(
        shared,
        sharedJava,
        options.javaOpt,
        options.jep,
        options.fetchCacheIKnowWhatImDoing,
        options.execve
      )
    }
  }
} 
Example 52
Source File: RepositoryParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.params

import java.io.File
import java.nio.charset.StandardCharsets
import java.nio.file.Files

import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.implicits._
import coursier.{Repositories, moduleString}
import coursier.cli.install.SharedChannelParams
import coursier.cli.options.RepositoryOptions
import coursier.core.Repository
import coursier.install.Channel
import coursier.ivy.IvyRepository
import coursier.maven.MavenRepository
import coursier.parse.RepositoryParser

final case class RepositoryParams(
  repositories: Seq[Repository],
  channels: SharedChannelParams
)

object RepositoryParams {

  def apply(options: RepositoryOptions, hasSbtPlugins: Boolean = false): ValidatedNel[String, RepositoryParams] = {

    val repositoriesV = Validated.fromEither(
      RepositoryParser.repositories(options.repository)
        .either
        .left
        .map {
          case h :: t => NonEmptyList(h, t)
        }
    )

    val channelsV = SharedChannelParams(options.channelOptions)

    (repositoriesV, channelsV).mapN {
      (repos0, channels) =>

        // preprend defaults
        val defaults =
          if (options.noDefault) Nil
          else {
            val extra =
              if (hasSbtPlugins) Seq(Repositories.sbtPlugin("releases"))
              else Nil
            coursier.Resolve.defaultRepositories ++ extra
          }
        var repos = defaults ++ repos0

        // take sbtPluginHack into account
        repos = repos.map {
          case m: MavenRepository => m.withSbtAttrStub(options.sbtPluginHack)
          case other => other
        }

        // take dropInfoAttr into account
        if (options.dropInfoAttr)
          repos = repos.map {
            case m: IvyRepository => m.withDropInfoAttributes(true)
            case other => other
          }

        RepositoryParams(
          repos,
          channels
        )
    }
  }
} 
Example 53
Source File: ArtifactParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.params

import cats.data.{Validated, ValidatedNel}
import coursier.cli.options.ArtifactOptions
import coursier.core.{Classifier, Type}

final case class ArtifactParams(
  classifiers: Set[Classifier],
  mainArtifacts: Boolean,
  artifactTypes: Set[Type],
  force: Boolean
)

object ArtifactParams {
  def apply(options: ArtifactOptions): ValidatedNel[String, ArtifactParams] = {

    // TODO Move the logic of ArtifactOptions.classifier0 and all here
    val params = ArtifactParams(
      options.classifier0 ++
        (if (options.sources) Seq(Classifier.sources) else Nil) ++
        (if (options.javadoc) Seq(Classifier.javadoc) else Nil),
      options.default0,
      options.artifactTypes,
      options.forceFetch
    )

    Validated.validNel(params)
  }
} 
Example 54
Source File: SharedLaunchParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.params

import java.nio.file.{Path, Paths}

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.fetch.FetchParams
import coursier.cli.options.SharedLaunchOptions
import coursier.cli.resolve.SharedResolveParams

final case class SharedLaunchParams(
  resolve: SharedResolveParams,
  artifact: ArtifactParams,
  sharedLoader: SharedLoaderParams,
  mainClassOpt: Option[String],
  properties: Seq[(String, String)],
  extraJars: Seq[Path],
  fork: Option[Boolean]
) {
  def fetch: FetchParams =
    FetchParams(
      classpath = false,
      jsonOutputOpt = None,
      resolve = resolve,
      artifact = artifact
    )
}

object SharedLaunchParams {

  def defaultFork: Boolean =
    sys.props
      .get("org.graalvm.nativeimage.imagecode")
      .contains("runtime")

  def apply(options: SharedLaunchOptions): ValidatedNel[String, SharedLaunchParams] = {

    val resolveV = SharedResolveParams(options.resolveOptions)
    val artifactV = ArtifactParams(options.artifactOptions)
    val sharedLoaderV = resolveV.map(_.resolution).toOption match {
      case None =>
        Validated.validNel(SharedLoaderParams(Nil, Map.empty))
      case Some(resolutionOpts) =>
        SharedLoaderParams.from(options.sharedLoaderOptions)
    }

    val mainClassOpt = Some(options.mainClass).filter(_.nonEmpty)

    val propertiesV = options.property.traverse { s =>
      val idx = s.indexOf('=')
      if (idx < 0)
        Validated.invalidNel(s"Malformed property argument '$s' (expected name=value)")
      else
        Validated.validNel(s.substring(0, idx) -> s.substring(idx + 1))
    }

    // check if those exist?
    val extraJars = options.extraJars.map { p =>
      Paths.get(p)
    }

    (resolveV, artifactV, sharedLoaderV, propertiesV).mapN {
      (resolve, artifact, sharedLoader, properties) =>
        SharedLaunchParams(
          resolve,
          artifact,
          sharedLoader,
          mainClassOpt,
          properties,
          extraJars,
          options.fork
        )
    }
  }
} 
Example 55
Source File: SharedLoaderParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.params

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.dependencyString
import coursier.cli.options.SharedLoaderOptions
import coursier.parse.{DependencyParser, JavaOrScalaDependency, ModuleParser}

final case class SharedLoaderParams(
  loaderNames: Seq[String],
  loaderDependencies: Map[String, Seq[JavaOrScalaDependency]]
)

object SharedLoaderParams {
  def from(options: SharedLoaderOptions): ValidatedNel[String, SharedLoaderParams] = {

    val targetsOpt = {
      val l = options
        .sharedTarget
        .flatMap(_.split(','))
        .flatMap(_.split(':'))
        .filter(_.nonEmpty)
      Some(l).filter(_.nonEmpty)
    }

    val defaultTarget = targetsOpt
      .flatMap(_.headOption)
      .getOrElse("default")

    val depsFromDeprecatedArgsV = options
      .isolated
      .traverse { d =>
        d.split(":", 2) match {
          case Array(target, dep) =>
            DependencyParser.javaOrScalaDependencyParams(dep) match {
              case Left(err) =>
                Validated.invalidNel(s"$d: $err")
              case Right((dep0, params)) =>
                if (params.isEmpty)
                  Validated.validNel(target -> dep0)
                else
                  Validated.invalidNel(s"$d: extra dependency parameters not supported for shared loader dependencies")
            }
          case _ =>
            Validated.invalidNel(s"$d: malformed shared dependency (expected target:org:name:version)")
        }
      }

    val depsV = options
      .shared
      .traverse { d =>

        val (target, dep) = d.split("@", 2) match {
          case Array(dep0, target0) =>
            (target0, dep0)
          case Array(dep0) =>
            (defaultTarget, dep0)
        }

        ModuleParser.javaOrScalaModule(dep) match {
          case Left(err) =>
            Validated.invalidNel(s"$d: $err")
          case Right(m) =>
            val asDep = JavaOrScalaDependency(m, dep"_:_:_") // actual version shouldn't matter
            Validated.validNel(target -> asDep)
        }
      }

    (depsFromDeprecatedArgsV, depsV).mapN {
      (depsFromDeprecatedArgs, deps) =>
        val deps0 = depsFromDeprecatedArgs ++ deps
        SharedLoaderParams(
          targetsOpt.getOrElse(deps0.map(_._1).distinct),
          deps0.groupBy(_._1).mapValues(_.map(_._2)).iterator.toMap
        )
    }
  }
} 
Example 56
Source File: OutputParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.params

import caseapp.Tag
import cats.data.{Validated, ValidatedNel}
import coursier.cache.CacheLogger
import coursier.cache.loggers.RefreshLogger
import coursier.cli.options.OutputOptions
import coursier.cache.loggers.FileTypeRefreshDisplay

final case class OutputParams(
  verbosity: Int,
  progressBars: Boolean
) {
  def logger(): CacheLogger =
    logger(byFileType = false)
  def logger(byFileType: Boolean): CacheLogger = {

    val loggerFallbackMode =
      !progressBars && RefreshLogger.defaultFallbackMode

    if (verbosity >= -1)
      RefreshLogger.create(
        System.err,
        if (byFileType)
          FileTypeRefreshDisplay.create(keepOnScreen = false)
        else
          RefreshLogger.defaultDisplay(
            loggerFallbackMode,
            quiet = verbosity == -1 || Option(System.getenv("CI")).nonEmpty
          )
      )
    else
      CacheLogger.nop
  }
}

object OutputParams {
  def apply(options: OutputOptions): ValidatedNel[String, OutputParams] = {

    val verbosityV =
      if (Tag.unwrap(options.quiet) > 0 && Tag.unwrap(options.verbose) > 0)
        Validated.invalidNel("Cannot have both quiet, and verbosity > 0")
      else
        Validated.validNel(Tag.unwrap(options.verbose) - Tag.unwrap(options.quiet))

    val progressBars = options.progress

    verbosityV.map { verbosity =>
      OutputParams(
        verbosity,
        progressBars
      )
    }
  }
} 
Example 57
Source File: GetParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.get

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.cli.params.{CacheParams, OutputParams}

final case class GetParams(
  cache: CacheParams,
  output: OutputParams,
  separator: String,
  force: Boolean
)

object GetParams {
  def apply(options: GetOptions): ValidatedNel[String, GetParams] = {
    val cacheV = options.cache.params
    val outputV = OutputParams(options.output)

    val separatorV = (options.zero, options.separator) match {
      case (false, None) => Validated.validNel(System.lineSeparator)
      case (false, Some(sep)) => Validated.validNel(sep)
      case (true, None) => Validated.validNel("\u0000")
      case (true, Some("\u0000")) => Validated.validNel("\u0000")
      case (true, Some(_)) => Validated.invalidNel("--zero and --separator cannot be specific at the same time")
    }

    (cacheV, outputV, separatorV).mapN {
      case (cache, output, separator) =>
        GetParams(
          cache,
          output,
          separator,
          options.force
        )
    }
  }
} 
Example 58
Source File: SonatypeParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.publish.sonatype

import caseapp.Tag
import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.core.Authentication

final case class SonatypeParams(
  raw: Boolean,
  listProfiles: Boolean,
  list: Boolean,
  cleanList: Boolean,
  profileIdOpt: Option[String],
  profileNameOpt: Option[String],
  repositoryIdOpt: Option[String],
  create: Boolean,
  close: Boolean,
  promote: Boolean,
  drop: Boolean,
  description: Option[String],
  base: String,
  authentication: Option[Authentication],
  verbosity: Int
) {
  def needListProfiles: Boolean =
    profileIdOpt.isEmpty && (profileNameOpt.nonEmpty || repositoryIdOpt.nonEmpty)
  def needListRepositories: Boolean =
    profileIdOpt.isEmpty && repositoryIdOpt.nonEmpty
}

object SonatypeParams {
  def apply(options: SonatypeOptions): ValidatedNel[String, SonatypeParams] = {

    val description = Some(options.description).filter(_.nonEmpty)

    val list = options.list.orElse(options.cleanList).getOrElse(false)

    val checkActionsV =
      if (!options.listProfiles && !list && !options.create && !options.close && !options.promote && !options.drop)
        Validated.invalidNel("No action specified (pass either one of --list-profiles, --list, --create, --close, --drop, or --promote)")
      else if (options.create && options.profileId.isEmpty && options.profile.isEmpty)
        Validated.invalidNel("Profile id or name required to create a repository")
      else if ((options.close || options.promote || options.drop) && options.repository.isEmpty)
        Validated.invalidNel("Repository required to close, promote, or drop")
      else
        Validated.validNel(())

    // FIXME this will duplicate error messages (re-uses the same Validated

    val authV = (options.user, options.password) match {
      case (None, None) =>
        (Option(System.getenv("SONATYPE_USERNAME")), Option(System.getenv("SONATYPE_PASSWORD"))) match {
          case (Some(u), Some(p)) =>
            Validated.validNel(Some(Authentication(u, p)))
          case _ =>
            // should we allow no authentication somehow?
            Validated.invalidNel("No authentication specified (either pass --user and --password, or set SONATYPE_USERNAME and SONATYPE_PASSWORD in the environment)")
        }
      case (Some(u), Some(p)) =>
        Validated.validNel(Some(Authentication(u, p)))
      case (Some(_), None) =>
        Validated.invalidNel("User specified, but no password passed")
      case (None, Some(_)) =>
        Validated.invalidNel("Password specified, but no user passed")
    }

    (checkActionsV, authV).mapN {
      (_, auth) =>
        SonatypeParams(
          options.raw,
          options.listProfiles,
          list,
          options.cleanList.getOrElse(!options.raw),
          options.profileId,
          options.profile,
          options.repository,
          options.create,
          options.close,
          options.promote,
          options.drop,
          description,
          options.base.getOrElse("https://oss.sonatype.org/service/local"),
          auth,
          Tag.unwrap(options.verbose)
        )
    }
  }
} 
Example 59
Source File: DirectoryParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.publish.params

import java.nio.file.{Files, Path, Paths}

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.publish.dir.Dir
import coursier.cli.publish.options.DirectoryOptions
import coursier.publish.sbt.Sbt

final case class DirectoryParams(
  directories: Seq[Path],
  sbtDirectories: Seq[Path]
)

object DirectoryParams {
  def apply(options: DirectoryOptions, args: Seq[String]): ValidatedNel[String, DirectoryParams] = {

    val dirsV = options.dir.traverse { d =>
      val dir0 = Paths.get(d)
      if (Files.exists(dir0)) {
        if (Files.isDirectory(dir0))
          Validated.validNel(dir0)
        else
          Validated.invalidNel(s"$d not a directory")
      } else
        Validated.invalidNel(s"$d not found")
    }

    val sbtDirsV = ((if (options.sbt) List(".") else Nil) ::: options.sbtDir).traverse { d =>
      val dir0 = Paths.get(d)
      if (Files.exists(dir0)) {
        if (Files.isDirectory(dir0)) {
          val buildProps = dir0.resolve("project/build.properties")
          if (Files.exists(buildProps))
            Validated.validNel(dir0)
          else
            Validated.invalidNel(s"project/build.properties not found under sbt directory $d")
        } else
          Validated.invalidNel(s"$d not a directory")
      } else
        Validated.invalidNel(s"$d not found")
    }

    val extraV = args
      .toList
      .traverse { a =>
        val p = Paths.get(a)
        if (Sbt.isSbtProject(p))
          Validated.validNel((None, Some(p)))
        else if (Dir.isRepository(p))
          Validated.validNel((Some(p), None))
        else
          Validated.invalidNel(s"$a is neither an sbt project or a local repository")
      }

    (dirsV, sbtDirsV, extraV).mapN {
      case (dirs, sbtDirs, extra) =>
        DirectoryParams(
          dirs ++ extra.flatMap(_._1),
          sbtDirs ++ extra.flatMap(_._2)
        )
    }
  }
} 
Example 60
Source File: ChecksumParams.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.cli.publish.params

import cats.data.{Validated, ValidatedNel}
import cats.implicits._
import coursier.publish.checksum.ChecksumType
import coursier.cli.publish.options.ChecksumOptions

final case class ChecksumParams(
  checksumsOpt: Option[Seq[ChecksumType]]
)

object ChecksumParams {

  def apply(options: ChecksumOptions): ValidatedNel[String, ChecksumParams] = {

    val checksumsOptV =
      options.checksums match {
        case None =>
          Validated.validNel(None)
        case Some(list) =>
          list
            .flatMap(_.split(','))
            .map(_.trim)
            .filter(_.nonEmpty)
            .traverse { s =>
              Validated.fromEither(ChecksumType.parse(s))
                .toValidatedNel
            }
            .map(Some(_))
      }

    checksumsOptV.map { checksumsOpt =>
      ChecksumParams(
        checksumsOpt
      )
    }
  }
}