packages feed

cabal2json (empty) → 0.0.0.0

raw patch · 5 files changed

+966/−0 lines, 5 filesdep +Cabaldep +aesondep +autodocodec

Dependencies added: Cabal, aeson, autodocodec, autodocodec-yaml, base, bytestring, cabal2json, hashable, pretty, pretty-show, sydtest, sydtest-aeson, text, unordered-containers, utf8-string

Files

+ app/Main.hs view
@@ -0,0 +1,6 @@+module Main where++import Cabal2JSON++main :: IO ()+main = cabal2JSON
+ cabal2json.cabal view
@@ -0,0 +1,74 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.34.7.+--+-- see: https://github.com/sol/hpack++name:           cabal2json+version:        0.0.0.0+synopsis:       Turn a .cabal file into a .json file+homepage:       https://github.com/NorfairKing/cabal2json#readme+bug-reports:    https://github.com/NorfairKing/cabal2json/issues+author:         Tom Sydney Kerckhove+maintainer:     syd@cs-syd.eu+copyright:      Copyright (c) 2022 Tom Sydney Kerckhove+license:        MIT+build-type:     Simple++source-repository head+  type: git+  location: https://github.com/NorfairKing/cabal2json++library+  exposed-modules:+      Cabal2JSON+  other-modules:+      Paths_cabal2json+  hs-source-dirs:+      src+  build-depends:+      Cabal+    , aeson+    , autodocodec+    , base >=4.7 && <5+    , bytestring+    , hashable+    , pretty+    , pretty-show+    , text+    , unordered-containers+  default-language: Haskell2010++executable cabal2json+  main-is: Main.hs+  other-modules:+      Paths_cabal2json+  hs-source-dirs:+      app+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.7 && <5+    , cabal2json+  default-language: Haskell2010++test-suite cabal2json-test+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  other-modules:+      Cabal2JSONSpec+      Paths_cabal2json+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-tool-depends:+      sydtest-discover:sydtest-discover+  build-depends:+      Cabal+    , autodocodec+    , autodocodec-yaml+    , base >=4.7 && <5+    , cabal2json+    , sydtest+    , sydtest-aeson+    , utf8-string+  default-language: Haskell2010
+ src/Cabal2JSON.hs view
@@ -0,0 +1,788 @@+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Cabal2JSON+  ( cabal2JSON,+  )+where++import Autodocodec+import Control.Arrow (first)+import Data.Aeson (FromJSON, ToJSON)+import qualified Data.ByteString.Char8 as SB8+import qualified Data.ByteString.Lazy as LB+import qualified Data.HashMap.Strict as HM+import Data.Hashable+import qualified Data.List.NonEmpty as NE+import qualified Data.Text as T+import Data.Text.Encoding+import Distribution.Compiler as Cabal+import Distribution.License as Cabal+import Distribution.ModuleName as Cabal+import Distribution.PackageDescription+import Distribution.PackageDescription.Parsec as Cabal+import Distribution.Parsec (eitherParsec)+import Distribution.Pretty as Pretty+import Distribution.SPDX (LicenseExpression (..), SimpleLicenseExpression (..))+import qualified Distribution.SPDX as SPDX+import Distribution.SPDX.License as SPDX+import Distribution.System+import Distribution.Types.CondTree as Cabal+import Distribution.Types.Dependency as Cabal+import Distribution.Types.ExeDependency as Cabal+import Distribution.Types.ExecutableScope as Cabal+import Distribution.Types.ForeignLib as Cabal+import Distribution.Types.ForeignLibOption as Cabal+import Distribution.Types.ForeignLibType as Cabal+import Distribution.Types.IncludeRenaming as Cabal+import Distribution.Types.LegacyExeDependency as Cabal+import Distribution.Types.LibraryVisibility as Cabal+import Distribution.Types.Mixin as Cabal+import Distribution.Types.PackageId as Cabal+import Distribution.Types.PackageName as Cabal+import Distribution.Types.PkgconfigDependency as Cabal+import Distribution.Types.PkgconfigName+import Distribution.Types.PkgconfigVersion+import Distribution.Types.PkgconfigVersionRange+import Distribution.Types.UnqualComponentName as Cabal+import Distribution.Types.Version as Cabal+import Distribution.Types.VersionRange as Cabal+import Distribution.Utils.ShortText as Cabal+import Distribution.Verbosity as Cabal+import Language.Haskell.Extension+import System.Environment++cabal2JSON :: IO ()+cabal2JSON = do+  args <- getArgs+  case args of+    [] -> error "Please provide path to cabal file as CLI argument"+    arg -> do+      genericPackageDescription <- Cabal.readGenericPackageDescription Cabal.deafening (head arg)+      SB8.putStrLn $ LB.toStrict $ encodeJSONViaCodec genericPackageDescription++instance HasCodec GenericPackageDescription where+  codec =+    object "GenericPackageDescription" $+      GenericPackageDescription+        <$> requiredField' "description" .= packageDescription+        <*> optionalFieldWithOmittedDefault' "package-flags" [] .= genPackageFlags+        <*> optionalField' "library" .= condLibrary+        <*> optionalFieldWithOmittedDefaultWith' "sublibraries" unqualComponentNameCodec [] .= condSubLibraries+        <*> optionalFieldWithOmittedDefaultWith' "foreign-libs" unqualComponentNameCodec [] .= condForeignLibs+        <*> optionalFieldWithOmittedDefaultWith' "executables" unqualComponentNameCodec [] .= condExecutables+        <*> optionalFieldWithOmittedDefaultWith' "test-suites" unqualComponentNameCodec [] .= condTestSuites+        <*> optionalFieldWithOmittedDefaultWith' "benchmarks" unqualComponentNameCodec [] .= condBenchmarks++deriving via (Autodocodec GenericPackageDescription) instance (FromJSON GenericPackageDescription)++deriving via (Autodocodec GenericPackageDescription) instance (ToJSON GenericPackageDescription)++unqualComponentNameCodec :: HasCodec b => JSONCodec [(UnqualComponentName, b)]+unqualComponentNameCodec = mapInListForCodec mkUnqualComponentName unUnqualComponentName++instance HasCodec UnqualComponentName where+  codec = dimapCodec mkUnqualComponentName unUnqualComponentName codec++mapInListForCodec ::+  HasCodec b =>+  (String -> a) ->+  (a -> String) ->+  JSONCodec [(a, b)]+mapInListForCodec fromText toText =+  dimapCodec+    (f . HM.toList)+    (HM.fromList . g)+    codec+  where+    f = map (first fromText)+    g = map (first toText)++instance Hashable UnqualComponentName where+  hashWithSalt s = hashWithSalt s . unUnqualComponentName++instance HasCodec VersionRange where+  codec = bimapCodec f g codec+    where+      f = \s -> case eitherParsec s of+        Left pe -> Left $ show pe+        Right a -> Right a+      g = prettyShow++instance HasCodec CompilerFlavor where+  codec =+    stringConstCodec+      [ (GHC, "GHC"),+        (GHCJS, "GHCJS"),+        (NHC, "NHC"),+        (YHC, "YHC"),+        (HBC, "HBC"),+        (Helium, "Helium"),+        (JHC, "JHC"),+        (LHC, "LHC"),+        (UHC, "UHC"),+        (Eta, "Eta")+      ]++instance HasCodec PackageDescription where+  codec =+    object "PackageDescription" $+      PackageDescription+        <$> requiredField' "spec-version" .= specVersionRaw+        <*> requiredField' "package" .= package+        <*> requiredField' "license" .= licenseRaw+        <*> requiredField' "license-files" .= licenseFiles+        <*> requiredField' "copyright" .= copyright+        <*> requiredField' "maintainer" .= maintainer+        <*> requiredField' "author" .= author+        <*> requiredField' "stability" .= stability+        <*> requiredField' "tested-with" .= testedWith+        <*> requiredField' "homepage" .= homepage+        <*> requiredField' "pkg-url" .= pkgUrl+        <*> requiredField' "bug-reports" .= bugReports+        <*> requiredField' "source-repos" .= sourceRepos+        <*> requiredField' "synopsis" .= synopsis+        <*> requiredField' "description" .= description+        <*> requiredField' "category" .= category+        <*> requiredField' "custom-fields" .= customFieldsPD+        <*> requiredField' "build-type-raw" .= buildTypeRaw+        <*> requiredField' "custom-setup" .= setupBuildInfo+        <*> requiredField' "library" .= library+        <*> requiredField' "sublibraries" .= subLibraries+        <*> requiredField' "executables" .= executables+        <*> requiredField' "foreign-libs" .= foreignLibs+        <*> requiredField' "test-suites" .= testSuites+        <*> requiredField' "benchmarks" .= benchmarks+        <*> requiredField' "data-files" .= dataFiles+        <*> requiredField' "data-dir" .= dataDir+        <*> requiredField' "extra-source-files" .= extraSrcFiles+        <*> requiredField' "extra-tmp-files" .= extraTmpFiles+        <*> requiredField' "extra-doc-files" .= extraDocFiles++instance HasCodec (PerCompilerFlavor [String]) where+  codec = dimapCodec (uncurry PerCompilerFlavor) (\(PerCompilerFlavor a b) -> (a, b)) codec++instance (HasCodec a) => HasCodec (a, a) where+  codec = dimapCodec (\(a : [b]) -> (a, b)) (\(a, b) -> [a, b]) codec++instance HasCodec (CompilerFlavor, VersionRange) where+  codec =+    object "(CompilerFlavor, VersionRange)" $+      (,)+        <$> requiredField' "compiler" .= fst+        <*> requiredField' "versionRange" .= snd++instance (HasCodec a) => HasCodec (a, a, a) where+  codec = dimapCodec (\(a : b : [c]) -> (a, b, c)) (\(a, b, c) -> [a, b, c]) codec++instance HasCodec (Maybe String, String) where+  codec =+    dimapCodec+      ( \case+          ("", s) -> (Nothing, s)+          (s1, s2) -> (Just s1, s2)+      )+      ( \case+          (Nothing, s) -> ("", s)+          (Just s1, s2) -> (s1, s2)+      )+      codec++instance HasCodec PackageName where+  codec = dimapCodec mkPackageName unPackageName codec++instance HasCodec PackageIdentifier where+  codec =+    object "PackgeIdentifier" $+      PackageIdentifier+        <$> requiredField' "name" .= pkgName+        <*> requiredField' "version" .= pkgVersion++instance HasCodec RepoKind where+  codec =+    object "RepoKind" $+      dimapCodec f g $+        eitherCodec (pure RepoHead) $+          eitherCodec (pure RepoThis) $+            requiredField' "repo-kind"+    where+      f = \case+        Left _ -> RepoHead+        Right (Left _) -> RepoThis+        Right (Right s) -> RepoKindUnknown s+      g = \case+        RepoHead -> Left ()+        RepoThis -> Right $ Left ()+        RepoKindUnknown s -> Right $ Right s++instance HasCodec RepoType where+  -- TODO add OtherRepoType+  codec =+    stringConstCodec+      [ (Darcs, "Darcs"),+        (Git, "Git"),+        (SVN, "SVN"),+        (CVS, "CVS"),+        (Mercurial, "Mercurial"),+        (GnuArch, "GnuArch"),+        (Bazaar, "Bazaar"),+        (Monotone, "Monotone")+      ]++instance HasCodec Dependency where+  codec =+    object "Dependency" $+      Dependency+        <$> requiredField' "package-name" .= (\(Dependency name _ _) -> name)+        <*> requiredField' "version-range" .= (\(Dependency _ version _) -> version)+        <*> requiredField' "library" .= (\(Dependency _ _ lib) -> lib)++instance HasCodec SourceRepo where+  codec =+    object "SourceRepo" $+      SourceRepo+        <$> requiredField' "kind" .= repoKind+        <*> requiredField' "type" .= repoType+        <*> requiredField' "location" .= repoLocation+        <*> requiredField' "module" .= repoModule+        <*> requiredField' "branch" .= repoBranch+        <*> requiredField' "tag" .= repoTag+        <*> requiredField' "subdir" .= repoSubdir++instance HasCodec ShortText where+  codec = dimapCodec toShortText fromShortText codec++instance HasCodec Cabal.License where+  -- TODO add others+  codec =+    named "Cabal.License" $+      stringConstCodec+        [ (BSD2, "BSD2"),+          (BSD3, "BSD3"),+          (BSD4, "BSD4"),+          (MIT, "MIT"),+          (ISC, "ISC"),+          (PublicDomain, "PublicDomain"),+          (AllRightsReserved, "AllRightsReserved"),+          (UnspecifiedLicense, "UnspecifiedLicense"),+          (OtherLicense, "OtherLicense")+        ]++instance HasCodec SPDX.License where+  codec =+    named "SPDX.License" $+      object "spdx-license" $+        dimapCodec f g $+          eitherCodec (pure NONE) $+            requiredField' "license-expression"+    where+      f = \case+        Left _ -> NONE+        Right e -> License e+      g = \case+        NONE -> Left ("None" :: String)+        License e -> Right e++instance HasCodec SPDX.LicenseExpression where+  codec =+    named "LicenseExpression" $+      dimapCodec f g $+        eitherCodec (object "ELicense" $ (,) <$> requiredField' "expression" .= fst <*> requiredField' "exception-id" .= snd) $+          eitherCodec (object "EAnd" $ (,) <$> requiredField' "expression-1" .= fst <*> requiredField' "expression-2" .= snd) $+            object "EOr" $ (,) <$> requiredField' "expression-11" .= fst <*> requiredField' "expression-22" .= snd+    where+      f = \case+        Left (e, c) -> ELicense e c+        Right (Left (exp1, exp2)) -> EAnd exp1 exp2+        Right (Right (exp1, exp2)) -> EOr exp1 exp2+      g = \case+        ELicense e c -> Left (e, c)+        EAnd exp1 exp2 -> Right $ Left (exp1, exp2)+        EOr exp1 exp2 -> Right $ Right (exp1, exp2)++instance HasCodec SPDX.SimpleLicenseExpression where+  codec =+    object "SimpleLicenseExpression" $+      dimapCodec f g $+        eitherCodec (requiredField' "id") $+          eitherCodec (requiredField' "id-plus") $+            requiredField' "license-ref"+    where+      f = \case+        Left i -> ELicenseId i+        Right (Left i) -> ELicenseIdPlus i+        Right (Right ref) -> ELicenseRef ref+      g = \case+        ELicenseId i -> Left i+        ELicenseIdPlus i -> Right $ Left i+        ELicenseRef ref -> Right $ Right ref++instance HasCodec SPDX.LicenseId where+  codec = named "SPDX.LicenseId" shownBoundedEnumCodec++instance HasCodec SPDX.LicenseRef where+  codec = dimapCodec f g codec+    where+      f = uncurry SPDX.mkLicenseRef'+      g = \l -> (SPDX.licenseDocumentRef l, SPDX.licenseRef l)++instance HasCodec SPDX.LicenseExceptionId where+  codec = shownBoundedEnumCodec++instance HasCodec BuildType where+  codec = stringConstCodec [(Simple, "Simple"), (Configure, "Configure"), (Make, "Make"), (Custom, "Custom")]++instance HasCodec SetupBuildInfo where+  codec =+    object "SetupBuildInfo" $+      SetupBuildInfo+        <$> requiredField' "setup-depends" .= setupDepends+        -- TODO: not needed+        <*> requiredField' "__defaultSetupDepends" .= defaultSetupDepends++instance HasCodec Flag where+  codec =+    object "Flag" $+      MkFlag+        <$> requiredField' "name" .= flagName+        <*> requiredField' "description" .= flagDescription+        <*> requiredField' "default" .= flagDefault+        <*> requiredField' "manual" .= flagManual++instance HasCodec FlagName where+  codec = dimapCodec mkFlagName unFlagName codec++instance HasCodec a => HasCodec (CondTree ConfVar [Dependency] a) where+  codec =+    named "ConditionalTree" $+      object "CondTree" $+        CondNode+          <$> requiredField' "condTreeData" .= condTreeData+          <*> requiredField' "condTreeConstraints" .= condTreeConstraints+          <*> requiredField' "condTreeComponents" .= condTreeComponents++instance (HasCodec a) => HasCodec (CondBranch ConfVar [Dependency] a) where+  codec =+    object "CondBranch" $+      CondBranch+        <$> requiredField' "condBranchCondition" .= condBranchCondition+        <*> requiredField' "condBranchIfTrue" .= condBranchIfTrue+        <*> optionalField' "condBranchIfFalse" .= condBranchIfFalse++instance HasCodec (Condition ConfVar) where+  codec =+    named "Condition" $+      dimapCodec f g $+        eitherCodec (object "var" $ requiredField' "v") $+          eitherCodec (object "lit" $ requiredField' "bool") $+            eitherCodec (object "cnot" $ requiredField' "cond") $+              eitherCodec (object "cor" $ (,) <$> requiredField' "cond1" .= fst <*> requiredField' "cond2" .= snd) $+                object "cand" $ (,) <$> requiredField' "cond12" .= fst <*> requiredField' "cond22" .= snd+    where+      f = \case+        Left c -> Var c+        Right (Left b) -> Lit b+        Right (Right (Left cond)) -> CNot cond+        Right (Right (Right (Left (cond1, cond2)))) -> COr cond1 cond2+        Right (Right (Right (Right (cond1, cond2)))) -> CAnd cond1 cond2+      g = \case+        Var c -> Left c+        Lit b -> Right $ Left b+        CNot cond -> Right $ Right $ Left cond+        COr cond1 cond2 -> Right $ Right $ Right $ Left (cond1, cond2)+        CAnd cond1 cond2 -> Right $ Right $ Right $ Right (cond1, cond2)++instance HasCodec ConfVar where+  codec =+    object "ConfVar" $+      dimapCodec f g $+        eitherCodec (requiredField' "os") $+          eitherCodec (requiredField' "arch") $+            eitherCodec (requiredField' "flag") $+              (,) <$> requiredField' "compiler" .= fst <*> requiredField' "version" .= snd+    where+      f = \case+        Left o -> OS o+        Right (Left a) -> Arch a+        Right (Right (Left name)) -> Flag name+        Right (Right (Right (compiler, version))) -> Impl compiler version+      g = \case+        OS o -> Left o+        Arch a -> Right $ Left a+        Flag name -> Right $ Right $ Left name+        Impl compiler version -> Right $ Right $ Right (compiler, version)++instance HasCodec Arch where+  -- TODO add OtherArch+  codec =+    stringConstCodec+      [ (I386, "I386"),+        (X86_64, "X86_64"),+        (PPC, "PPC"),+        (PPC64, "PPC64"),+        (Sparc, "Sparc"),+        (Arm, "Arm"),+        (AArch64, "AArch64"),+        (Mips, "Mips"),+        (SH, "SH"),+        (IA64, "IA64"),+        (S390, "S390"),+        (Alpha, "Alpha"),+        (Hppa, "Hppa"),+        (Rs6000, "Rs6000"),+        (M68k, "M68k"),+        (Vax, "Vax"),+        (JavaScript, "JavaScript")+      ]++instance HasCodec OS where+  -- TODO add OtherOS+  codec =+    stringConstCodec+      [ (Linux, "Linux"),+        (Windows, "Windows"),+        (OSX, "OSX"),+        (FreeBSD, "FreeBSD"),+        (OpenBSD, "OpenBSD"),+        (NetBSD, "NetBSD"),+        (DragonFly, "DragonFly"),+        (Solaris, "Solaris"),+        (AIX, "AIX"),+        (HPUX, "HPUX"),+        (IRIX, "IRIX"),+        (HaLVM, "HaLVM"),+        (Hurd, "Hurd"),+        (IOS, "IOS"),+        (Android, "Android"),+        (Ghcjs, "Ghcjs")+      ]++instance HasCodec Library where+  codec =+    object "Library" $+      Library+        <$> requiredField' "name" .= libName+        <*> requiredField' "exposed-modules" .= exposedModules+        <*> requiredField' "re-exported-modules" .= reexportedModules+        <*> requiredField' "signatures" .= signatures+        <*> requiredField' "exposed" .= libExposed+        <*> requiredField' "visibility" .= libVisibility+        <*> requiredField' "build-info" .= libBuildInfo++instance HasCodec LibraryName where+  codec =+    object "LibraryName" $+      dimapCodec f g $+        eitherCodec (pure LMainLibName) $+          requiredField' "sub-lib-name"+    where+      f = \case+        Left _ -> LMainLibName+        Right s -> LSubLibName s+      g = \case+        LMainLibName -> Left ()+        LSubLibName s -> Right s++instance HasCodec ModuleName where+  codec = dimapCodec fromComponents components codec++instance HasCodec ModuleReexport where+  codec =+    object "ModuleReexport" $+      ModuleReexport+        <$> requiredField' "moduleReexportOriginalPackage" .= moduleReexportOriginalPackage+        <*> requiredField' "moduleReexportOriginalName" .= moduleReexportOriginalName+        <*> requiredField' "moduleReexportName" .= moduleReexportName++instance HasCodec LibraryVisibility where+  codec = stringConstCodec [(LibraryVisibilityPublic, "LibraryVisibilityPublic"), (LibraryVisibilityPrivate, "LibraryVisibilityPrivate")]++instance HasCodec ForeignLib where+  codec =+    object "ForeignLib" $+      ForeignLib+        <$> requiredField' "name" .= foreignLibName+        <*> requiredField' "type" .= foreignLibType+        <*> requiredField' "options" .= foreignLibOptions+        <*> requiredField' "build-info" .= foreignLibBuildInfo+        <*> requiredField' "version-info" .= foreignLibVersionInfo+        <*> requiredField' "linux-version" .= foreignLibVersionLinux+        <*> requiredField' "mod-def-files" .= foreignLibModDefFile++instance HasCodec ForeignLibType where+  codec = stringConstCodec [(ForeignLibNativeShared, "ForeignLibNativeShared"), (ForeignLibNativeStatic, "ForeignLibNativeStatic"), (ForeignLibTypeUnknown, "ForeignLibTypeUnknown")]++instance HasCodec ForeignLibOption where+  codec = literalTextValueCodec ForeignLibStandalone "ForeignLibStandalone"++instance HasCodec LibVersionInfo where+  codec = dimapCodec mkLibVersionInfo libVersionInfoCRA codec++instance HasCodec Version where+  codec = dimapCodec mkVersion versionNumbers codec++instance HasCodec Executable where+  codec =+    object "Executable" $+      Executable+        <$> requiredField' "name" .= exeName+        <*> requiredField' "module-path" .= modulePath+        <*> requiredField' "scope" .= exeScope+        <*> requiredField' "build-info" .= buildInfo++instance HasCodec ExecutableScope where+  codec =+    stringConstCodec $+      NE.fromList+        [ (ExecutablePublic, "public"),+          (ExecutablePrivate, "private")+        ]++instance HasCodec TestSuite where+  codec =+    object "TestSuite" $+      TestSuite+        <$> requiredField' "name" .= testName+        <*> requiredField' "interface" .= testInterface+        <*> requiredField' "build-info" .= testBuildInfo++instance HasCodec TestSuiteInterface where+  codec =+    object "TestSuiteInterface" $+      dimapCodec f g $+        eitherCodec ((,) <$> requiredField' "version" .= fst <*> requiredField' "filepath" .= snd) $+          eitherCodec ((,) <$> requiredField' "version" .= fst <*> requiredField' "module-name" .= snd) $+            requiredField' "type"+    where+      f = \case+        Left (v, fp) -> TestSuiteExeV10 v fp+        Right (Left (v, mn)) -> TestSuiteLibV09 v mn+        Right (Right tt) -> TestSuiteUnsupported tt+      g = \case+        TestSuiteExeV10 v fp -> Left (v, fp)+        TestSuiteLibV09 v mn -> Right $ Left (v, mn)+        TestSuiteUnsupported tt -> Right $ Right tt++instance HasCodec TestType where+  codec =+    object "TestType" $+      dimapCodec f g $+        eitherCodec (requiredField' "version") $+          eitherCodec (requiredField' "version") $+            (,) <$> requiredField' "name" .= fst <*> requiredField' "version" .= snd+    where+      f = \case+        Left v -> TestTypeExe v+        Right (Left v) -> TestTypeLib v+        Right (Right (s, v)) -> TestTypeUnknown s v+      g = \case+        TestTypeExe v -> Left v+        TestTypeLib v -> Right $ Left v+        TestTypeUnknown s v -> Right $ Right (s, v)++instance HasCodec Benchmark where+  codec =+    object "Benchmark" $+      Benchmark+        <$> requiredField' "name" .= benchmarkName+        <*> requiredField' "interface" .= benchmarkInterface+        <*> requiredField' "build-info" .= benchmarkBuildInfo++instance HasCodec BenchmarkType where+  codec =+    object "BenchmarkType" $+      dimapCodec f g $+        eitherCodec (requiredField' "benchmark-type") $+          (,)+            <$> requiredField' "type" .= fst+            <*> requiredField' "version" .= snd+    where+      f = \case+        Left v -> BenchmarkTypeExe v+        Right (s, v) -> BenchmarkTypeUnknown s v+      g = \case+        BenchmarkTypeExe v -> Left v+        BenchmarkTypeUnknown s v -> Right (s, v)++instance HasCodec BenchmarkInterface where+  codec =+    dimapCodec f g $+      eitherCodec+        ( object "BenchmarkExeV10" $+            (,)+              <$> requiredField' "version" .= fst+              <*> requiredField' "filepath" .= snd+        )+        $ object "BenchmarkUnsupported" $ requiredField' "benchmark-type"+    where+      f = \case+        Left (version, file) -> BenchmarkExeV10 version file+        Right t -> BenchmarkUnsupported t+      g = \case+        BenchmarkExeV10 version file -> Left (version, file)+        BenchmarkUnsupported t -> Right t++instance HasCodec ModuleRenaming where+  codec =+    object "ModuleRenaming" $+      dimapCodec f g $+        eitherCodec (pure DefaultRenaming) $+          eitherCodec (requiredField' "name") (requiredField' "name")+    where+      f = \case+        Left _ -> DefaultRenaming+        Right (Left m) -> ModuleRenaming m+        Right (Right m) -> HidingRenaming m+      g = \case+        DefaultRenaming -> Left ()+        ModuleRenaming m -> Right $ Left m+        HidingRenaming m -> Right $ Right m++instance HasCodec IncludeRenaming where+  codec =+    object "IncludeRenaming" $+      IncludeRenaming+        <$> requiredField' "includeProvidesRn" .= includeProvidesRn+        <*> requiredField' "includeRequiresRn" .= includeRequiresRn++instance HasCodec Mixin where+  codec =+    object "Mixin" $+      Mixin+        <$> requiredField' "package-name" .= mixinPackageName+        <*> requiredField' "include-renaming" .= mixinIncludeRenaming++instance HasCodec LegacyExeDependency where+  codec =+    object "LegacyExeDependency" $+      LegacyExeDependency+        <$> requiredField' "package-name" .= (\(LegacyExeDependency s _) -> s)+        <*> requiredField' "include-renaming" .= (\(LegacyExeDependency _ vr) -> vr)++instance HasCodec ExeDependency where+  codec =+    object "ExeDependency" $+      ExeDependency+        <$> requiredField' "package-name" .= (\(ExeDependency a _ _) -> a)+        <*> requiredField' "executable-component-name" .= (\(ExeDependency _ b _) -> b)+        <*> requiredField' "version-range" .= (\(ExeDependency _ _ c) -> c)++instance HasCodec PkgconfigDependency where+  codec =+    object "PkgconfigDependency" $+      PkgconfigDependency+        <$> requiredField' "pkgconfigName" .= (\(PkgconfigDependency name _) -> name)+        <*> requiredField' "pkgconfigVersionRange" .= (\(PkgconfigDependency _ version) -> version)++instance HasCodec PkgconfigName where+  codec = dimapCodec mkPkgconfigName unPkgconfigName codec++instance HasCodec PkgconfigVersionRange where+  codec = bimapCodec f g codec+    where+      f = \s -> case eitherParsec s of+        Left pe -> Left $ show pe+        Right a -> Right a+      g = prettyShow++instance HasCodec PkgconfigVersion where+  codec =+    bimapCodec+      (Right . PkgconfigVersion . encodeUtf8)+      ( \(PkgconfigVersion v) -> case decodeUtf8' v of+          Left ex -> T.pack $ show ex+          Right txt -> txt+      )+      codec++instance HasCodec Language where+  codec =+    dimapCodec f g $+      eitherCodec (literalTextValueCodec Haskell98 "Haskell98") $+        eitherCodec+          (literalTextValueCodec Haskell2010 "Haskell2010")+          codec+    where+      f = \case+        Left l -> l+        Right (Left l) -> l+        Right (Right s) -> UnknownLanguage s+      g = \case+        Haskell98 -> Left Haskell98+        Haskell2010 -> Right $ Left Haskell2010+        UnknownLanguage s -> Right $ Right s++instance HasCodec Extension where+  codec =+    named "Extension" $+      object "Extension" $+        dimapCodec f g $+          eitherCodec (requiredField' "enable-extension") $+            eitherCodec+              (requiredField' "disable-extension")+              (requiredField' "unknown-extension")+    where+      f = \case+        Left e -> EnableExtension e+        Right (Left e) -> DisableExtension e+        Right (Right s) -> UnknownExtension s+      g = \case+        EnableExtension e -> Left e+        DisableExtension e -> Right $ Left e+        UnknownExtension e -> Right $ Right e++instance HasCodec KnownExtension where+  codec = named "KnownExtension" shownBoundedEnumCodec++instance HasCodec BuildInfo where+  codec =+    object "BuildInfo" $+      BuildInfo+        <$> requiredField' "buildable" .= buildable+        <*> requiredField' "buildTools" .= buildTools+        <*> requiredField' "buildToolDepends" .= buildToolDepends+        <*> requiredField' "cppOptions" .= cppOptions+        <*> requiredField' "asmOptions" .= asmOptions+        <*> requiredField' "cmmOptions" .= cmmOptions+        <*> requiredField' "ccOptions" .= ccOptions+        <*> requiredField' "cxxOptions" .= cxxOptions+        <*> requiredField' "ldOptions" .= ldOptions+        <*> requiredField' "pkgconfigDepends" .= pkgconfigDepends+        <*> requiredField' "frameworks" .= frameworks+        <*> requiredField' "extraFrameworkDirs" .= extraFrameworkDirs+        <*> requiredField' "asmSources" .= asmSources+        <*> requiredField' "cmmSources" .= cmmSources+        <*> requiredField' "cSources" .= cSources+        <*> requiredField' "cxxSources" .= cxxSources+        <*> requiredField' "jsSources" .= jsSources+        <*> requiredField' "hsSourceDirs" .= hsSourceDirs+        <*> requiredField' "otherModules" .= otherModules+        <*> requiredField' "virtualModules" .= virtualModules+        <*> requiredField' "autogenModules" .= autogenModules+        <*> requiredField' "defaultLanguage" .= defaultLanguage+        <*> requiredField' "otherLanguages" .= otherLanguages+        <*> requiredField' "defaultExtensions" .= defaultExtensions+        <*> requiredField' "otherExtensions" .= otherExtensions+        <*> requiredField' "oldExtensions" .= oldExtensions+        <*> requiredField' "extraLibs" .= extraLibs+        <*> requiredField' "extraGHCiLibs" .= extraGHCiLibs+        <*> requiredField' "extraBundledLibs" .= extraBundledLibs+        <*> requiredField' "extraLibFlavours" .= extraLibFlavours+        <*> requiredField' "extraDynLibFlavours" .= extraDynLibFlavours+        <*> requiredField' "extraLibDirs" .= extraLibDirs+        <*> requiredField' "includeDirs" .= includeDirs+        <*> requiredField' "includes" .= includes+        <*> requiredField' "autogenIncludes" .= autogenIncludes+        <*> requiredField' "installIncludes" .= installIncludes+        <*> requiredField' "options" .= options+        <*> requiredField' "profOptions" .= profOptions+        <*> requiredField' "sharedOptions" .= sharedOptions+        <*> requiredField' "staticOptions" .= staticOptions+        <*> requiredField' "customFieldsBI" .= customFieldsBI+        <*> requiredField' "targetBuildDepends" .= targetBuildDepends+        <*> requiredField' "mixins" .= mixins
+ test/Cabal2JSONSpec.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++module Cabal2JSONSpec (spec) where++import Autodocodec+import Autodocodec.Yaml+import Cabal2JSON ()+import qualified Distribution.Make as Cabal+import Distribution.ModuleName as Cabal+import Distribution.PackageDescription.Parsec as Cabal+import qualified Distribution.SPDX as SPDX+import Distribution.Types.Benchmark as Cabal+import Distribution.Types.BenchmarkInterface as Cabal+import Distribution.Types.BenchmarkType as Cabal+import Distribution.Types.BuildInfo as Cabal+import Distribution.Types.BuildType as Cabal+import Distribution.Types.Executable as Cabal+import Distribution.Types.ExecutableScope as Cabal+import Distribution.Types.Flag as Cabal+import Distribution.Types.ForeignLib as Cabal+import Distribution.Types.ForeignLibOption as Cabal+import Distribution.Types.ForeignLibType as Cabal+import Distribution.Types.GenericPackageDescription as Cabal+import Distribution.Types.Library as Cabal+import Distribution.Types.LibraryName as Cabal+import Distribution.Types.LibraryVisibility as Cabal+import Distribution.Types.ModuleReexport as Cabal+import Distribution.Types.PackageDescription as Cabal+import Distribution.Types.PkgconfigVersion as Cabal+import Distribution.Types.PkgconfigVersionRange as Cabal+import Distribution.Types.SourceRepo as Cabal+import Distribution.Types.TestSuite as Cabal+import Distribution.Types.TestSuiteInterface as Cabal+import Distribution.Types.UnqualComponentName as Cabal+import Distribution.Types.VersionRange as Cabal+import Distribution.Utils.ShortText as Cabal+import Distribution.Verbosity as Cabal+import Language.Haskell.Extension as Cabal+import Test.Syd+import Test.Syd.Aeson++spec :: Spec+spec = do+  it "outputs the same json for the cabal2json cabal file" $+    goldenJSONValueFile+      "test_resources/json/cabal2json.cabal.json"+      (Cabal.readGenericPackageDescription Cabal.silent "cabal2json.cabal")++  schemaSpec @Cabal.GenericPackageDescription "generic-package-description"+  schemaSpec @Cabal.PackageDescription "package-description"+  schemaSpec @Cabal.PackageIdentifier "package-identified"+  schemaSpec @Cabal.BenchmarkType "benchmark-type"+  schemaSpec @Cabal.BenchmarkInterface "benchmark-interface"+  schemaSpec @Cabal.Benchmark "benchmark"+  schemaSpec @Cabal.BuildInfo "build-info"+  schemaSpec @Cabal.BuildType "build-type"+  schemaSpec @Cabal.Executable "executable"+  schemaSpec @Cabal.ExecutableScope "executable-scope"+  schemaSpec @Cabal.Extension "extension"+  schemaSpec @Cabal.Flag "flag"+  schemaSpec @Cabal.FlagName "flag-name"+  schemaSpec @Cabal.ForeignLibType "foreign-lib-type"+  schemaSpec @Cabal.ForeignLibOption "foreign-lib-option"+  schemaSpec @Cabal.ForeignLib "foreign-lib"+  schemaSpec @Cabal.KnownExtension "KnownExtension"+  schemaSpec @Cabal.Language "language"+  schemaSpec @Cabal.Library "library"+  schemaSpec @Cabal.LibraryName "library-name"+  schemaSpec @Cabal.LibraryVisibility "library-visibility"+  schemaSpec @Cabal.License "license"+  schemaSpec @Cabal.ModuleName "module-name"+  schemaSpec @Cabal.ModuleReexport "module-reexport"+  schemaSpec @Cabal.PackageIdentifier "package-identifier"+  schemaSpec @Cabal.PkgconfigVersion "pkgconfig-version"+  schemaSpec @Cabal.PkgconfigVersionRange "pkgconfig-version-range"+  schemaSpec @Cabal.ShortText "short-text"+  schemaSpec @Cabal.SourceRepo "source-repo"+  schemaSpec @Cabal.TestSuiteInterface "test-suite-interface"+  schemaSpec @Cabal.TestSuite "test-suite"+  schemaSpec @Cabal.UnqualComponentName "unqual-component-name"+  schemaSpec @Cabal.Version "version"+  schemaSpec @Cabal.VersionRange "version-range"+  schemaSpec @SPDX.License "spdx-license"+  schemaSpec @SPDX.LicenseExpression "spdx-license-expression"+  schemaSpec @SPDX.SimpleLicenseExpression "spdx-simple-license-expression"+  schemaSpec @SPDX.LicenseExceptionId "spdx-license-exception-id"+  schemaSpec @SPDX.LicenseRef "spdx-license-ref"+  schemaSpec @SPDX.LicenseId "spdx-license-id"++schemaSpec :: forall a. HasCodec a => String -> Spec+schemaSpec name =+  it ("outputs the same yaml file for " <> name) $+    pureGoldenByteStringFile+      ("test_resources/schemas/" <> name <> ".txt")+      (renderColouredSchemaViaCodec @a)
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF sydtest-discover #-}