cats.data.Validated Scala Examples

The following examples show how to use cats.data.Validated. 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: EpisodeParser.scala    From scalalaz-gen   with Apache License 2.0 5 votes vote down vote up
package ru.scalalaz.gen.parsing

import cats.data.Validated
import cats.implicits._
import ru.scalalaz.gen.Episode

object EpisodeParser {

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

  def fromString(content: String): Validated[EpisodeParseError, Episode] =
    FormatParser
      .parseContent(content)
      .toValidated
      .leftMap(e => {
        InvalidFormat(e.longAggregateMsg)
      })
      .andThen(f => fromFormat(f))

  def fromFormat(format: FileFormat): Validated[EpisodeParseError, Episode] =
    EpisodeSettingsExtractor
      .fromMap(format.header)
      .map(rss => Episode(rss, format.otherData))
      .leftMap(list => ManyErrors(list))

} 
Example 2
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 3
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
      )
    }
  }
} 
Example 4
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 5
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 6
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 7
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 8
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 9
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 10
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 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: 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 13
Source File: PageParser.scala    From scalalaz-gen   with Apache License 2.0 5 votes vote down vote up
package ru.scalalaz.gen.parsing


import cats.implicits._
import cats.data.Validated
import ru.scalalaz.gen.Page

object PageParser {

  import ru.scalalaz.gen.parsing.SpecialPageErrors._

  def fromString(content: String): Validated[PageParseError, Page] =
    FormatParser
      .parseContent(content)
      .toValidated
      .leftMap(e => {
        InvalidFormat(e.longAggregateMsg)
      })
      .andThen(f => fromFormat(f))

  def fromFormat(format: FileFormat): Validated[PageParseError, Page] =
    PageSettingsExtractor
      .fromMap(format.header)
      .map(settings => Page(settings, format.otherData))
      .leftMap(list => ManyErrors(list))

} 
Example 14
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 15
Source File: ReprAsObjectCodec.scala    From circe-generic-extras   with Apache License 2.0 5 votes vote down vote up
package io.circe.generic.extras.codec

import cats.data.Validated
import io.circe.{ Decoder, DecodingFailure, HCursor, JsonObject }
import io.circe.generic.extras.ConfigurableDeriver
import io.circe.generic.extras.decoding.ReprDecoder
import io.circe.generic.extras.encoding.ReprAsObjectEncoder
import scala.annotation.implicitNotFound
import scala.collection.immutable.Map
import scala.language.experimental.macros
import shapeless.HNil


@implicitNotFound(
  """Could not find ReprAsObjectCodec for type ${A}.
Some possible causes for this:
- ${A} isn't a case class or sealed trat
- some of ${A}'s members don't have codecs of their own
- missing implicit Configuration"""
)
abstract class ReprAsObjectCodec[A] extends ReprDecoder[A] with ReprAsObjectEncoder[A]

object ReprAsObjectCodec {
  implicit def deriveReprAsObjectCodec[R]: ReprAsObjectCodec[R] = macro ConfigurableDeriver.deriveConfiguredCodec[R]

  val hnilReprCodec: ReprAsObjectCodec[HNil] = new ReprAsObjectCodec[HNil] {
    def configuredDecode(c: HCursor)(
      transformMemberNames: String => String,
      transformConstructorNames: String => String,
      defaults: Map[String, Any],
      discriminator: Option[String]
    ): Decoder.Result[HNil] =
      if (c.value.isObject) Right(HNil) else Left(DecodingFailure("HNil", c.history))

    def configuredDecodeAccumulating(c: HCursor)(
      transformMemberNames: String => String,
      transformConstructorNames: String => String,
      defaults: Map[String, Any],
      discriminator: Option[String]
    ): Decoder.AccumulatingResult[HNil] =
      if (c.value.isObject) Validated.valid(HNil) else Validated.invalidNel(DecodingFailure("HNil", c.history))

    def configuredEncodeObject(a: HNil)(
      transformMemberNames: String => String,
      transformDiscriminator: String => String,
      discriminator: Option[String]
    ): JsonObject = JsonObject.empty
  }
} 
Example 16
Source File: ValidatedValuesSpec.scala    From cats-scalatest   with Apache License 2.0 5 votes vote down vote up
package cats.scalatest

import org.scalatest.exceptions.TestFailedException
import cats.data.Validated

class ValidatedValuesSpec extends TestBase {
  import ValidatedValues._

  "value on Validated" should {
    "return the value inside a Validated.Right if that Validated is Validated.Right" in {
      val r: String Validated String = Validated.Valid(thisRecord)
      r.value should ===(thisRecord)
    }

    "should throw TestFailedException if that Validated is a left " in {
      val r: String Validated String = Validated.Invalid(thisTobacconist)
      val caught =
        intercept[TestFailedException] {
          r.value should ===(thisRecord)
        }
      if (isJVM)
        caught.failedCodeLineNumber.value should equal(thisLineNumber - 3)
      caught.failedCodeFileName.value should be("ValidatedValuesSpec.scala")
    }
  }

  "invalidValue on Validated" should {
    "return the value if it's invalid" in {
      val r = Validated.Invalid(thisRecord)
      r.invalidValue should ===(thisRecord)
    }

    "throw TestFailedException if the Validated is Valid" in {
      val r = Validated.Valid(thisRecord)
      val caught = intercept[TestFailedException] {
        r.invalidValue
      }
      if (isJVM)
        caught.failedCodeLineNumber.value should equal(thisLineNumber - 3)
      caught.failedCodeFileName.value should be("ValidatedValuesSpec.scala")
    }
  }

  "valid on Validated" should {
    "return the valid if it's a Valid" in {
      val r = Validated.Valid(thisRecord)
      r.valid should ===(r)
    }

    "throw TestFailedException if the Validated is Invalid" in {
      val r: String Validated String = Validated.Invalid(thisTobacconist)
      val caught =
        intercept[TestFailedException] {
          r.valid should ===(r)
        }
      if (isJVM)
        caught.failedCodeLineNumber.value should equal(thisLineNumber - 3)
      caught.failedCodeFileName.value should be("ValidatedValuesSpec.scala")
    }
  }

  "invalid on Validated" should {
    "return the invalid if it's a Invalid" in {
      val r = Validated.Invalid(thisTobacconist)
      r.invalid should ===(r)
    }

    "throw TestFailedException if the Validated is Valid" in {
      val r: String Validated String = Validated.Valid(thisRecord)
      val caught =
        intercept[TestFailedException] {
          r.invalid should ===(r)
        }
      if (isJVM)
        caught.failedCodeLineNumber.value should equal(thisLineNumber - 3)
      caught.failedCodeFileName.value should be("ValidatedValuesSpec.scala")
    }
  }
} 
Example 17
Source File: GraphQLSuperMicroService.scala    From cornichon   with Apache License 2.0 5 votes vote down vote up
package com.github.agourlay.cornichon.framework.examples.superHeroes.server

import cats.data.Validated
import cats.data.Validated.{ Invalid, Valid }
import sangria.macros.derive._
import sangria.schema.Schema
import sangria.schema._
import sangria.marshalling.circe._
import io.circe.generic.auto._

class GraphQLSuperMicroService(sm: SuperMicroService) {

  def publisherByName(sessionId: String, name: String): Option[Publisher] =
    unpack(sm.publisherByName(sessionId, name))

  def superheroByName(sessionId: String, name: String, protectIdentity: Boolean = false): Option[SuperHero] =
    unpack(sm.superheroByName(sessionId, name, protectIdentity))

  def updateSuperhero(sessionId: String, s: SuperHero): Option[SuperHero] =
    unpack(sm.updateSuperhero(sessionId, s))

  private def unpack[A](v: Validated[ApiError, A]): Option[A] =
    v match {
      case Valid(p) => Some(p)
      case Invalid(e) => e match {
        case SessionNotFound(_)   => None
        case PublisherNotFound(_) => None
        case SuperHeroNotFound(_) => None
        case _                    => throw new RuntimeException(e.msg)
      }
    }
}

object GraphQlSchema {

  implicit val PublisherType = deriveObjectType[Unit, Publisher](
    ObjectTypeDescription("A comics publisher.")
  )

  implicit val SuperHeroType = deriveObjectType[Unit, SuperHero](
    ObjectTypeDescription("A superhero.")
  )

  implicit val PublisherInputType = deriveInputObjectType[Publisher](
    InputObjectTypeName("PublisherInput")
  )

  implicit val SuperHeroInputType = deriveInputObjectType[SuperHero](
    InputObjectTypeName("SuperHeroInput")
  )

  val QueryType = deriveObjectType[Unit, GraphQLSuperMicroService](
    ObjectTypeName("Root"),
    ObjectTypeDescription("Gateway to awesomeness."),
    IncludeMethods("publisherByName", "superheroByName")
  )

  val MutationType = deriveObjectType[Unit, GraphQLSuperMicroService](
    ObjectTypeName("RootMut"),
    ObjectTypeDescription("Gateway to mutation awesomeness!"),
    IncludeMethods("updateSuperhero")
  )

  val SuperHeroesSchema = Schema(QueryType, Some(MutationType))
} 
Example 18
Source File: IssueTxValidator.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction.validation.impl

import cats.data.Validated
import com.wavesplatform.lang.script.v1.ExprScript
import com.wavesplatform.transaction.TxValidationError.GenericError
import com.wavesplatform.transaction.assets.IssueTransaction
import com.wavesplatform.transaction.validation.{TxValidator, ValidatedV}
import com.wavesplatform.transaction.{TxValidationError, TxVersion}

object IssueTxValidator extends TxValidator[IssueTransaction] {
  override def validate(tx: IssueTransaction): ValidatedV[IssueTransaction] = {
    def assetDecimals(decimals: Byte): ValidatedV[Byte] = {
      Validated
        .condNel(
          decimals >= 0 && decimals <= IssueTransaction.MaxAssetDecimals,
          decimals,
          TxValidationError.TooBigArray
        )
    }

    import tx._
    V.seq(tx)(
      V.positiveAmount(quantity, "assets"),
      V.assetName(tx.name),
      V.assetDescription(tx.description),
      assetDecimals(decimals),
      V.fee(fee),
      V.cond(version > TxVersion.V1 || script.isEmpty, GenericError("Script not supported")),
      V.cond(script.forall(_.isInstanceOf[ExprScript]), GenericError(s"Asset can only be assigned with Expression script, not Contract"))
    )
  }
} 
Example 19
Source File: GenesisTransaction.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.transaction

import cats.data.Validated
import com.google.common.primitives.{Bytes, Ints, Longs}
import com.wavesplatform.account.Address
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.crypto
import com.wavesplatform.lang.ValidationError
import com.wavesplatform.transaction.Asset.Waves
import com.wavesplatform.transaction.serialization.impl.GenesisTxSerializer
import com.wavesplatform.transaction.validation.{TxConstraints, TxValidator}
import monix.eval.Coeval
import play.api.libs.json.JsObject

import scala.util.Try

case class GenesisTransaction private (recipient: Address, amount: Long, timestamp: Long, signature: ByteStr, chainId: Byte) extends Transaction {
  override val builder                 = GenesisTransaction
  override val assetFee: (Asset, Long) = (Waves, 0)
  override val id: Coeval[ByteStr]     = Coeval.evalOnce(signature)

  override val bodyBytes: Coeval[Array[Byte]] = Coeval.evalOnce(builder.serializer.toBytes(this))
  override val bytes: Coeval[Array[Byte]]     = bodyBytes
  override val json: Coeval[JsObject]         = Coeval.evalOnce(builder.serializer.toJson(this))
}

object GenesisTransaction extends TransactionParser {
  type TransactionT = GenesisTransaction

  override val typeId: TxType                    = 1: Byte
  override val supportedVersions: Set[TxVersion] = Set(1)

  val serializer = GenesisTxSerializer

  override def parseBytes(bytes: Array[TxVersion]): Try[GenesisTransaction] =
    serializer.parseBytes(bytes)

  implicit val validator: TxValidator[GenesisTransaction] =
    tx => TxConstraints.seq(tx)(
      Validated.condNel(tx.amount >= 0, tx, TxValidationError.NegativeAmount(tx.amount, "waves")),
      TxConstraints.addressChainId(tx.recipient, tx.chainId)
    )

  def generateSignature(recipient: Address, amount: Long, timestamp: Long): Array[Byte] = {
    val payload = Bytes.concat(Ints.toByteArray(typeId), Longs.toByteArray(timestamp), recipient.bytes, Longs.toByteArray(amount))
    val hash    = crypto.fastHash(payload)
    Bytes.concat(hash, hash)
  }

  def create(recipient: Address, amount: Long, timestamp: Long): Either[ValidationError, GenesisTransaction] = {
    val signature = ByteStr(GenesisTransaction.generateSignature(recipient, amount, timestamp))
    GenesisTransaction(recipient, amount, timestamp, signature, recipient.chainId).validatedEither
  }
} 
Example 20
Source File: ConfigOps.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.settings.utils

import cats.data.Validated
import com.typesafe.config.Config
import com.wavesplatform.settings.utils.ConfigSettingsValidator.ErrorListOrOps
import net.ceedubs.ficus.readers.ValueReader

object ConfigOps {

  implicit class ConfigOps(config: Config) {

    val cfgValidator = ConfigSettingsValidator(config)

    def getValidatedSet[T: ValueReader](path: String): Set[T] = {
      cfgValidator.validateList[T](path).map(_.toSet) getValueOrThrowErrors
    }

    def getValidatedMap[K, V: ValueReader](path: String)(keyValidator: String => Validated[String, K]): Map[K, V] = {
      cfgValidator.validateMap(path)(keyValidator) getValueOrThrowErrors
    }

    def getValidatedByPredicate[T: ValueReader](path: String)(predicate: T => Boolean, errorMsg: String): T = {
      cfgValidator.validateByPredicate(path)(predicate, errorMsg) getValueOrThrowErrors
    }
  }
} 
Example 21
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 22
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 23
Source File: ResponseVerificationSyntax.scala    From http4s-poc-api   with MIT License 5 votes vote down vote up
package syntax

import java.nio.charset.StandardCharsets

import cats.data.Validated
import cats.instances.string._
import cats.syntax.eq._
import cats.syntax.show._
import cats.syntax.validated._
import cats.{Eq, Show}
import org.http4s.{EntityDecoder, Response, Status}
import typeclasses.RunSync
import zio.Task
import zio.interop.catz._

import scala.language.implicitConversions

private[syntax] trait ResponseVerificationSyntax {
  implicit def verifiedSyntax[A](a: A): VerifiedOps[A]                     = new VerifiedOps(a)
  implicit def verifiedOptionSyntax[A](a: Option[A]): VerifiedOptionOps[A] = new VerifiedOptionOps(a)

  implicit def responseVerificationSyntax(response: Task[Response[Task]]) =
    new IoResponseResultOps(response)
}

private[syntax] class IoResponseResultOps(private val response: Task[Response[Task]]) extends AnyVal {
  import syntax.responseVerification._

  def verify[A: EntityDecoder[Task, *]](status: Status, check: A => Verified[A])(
    implicit ev1: Eq[Status],
    ev2: Show[Status],
    run: RunSync[Task]
  ): Verified[A] =
    run
      .syncUnsafe(response)
      .fold(
        err => s"Should succeed but returned the error $err".invalidNel,
        res => res.status isSameAs status andThen { _ => verifiedResponse[A](res, check) }
      )

  def verifyResponseText(status: Status, expected: String)(
    implicit ev1: Eq[Status],
    ev2: Show[Status],
    run: RunSync[Task]
  ): Verified[String] =
    run
      .syncUnsafe(response)
      .fold(
        err => s"Should succeed but returned the error $err".invalidNel,
        res => res.status isSameAs status andThen { _ => verifiedResponseText(res, expected) }
      )

  private def verifiedResponse[A: EntityDecoder[Task, *]](res: Response[Task], check: A => Verified[A])(
    implicit run: RunSync[Task]
  ): Verified[A] =
    run
      .syncUnsafe(res.as[A])
      .fold(
        respErr => s"Response should succeed but returned the error $respErr".invalidNel,
        respRes => check(respRes)
      )

  private def verifiedResponseText[A](res: Response[Task], expected: String)(
    implicit run: RunSync[Task]
  ): Verified[String] =
    run
      .syncUnsafe(res.body.compile.toVector)
      .map(_.toArray)
      .fold(
        respErr => s"Response should succeed but returned the error $respErr".invalidNel,
        respMsg => new String(respMsg, StandardCharsets.UTF_8) isSameAs expected
      )
}

private[syntax] class VerifiedOps[A](private val a: A) extends AnyVal {
  def isNotSameAs(expected: =>A)(implicit ev1: Eq[A], ev2: Show[A]): Verified[A] =
    Validated.condNel(
      a =!= expected,
      a,
      s"Unexpected value. Expected different from ${expected.show} but was ${a.show}"
    )

  def isSameAs(expected: =>A)(implicit ev1: Eq[A], ev2: Show[A]): Verified[A] =
    Validated.condNel(a === expected, a, s"Unexpected value. Expected ${expected.show} but was ${a.show}")

  def is(p: A => Boolean, reason: =>String = "")(implicit ev: Show[A]): Verified[A] =
    Validated.condNel(p(a), a, s"Unexpected value ${a.show}: Reason $reason")
}

private[syntax] class VerifiedOptionOps[A](private val a: Option[A]) extends AnyVal {
  def isNotEmpty: Verified[Option[A]] =
    Validated.condNel(a.isDefined, a, s"Unexpected empty option value")
} 
Example 24
Source File: JacksonParserSuite.scala    From circe-jackson   with Apache License 2.0 5 votes vote down vote up
package io.circe.jackson

import cats.data.Validated
import com.fasterxml.jackson.core.JsonToken
import com.fasterxml.jackson.databind.{ ObjectMapper, ObjectReader }
import io.circe.Json
import io.circe.testing.ParserTests
import java.io.{ ByteArrayInputStream, File }

import scala.io.Source

class JacksonParserSuite extends CirceSuite with JacksonInstances {
  checkAll("Parser", ParserTests(`package`).fromString(arbitraryCleanedJson, shrinkJson))
  checkAll(
    "Parser",
    ParserTests(`package`).fromFunction[Array[Byte]]("fromByteArray")(
      s => s.getBytes("UTF-8"),
      p => p.parseByteArray _,
      p => p.decodeByteArray[Json] _,
      p => p.decodeByteArrayAccumulating[Json] _
    )(arbitraryCleanedJson, shrinkJson)
  )

  "parse and decode(Accumulating)" should "fail on invalid input" in forAll { (s: String) =>
    assert(parse(s"Not JSON $s").isLeft)
    assert(decode[Json](s"Not JSON $s").isLeft)
    assert(decodeAccumulating[Json](s"Not JSON $s").isInvalid)
  }

  "parseFile and decodeFile(Accumulating)" should "parse a JSON file" in {
    val url = getClass.getResource("/io/circe/jackson/examples/glossary.json")
    val file = new File(url.toURI)

    assert(decodeFile[Json](file) === Right(glossary))
    assert(decodeFileAccumulating[Json](file) == Validated.valid(glossary))
    assert(parseFile(file) === Right(glossary))
  }

  "parseByteArray and decodeByteArray(Accumulating)" should "parse an array of elementAsBytes" in {
    val bytes = glossaryAsBytes

    assert(decodeByteArray[Json](bytes) === Right(glossary))
    assert(decodeByteArrayAccumulating[Json](bytes) === Validated.valid(glossary))
    assert(parseByteArray(bytes) === Right(glossary))
  }

  for (elementCount <- 1 to 4) {
    "CirceJsonDeserializer" should s"be useable with Jackson's MappingIterator " +
      s"with ${elementCount} elements in array" in {
      val input = new ByteArrayInputStream(createJsonArrayAsBytes(glossaryAsBytes, elementCount))
      val objectMapper = new ObjectMapper()
      objectMapper.registerModule(CirceJsonModule)
      val jsonParser = objectMapper.getFactory.createParser(input)

      assert(jsonParser.nextToken() == JsonToken.START_ARRAY)
      assert(jsonParser.nextToken() == JsonToken.START_OBJECT)

      val reader = createReader(objectMapper).forType(classOf[Json])
      val iterator = reader.readValues[Json](jsonParser)
      var counter = 0
      while (iterator.hasNext) {
        val glossaryFromIterator = iterator.next()
        assert(glossary == glossaryFromIterator)
        counter = counter + 1
      }
      assert(counter == elementCount)
    }
  }

  // workaround warnings from compiler with Jackson 2.5
  @unchecked
  private def createReader(objectMapper: ObjectMapper): ObjectReader =
    objectMapper.reader()

  private def createJsonArrayAsBytes(elementAsBytes: Array[Byte], elementCount: Int): Array[Byte] = {
    val byteArrayOutput = new java.io.ByteArrayOutputStream()
    byteArrayOutput.write('[')
    for (i <- 1 to elementCount) {
      if (i != 1) {
        byteArrayOutput.write(',')
      }
      byteArrayOutput.write(elementAsBytes)
    }
    byteArrayOutput.write(']')
    byteArrayOutput.toByteArray
  }

  private def glossaryAsBytes = {
    val stream = getClass.getResourceAsStream("/io/circe/jackson/examples/glossary.json")
    val source = Source.fromInputStream(stream)
    val bytes = source.map(_.toByte).toArray
    source.close()
    bytes
  }
} 
Example 25
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 26
Source File: User.scala    From whirlwind-tour-akka-typed   with Apache License 2.0 5 votes vote down vote up
package de.heikoseeberger.wtat

import cats.data.{ NonEmptyList, Validated }
import cats.syntax.apply._
import cats.syntax.either._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.boolean.And
import eu.timepit.refined.char.LetterOrDigit
import eu.timepit.refined.collection.{ Forall, NonEmpty }
import eu.timepit.refined.refineV

object User {

  type Username           = Refined[String, UsernameRefinement]
  type UsernameRefinement = And[NonEmpty, Forall[LetterOrDigit]]

  type Nickname           = Refined[String, NicknameRefinement]
  type NicknameRefinement = NonEmpty

  def apply(username: String, nickname: String): Validated[NonEmptyList[String], User] =
    (validateUsername(username), validateNickname(nickname)).mapN(new User(_, _))

  def validateUsername(username: String): Validated[NonEmptyList[String], Username] =
    refineV[UsernameRefinement](username).toValidatedNel

  def validateNickname(nickname: String): Validated[NonEmptyList[String], Nickname] =
    refineV[NicknameRefinement](nickname).toValidatedNel
}

final case class User(username: User.Username, nickname: User.Nickname) 
Example 27
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 28
Source File: ConfigOps.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.settings.utils

import java.util.Properties

import cats.data.Validated
import com.typesafe.config.{Config, ConfigRenderOptions}
import com.wavesplatform.dex.settings.utils.ConfigSettingsValidator.ErrorListOrOps
import mouse.any._
import net.ceedubs.ficus.readers.ValueReader

object ConfigOps {

  final implicit class ConfigOps(config: Config) {

    val cfgValidator: ConfigSettingsValidator = ConfigSettingsValidator(config)

    def getValidatedSet[T: ValueReader](path: String): Set[T] = {
      cfgValidator.validateList[T](path).map(_.toSet) getValueOrThrowErrors
    }

    def getValidatedMap[K, V: ValueReader](path: String)(keyValidator: String => Validated[String, K]): Map[K, V] = {
      cfgValidator.validateMap(path)(keyValidator) getValueOrThrowErrors
    }

    def getValidatedByPredicate[T: ValueReader](path: String)(predicate: T => Boolean, errorMsg: String): T = {
      cfgValidator.validateByPredicate(path)(predicate, errorMsg) getValueOrThrowErrors
    }

    def toProperties: Properties = new Properties() unsafeTap { properties =>
      config.entrySet().forEach { entry =>
        properties.setProperty(entry.getKey, config getString entry.getKey)
      }
    }

    def rendered: String =
      config
        .resolve()
        .root()
        .render(
          ConfigRenderOptions
            .concise()
            .setOriginComments(false)
            .setComments(false)
            .setFormatted(true)
            .setJson(false)
        )
  }
} 
Example 29
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 30
Source File: PathGroupTest.scala    From docless   with MIT License 5 votes vote down vote up
package com.timeout.docless.swagger

import org.scalatest.{FreeSpec, Inside, Matchers}
import cats.data.NonEmptyList
import cats.data.Validated
import SchemaError._
import com.timeout.docless.schema.JsonSchema
import com.timeout.docless.schema.JsonSchema._
import com.timeout.docless.swagger.Method._

class PathGroupTest extends FreeSpec with Matchers {
  "PathGroup" - {
    val petstore = PetstoreSchema()
    val pet      = PetstoreSchema.Schemas.pet

    val paths     = Path("/example") :: petstore.paths.get.toList
    val defs      = petstore.definitions.get.toList
    val defsNoPet = defs.filterNot(_.id === pet.id)
    val params    = petstore.parameters.get.toList

    val group1          = PathGroup(paths, defs, params)
    val group2          = PathGroup(List(Path("/extra")), Nil, Nil)
    val groupMissingErr = PathGroup(paths, defsNoPet, params)

    def err(path: String, m: Method, f: Definition => Ref): SchemaError =
      missingDefinition(RefWithContext.response(f(pet.definition), m, path))

    "aggregate" - {
      "when some top level definitions are missing" - {
        "returns the missing refs" in {
          PathGroup.aggregate(petstore.info, List(groupMissingErr)) should ===(
            Validated.invalid[NonEmptyList[SchemaError], APISchema](
              NonEmptyList.of(
                err("/pets", Get, ArrayRef.apply),
                err("/pets", Post, TypeRef.apply),
                err("/pets/{id}", Get, TypeRef.apply),
                err("/pets/{id}", Delete, TypeRef.apply)
              )
            )
          )
        }
      }
      "when some nested definitions are missing" - {
        val info = Info("example")
        case class Nested(name: String)
        case class TopLevel(nested: Nested)

        val schema = JsonSchema.deriveFor[TopLevel]
        val nested = schema.relatedDefinitions.head

        val paths = List(
          "/example".Post(
            Operation('_, "...")
              .withParams(BodyParameter(schema = Some(schema.asRef)))
          )
        )

        val withNested    = PathGroup(paths, schema.definitions.toList, Nil)
        val withoutNested = PathGroup(paths, List(schema.definition), Nil)

        "returns the missing refs" in {
          PathGroup.aggregate(info, List(withNested)).isValid shouldBe true
          PathGroup.aggregate(info, List(withoutNested)) should ===(
            Validated.invalid[NonEmptyList[SchemaError], APISchema](
              NonEmptyList.of(
                MissingDefinition(
                  RefWithContext.definition(nested.asRef, schema.definition)
                )
              )
            )
          )
        }
      }
      "when no definition is missing" - {
        "returns a valid api schema" in new Inside {
          inside(PathGroup.aggregate(petstore.info, List(group1, group2))) {
            case Validated.Valid(schema) =>
              schema.info should ===(petstore.info)
              schema.paths.get should ===(group1.paths ++ group2.paths)
              schema.definitions.get should ===(
                group1.definitions ++ group2.definitions
              )
              schema.parameters.get should ===(group1.params ++ group2.params)
          }
        }
      }
    }
  }
} 
Example 31
Source File: CatsIntegrationSpec.scala    From octopus   with Apache License 2.0 5 votes vote down vote up
package octopus.cats

import cats.data.{NonEmptyList, Validated}
import octopus.example.domain._
import octopus.syntax._
import octopus.{Fixtures, ValidationError}
import org.scalatest.matchers.must.Matchers
import org.scalatest.wordspec.AnyWordSpec

class CatsIntegrationSpec
  extends AnyWordSpec with Matchers with Fixtures {

  "Cats Integration" should {

    "support ValidatedNel" when {

      "Valid scenario" in {
        1.validate.toValidatedNel mustBe Validated.Valid(1)
        userId_Valid.validate.toValidatedNel mustBe Validated.Valid(userId_Valid)
        user_Valid.validate.toValidatedNel mustBe Validated.Valid(user_Valid)
      }

      "Invalid scenario" in {

        userId_Invalid.validate.toValidatedNel mustBe Validated.Invalid(
          NonEmptyList.of(ValidationError(UserId.Err_MustBePositive))
        )

        user_Invalid1.validate.toValidatedNel.leftMap(_.map(_.toPair)) mustBe Validated.Invalid(
          NonEmptyList.of(
            "id" -> UserId.Err_MustBePositive,
            "email" -> Email.Err_MustContainAt,
            "email" -> Email.Err_MustContainDotAfterAt,
            "address.postalCode" -> PostalCode.Err_MustBeLengthOf5,
            "address.postalCode" -> PostalCode.Err_MustContainOnlyDigits,
            "address.city" -> Address.Err_MustNotBeEmpty,
            "address.street" -> Address.Err_MustNotBeEmpty
          )
        )
      }
    }

    "support Validated" when {

      "Valid scenario" in {
        1.validate.toValidated mustBe Validated.Valid(1)
        userId_Valid.validate.toValidated mustBe Validated.Valid(userId_Valid)
        user_Valid.validate.toValidated mustBe Validated.Valid(user_Valid)
      }

      "Invalid scenario" in {

        userId_Invalid.validate.toValidated mustBe Validated.Invalid(
          List(ValidationError(UserId.Err_MustBePositive))
        )

        user_Invalid1.validate.toValidated.leftMap(_.map(_.toPair)) mustBe Validated.Invalid(
          List(
            "id" -> UserId.Err_MustBePositive,
            "email" -> Email.Err_MustContainAt,
            "email" -> Email.Err_MustContainDotAfterAt,
            "address.postalCode" -> PostalCode.Err_MustBeLengthOf5,
            "address.postalCode" -> PostalCode.Err_MustContainOnlyDigits,
            "address.city" -> Address.Err_MustNotBeEmpty,
            "address.street" -> Address.Err_MustNotBeEmpty
          )
        )
      }
    }
  }

} 
Example 32
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 33
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 34
Source File: TestSuiteTests.scala    From circe-json-schema   with Apache License 2.0 5 votes vote down vote up
package io.circe.schema

import cats.data.Validated
import io.circe.{ Decoder, Json }
import java.io.File
import org.scalatest.flatspec.AnyFlatSpec

case class SchemaTestCase(description: String, data: Json, valid: Boolean)
case class SchemaTest(description: String, schema: Json, tests: List[SchemaTestCase])

object SchemaTestCase {
  implicit val decodeSchemaTestCase: Decoder[SchemaTestCase] = io.circe.generic.semiauto.deriveDecoder
}

object SchemaTest {
  implicit val decodeSchemaTest: Decoder[SchemaTest] = io.circe.generic.semiauto.deriveDecoder
}

class TestSuiteTests(path: String) extends AnyFlatSpec {
  val tests: List[SchemaTest] = io.circe.jawn
    .decodeFile[List[SchemaTest]](new File(path))
    .getOrElse(
      throw new Exception(s"Unable to load test file: $path")
    )

  tests.foreach {
    case SchemaTest(description, schema, tests) =>
      tests.foreach {
        case SchemaTestCase(caseDescription, data, valid) =>
          val expected = if (valid) "validate successfully" else "fail to validate"
          s"$description: $caseDescription" should expected in {
            val errors = Schema.load(schema).validate(data)

            if (valid) {
              assert(errors == Validated.valid(()))
            } else {
              assert(errors.isInvalid)
            }
          }

          it should s"$expected when schema is loaded from a string" in {
            val errors = Schema.loadFromString(schema.noSpaces).get.validate(data)

            if (valid) {
              assert(errors == Validated.valid(()))
            } else {
              assert(errors.isInvalid)
            }
          }
      }
  }
}

class AdditionalItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/additionalItems.json")
class AdditionalPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/additionalProperties.json")
class AllOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/allOf.json")
class AnyOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/anyOf.json")
class BooleanSchemaTestSuiteTests extends TestSuiteTests("tests/tests/draft7/boolean_schema.json")
class ConstTestSuiteTests extends TestSuiteTests("tests/tests/draft7/const.json")
class ContainsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/contains.json")
class DefaultTestSuiteTests extends TestSuiteTests("tests/tests/draft7/default.json")
//class DefinitionsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/definitions.json")
class EnumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/enum.json")
class ExclusiveMaximumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/exclusiveMaximum.json")
class ExclusiveMinimumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/exclusiveMinimum.json")
class FormatTestSuiteTests extends TestSuiteTests("tests/tests/draft7/format.json")
class IfThenElseTestSuiteTests extends TestSuiteTests("tests/tests/draft7/if-then-else.json")
class ItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/items.json")
class MaximumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maximum.json")
class MaxItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maxItems.json")
class MaxLengthTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maxLength.json")
class MaxPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/maxProperties.json")
class MinimumTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minimum.json")
class MinItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minItems.json")
class MinLengthTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minLength.json")
class MinPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/minProperties.json")
class MultipleOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/multipleOf.json")
class NotTestSuiteTests extends TestSuiteTests("tests/tests/draft7/not.json")
class OneOfTestSuiteTests extends TestSuiteTests("tests/tests/draft7/oneOf.json")
class PatternTestSuiteTests extends TestSuiteTests("tests/tests/draft7/pattern.json")
class PatternPropertiesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/patternProperties.json")
class PropertyNamesTestSuiteTests extends TestSuiteTests("tests/tests/draft7/propertyNames.json")
// Not currently running remote tests.
//class RefTestSuiteTests extends TestSuiteTests("tests/tests/draft7/ref.json")
//class RefRemoteTestSuiteTests extends TestSuiteTests("tests/tests/draft7/refRemote.json")
class RequiredTestSuiteTests extends TestSuiteTests("tests/tests/draft7/required.json")
class TypeTestSuiteTests extends TestSuiteTests("tests/tests/draft7/type.json")
class UniqueItemsTestSuiteTests extends TestSuiteTests("tests/tests/draft7/uniqueItems.json") 
Example 35
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 36
Source File: UnusedLetCheck.scala    From bosatsu   with Apache License 2.0 5 votes vote down vote up
package org.bykn.bosatsu

import cats.Applicative
import cats.data.{Chain, Validated, ValidatedNec, Writer, NonEmptyChain}
import cats.implicits._

import Expr._
import Identifier.Bindable

object UnusedLetCheck {

  private[this] val ap = Applicative[Writer[Chain[(Bindable, Region)], ?]]
  private[this] val empty: Writer[Chain[(Bindable, Region)], Set[Bindable]] = ap.pure(Set.empty)

  private[this] def checkArg(arg: Bindable, reg: => Region, w: Writer[Chain[(Bindable, Region)], Set[Bindable]]) =
    w.flatMap { free =>
      if (free(arg)) ap.pure(free - arg)
      else {
        // this arg is free:
        ap.pure(free).tell(Chain.one((arg, reg)))
      }
    }

  private[this] def loop[A: HasRegion](e: Expr[A]): Writer[Chain[(Bindable, Region)], Set[Bindable]] =
    e match {
      case Annotation(expr, _, _) =>
        loop(expr)
      case AnnotatedLambda(arg, _, expr, _) =>
        checkArg(arg, HasRegion.region(e), loop(expr))
      case Lambda(arg, expr, _) =>
        checkArg(arg, HasRegion.region(e), loop(expr))
      case Let(arg, expr, in, rec, _) =>
        val exprCheck = loop(expr)
        val exprRes =
          // if it is recursive, it is definitely used, because
          // that is automatically applied in source conversions
          if (rec.isRecursive) exprCheck.map(_ - arg) else exprCheck
        val inCheck = checkArg(arg, HasRegion.region(e), loop(in))
        (exprRes, inCheck).mapN(_ ++ _)
      case Var(None, name: Bindable, _) =>
        // this is a free variable:
        ap.pure(Set(name))
      case Var(_, _, _) | Literal(_, _) => empty
      case App(fn, arg, _) =>
        (loop(fn), loop(arg)).mapN(_ ++ _)
      case Match(arg, branches, _) =>
        // TODO: patterns need their own region
        val argCheck = loop(arg)
        val bcheck = branches.traverse { case (pat, expr) =>
          val region = HasRegion.region(expr)
          loop(expr).flatMap { frees =>
            val thisPatNames = pat.names
            val unused = thisPatNames.filterNot(frees)
            val nextFrees = frees -- thisPatNames

            ap.pure(nextFrees).tell(Chain.fromSeq(unused.map((_, region))))
          }
        }
        .map(_.combineAll)

      (argCheck, bcheck).mapN(_ ++ _)
    }

  
  def freeBound[A](e: Expr[A]): Set[Bindable] =
    loop(e)(HasRegion.instance(_ => Region(0, 0))).run._2
} 
Example 37
Source File: IorMethods.scala    From bosatsu   with Apache License 2.0 5 votes vote down vote up
package org.bykn.bosatsu

import cats.data.{Ior, Validated}

object IorMethods {
  implicit class IorExtension[A, B](val ior: Ior[A, B]) extends AnyVal {
    def strictToValidated: Validated[A, B] =
      ior match {
        case Ior.Right(b) => Validated.valid(b)
        case Ior.Left(a) => Validated.invalid(a)
        case Ior.Both(a, _) => Validated.invalid(a)
      }
  }
} 
Example 38
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 39
Source File: TypeRecursionCheckTest.scala    From bosatsu   with Apache License 2.0 5 votes vote down vote up
package org.bykn.bosatsu

import cats.data.Validated
import org.bykn.bosatsu.rankn.TypeEnv
import org.scalatest.FunSuite

class TypeRecursionCheckTest extends FunSuite {

  def allowed(teStr: String) = {
    val te = TestUtils.typeEnvOf(PackageName.PredefName, teStr)
    VarianceFormula.solve(TypeEnv.empty, te.allDefinedTypes) match {
      case Left(errs) => fail(s"couldn't solve: $errs")
      case Right(teVar) =>
        assert(
          TypeRecursionCheck.checkLegitRecursion(TypeEnv.empty, teVar) ==
            Validated.valid(()))
    }
  }

  def disallowed(teStr: String) = {
    val te = TestUtils.typeEnvOf(PackageName.PredefName, teStr)
    VarianceFormula.solve(TypeEnv.empty, te.allDefinedTypes) match {
      case Left(errs) => fail(s"couldn't solve: $errs")
      case Right(teVar) =>
        assert(
          TypeRecursionCheck.checkLegitRecursion(TypeEnv.empty, teVar).isInvalid)
    }
  }

  test("linked list is allowed") {
    allowed("""#
enum Lst: E, N(head: a, tail: Lst[a])
""")
  }

  test("tree is allowed") {
    allowed("""#
enum Lst: E, N(head: a, tail: Lst[a])

struct Tree(root: a, children: Lst[Tree[a]])
""")
  }

  test("directory example is allowed") {
    allowed("""#
enum Lst: E, N(head: a, tail: Lst[a])

enum Path:
  Dir(name: String, children: Lst[Path])
  File(name: String, content: String)
""")
  }

  test("cont is allowed with Tree") {
    allowed("""#
struct Cont(fn: (a -> b) -> b)

struct Tree(root: a, children: Cont[Tree[a], b])
""")

    disallowed("""#
struct ICont(fn: (a -> a) -> a)

struct Tree(root: a, children: ICont[Tree[a]])
""")
  }

  test("y-combinator type is disallowed") {
    disallowed("""#
struct W(fn: W[a, b] -> a -> b)
""")
  }

  test("mutual recursion is (currently) completely unallowed") {
    disallowed("""#
struct Foo(bar: Bar)
struct Bar(foo: Foo)
""")
  }

  test("recursion with type constructors is disallowed") {
    disallowed("""#
struct Tree(root: a, children: f[Tree[a]])
""")
  }
} 
Example 40
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 41
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 42
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 43
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 44
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 45
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 46
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 47
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 48
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 49
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 50
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 51
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 52
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
        )
    }
  }
}