packages feed

argon 0.4.1.0 → 0.4.2.0

raw patch · 13 files changed

+267/−166 lines, 13 filesdep +dirstreamdep +ghc-bootdep +system-filepathdep −pipes-filesdep ~Cabaldep ~aesondep ~ansi-terminal

Dependencies added: dirstream, ghc-boot, system-filepath

Dependencies removed: pipes-files

Dependency ranges changed: Cabal, aeson, ansi-terminal, base, bytestring, containers, directory, filepath, ghc, ghc-paths, ghc-syb-utils, hlint, hspec, lens-simple, pipes, pipes-bytestring, pipes-group, pipes-safe, syb

Files

README.md view
@@ -42,8 +42,52 @@  #### GHC compatibility -Argon is compatible with GHC 7.8 and 7.10, it's tested against those versions-only.+Argon is compatible with GHC version 8.0.2 and above. In the+[releases](https://github.com/rubik/argon/releases) page you can find binaries+for older versions of `argon` which support GHC versions 7.8 and 7.10.++### About the complexity being measured++`argon` will compute the [cyclomatic+complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) of Haskell+functions, which is the number of decisions in a block of code plus 1. For+instance the following function:++```haskell+func n = case n of+           2 -> 3+           4 -> 6+           _ -> 42+```++has a cyclomatic complexity of 3.++The boolean operators `&&` and `||` also affect the this number. For instance+the following function:++```haskell+g n = n < 68 && n `mod` 3 == 2 && n > 49+```+has a cyclomatic complexity of 3.++As a last example, the following function:++```haskell+func n = case n of+           2 -> 3+           4 -> 6+           _ -> if 0 < n+                then 7+                else 8+```++has a cyclomatic complexity of 5.++Cyclomatic complexity provides a very shallow metric of code complexity: a high+cyclomatic complexity number does not necessarily mean that the function is+complex, and conversely, a low number does not necessarily indicate that the+function is simple. However, this number it can be useful for highlighting+potential maintainability issues.  ### Running 
argon.cabal view
@@ -1,5 +1,5 @@ name:                argon-version:             0.4.1.0+version:             0.4.2.0 synopsis:            Measure your code's complexity homepage:            http://github.com/rubik/argon bug-reports:         http://github.com/rubik/argon/issues@@ -10,7 +10,7 @@ copyright:           2015 Michele Lacchia category:            Development, Static Analysis build-type:          Simple-cabal-version:       >=1.18+cabal-version:       1.18 description:     Argon performs static analysis on your code in order to compute cyclomatic     complexity. It is a quantitative measure of the number of linearly@@ -21,7 +21,6 @@     JSON. extra-source-files:     stack.yaml-    stack-7.8.yaml     README.md     CHANGELOG.md     USAGE.txt@@ -33,7 +32,7 @@     test/tree/*.txt     test/tree/sub/*.hs     test/tree/sub2/*.hs-tested-with: GHC >= 7.8 && < 8+tested-with: GHC >= 8.0.2 && < 9  library   hs-source-dirs:      src@@ -49,24 +48,31 @@                        Argon.SYB.Utils                        Argon.Walker   build-depends:       base             >=4.7    && <5-                     , ansi-terminal    >=0.6-                     , aeson            >=0.8-                     , bytestring       >=0.10-                     , pipes            >=4.1-                     , pipes-group      >=1.0-                     , pipes-files      >=0.1-                     , pipes-safe       >=2.2-                     , pipes-bytestring >=2.1-                     , lens-simple      >=0.1-                     , ghc              >=7.8    && <8-                     , ghc-paths        >=0.1-                     , ghc-syb-utils    >=0.2-                     , syb              >=0.4-                     , Cabal            >=1.18-                     , containers       >=0.5-                     , directory        >=1.2+                     , ansi-terminal+                     , aeson+                     , bytestring+                     , pipes+                     , pipes-group+                     , pipes-safe+                     , pipes-bytestring+                     , lens-simple+                     , ghc+                     , ghc-boot+                     , ghc-paths+                     , ghc-syb-utils+                     , syb+                     , Cabal+                     , containers+                     , directory+                     , system-filepath+                     , dirstream+                     , filepath   default-language:    Haskell2010   ghc-options:         -Wall+                       -Wcompat+                       -Wincomplete-record-updates+                       -Wincomplete-uni-patterns+                       -Wredundant-constraints   if impl(ghc < 7.8)     buildable: False @@ -89,16 +95,18 @@   main-is:             Spec.hs   other-modules:       ArgonSpec   build-depends:       base             >=4.7    && <5-                     , argon            -any-                     , ansi-terminal    >=0.6-                     , ghc              >=7.8    && <8-                     , aeson            >=0.8-                     , hspec            >=2.1-                     , QuickCheck       -any-                     , filepath         >=1.3-                     , pipes            >=4.1-                     , pipes-safe       >=2.2-  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N+                     , argon+                     , ansi-terminal+                     , ghc+                     , aeson+                     , hspec+                     , QuickCheck+                     , filepath+                     , pipes+                     , pipes-safe+  ghc-options:         -Wall+                       -threaded -rtsopts -with-rtsopts=-N+   default-language:    Haskell2010   if impl(ghc < 7.8)     buildable: False@@ -107,8 +115,8 @@   type:                exitcode-stdio-1.0   hs-source-dirs:      test   main-is:             HLint.hs-  build-depends:       base  ==4.*-                     , hlint ==1.*+  build-depends:       base             >=4.7   &&  <5+                     , hlint   default-language:    Haskell2010   ghc-options:         -Wall 
src/Argon.hs view
@@ -23,7 +23,6 @@     , analyze     , parseModule     , parseExts-    , flagsMap     -- * Manipulating results     , order     , filterResults@@ -40,7 +39,7 @@  import Argon.Parser (LModule, analyze, parseModule) import Argon.Results (order, filterResults, filterNulls, exportStream)-import Argon.Cabal (flagsMap, parseExts)+import Argon.Cabal (parseExts) import Argon.Types import Argon.Loc import Argon.Walker (allFiles)
src/Argon/Cabal.hs view
@@ -1,46 +1,34 @@ {-# LANGUAGE CPP #-}-module Argon.Cabal (flagsMap, parseExts)+module Argon.Cabal (parseExts)     where -import Data.Maybe (mapMaybe)-import Data.Map.Strict (Map)-import qualified Data.Map.Strict as M+import           Data.List                             (nub) #if __GLASGOW_HASKELL__ < 710-import Control.Applicative ((<$>))-#else-import Control.Arrow ((&&&))+import           Control.Applicative                   ((<$>)) #endif -import qualified DynFlags as GHC-import qualified Language.Haskell.Extension            as Dist-import qualified Distribution.Verbosity                as Dist import qualified Distribution.PackageDescription       as Dist import qualified Distribution.PackageDescription.Parse as Dist+import qualified Distribution.Verbosity                as Dist+import qualified Language.Haskell.Extension            as Dist  --- | A 'Map' from extensions names to extensions flags-flagsMap :: Map String GHC.ExtensionFlag-flagsMap = M.fromList $ map specToPair GHC.xFlags- -- | Parse the given Cabal file generate a list of GHC extension flags. The --   extension names are read from the default-extensions field in the library --   section.-parseExts :: FilePath -> IO [GHC.ExtensionFlag]+parseExts :: FilePath -> IO [String]+#if __GLASGOW_HASKELL__ < 802 parseExts path = extract <$> Dist.readPackageDescription Dist.silent path+#else+parseExts path = extract <$> Dist.readGenericPackageDescription Dist.silent path+#endif     where extract pkg = maybe [] extFromBI $-            (Dist.libBuildInfo . Dist.condTreeData) <$> Dist.condLibrary pkg+            Dist.libBuildInfo . Dist.condTreeData <$> Dist.condLibrary pkg -extFromBI :: Dist.BuildInfo -> [GHC.ExtensionFlag]-extFromBI = mapMaybe (get . toString) . Dist.defaultExtensions-    where get = flip M.lookup flagsMap-          toString (Dist.UnknownExtension ext) = ext+extFromBI :: Dist.BuildInfo -> [String]+extFromBI binfo = map toString . nub $ allExts+    where toString (Dist.UnknownExtension ext) = ext           toString (Dist.EnableExtension  ext) = show ext           toString (Dist.DisableExtension ext) = show ext--#if __GLASGOW_HASKELL__ < 710-specToPair :: (String, GHC.ExtensionFlag, a) -> (String, GHC.ExtensionFlag)-specToPair (a, b, _) = (a, b)-#else-specToPair :: GHC.FlagSpec GHC.ExtensionFlag -> (String, GHC.ExtensionFlag)-specToPair = GHC.flagSpecName &&& GHC.flagSpecFlag-#endif+          allExts = concatMap ($ binfo)+              [Dist.defaultExtensions, Dist.otherExtensions, Dist.oldExtensions]
src/Argon/Parser.hs view
@@ -2,7 +2,6 @@ module Argon.Parser (LModule, analyze, parseModule)     where -import Data.List (foldl') import Control.Monad (void) import qualified Control.Exception as E @@ -11,6 +10,7 @@ import qualified Lexer        as GHC import qualified Parser       as GHC import qualified DynFlags     as GHC+import qualified GHC.LanguageExtensions as GHC import qualified HeaderInfo   as GHC import qualified MonadUtils   as GHC import qualified Outputable   as GHC@@ -61,7 +61,7 @@ parseModuleWithCpp conf cppOptions file =     GHC.runGhc (Just libdir) $ do       dflags <- initDynFlags conf file-      let useCpp = GHC.xopt GHC.Opt_Cpp dflags+      let useCpp = GHC.xopt GHC.Cpp dflags       (fileContents, dflags1) <-         if useCpp            then getPreprocessedSrcDirect cppOptions file@@ -86,15 +86,16 @@ initDynFlags :: GHC.GhcMonad m => Config -> FilePath -> m GHC.DynFlags initDynFlags conf file = do     dflags0 <- GHC.getSessionDynFlags-    src_opts <- GHC.liftIO $ GHC.getOptionsFromFile dflags0 file-    (dflags1, _, _) <- GHC.parseDynamicFilePragma dflags0 src_opts-    let cabalized = foldl' GHC.xopt_set dflags1 $ exts conf-    let dflags2 = cabalized { GHC.log_action = customLogAction }-    void $ GHC.setSessionDynFlags dflags2-    return dflags2+    (dflags1,_,_) <- GHC.parseDynamicFlagsCmdLine dflags0+        [GHC.L GHC.noSrcSpan ("-X" ++ e) | e <- exts conf]+    src_opts <- GHC.liftIO $ GHC.getOptionsFromFile dflags1 file+    (dflags2, _, _) <- GHC.parseDynamicFilePragma dflags1 src_opts+    let dflags3 = dflags2 { GHC.log_action = customLogAction }+    void $ GHC.setSessionDynFlags dflags3+    return dflags3  customLogAction :: GHC.LogAction-customLogAction dflags severity srcSpan _ m =+customLogAction dflags _ severity srcSpan _ m =     case severity of       GHC.SevFatal -> throwError       GHC.SevError -> throwError
src/Argon/Types.hs view
@@ -15,7 +15,6 @@ import Data.Typeable import Control.Exception (Exception) -import qualified DynFlags as GHC import Argon.Loc  @@ -38,8 +37,8 @@ data Config = Config {     -- | Minimum complexity a block has to have to be shown in results.     minCC       :: Int-    -- | Path to the main Cabal file-  , exts        :: [GHC.ExtensionFlag]+    -- | Extension to activate+  , exts        :: [String]     -- | Header files to be automatically included before preprocessing   , headers     :: [FilePath]     -- | Additional include directories for the C preprocessor
src/Argon/Visitor.hs view
@@ -1,16 +1,17 @@+{-# LANGUAGE CPP #-} module Argon.Visitor (funcsCC)     where -import Data.Generics (Data, Typeable, mkQ)-import Argon.SYB.Utils (Stage(..), everythingStaged)-import Control.Arrow ((&&&))+import           Argon.SYB.Utils (Stage (..), everythingStaged)+import           Control.Arrow   ((&&&))+import           Data.Generics   (Data, mkQ)  import qualified GHC-import qualified RdrName as GHC-import qualified OccName as GHC+import qualified OccName         as GHC+import qualified RdrName         as GHC -import Argon.Loc-import Argon.Types (ComplexityBlock(..))+import           Argon.Loc+import           Argon.Types     (ComplexityBlock (..))  type Exp = GHC.HsExpr GHC.RdrName type Function = GHC.HsBindLR GHC.RdrName GHC.RdrName@@ -18,16 +19,16 @@   -- | Compute cyclomatic complexity of every function binding in the given AST.-funcsCC :: (Data from, Typeable from) => from -> [ComplexityBlock]+funcsCC :: (Data from) => from -> [ComplexityBlock] funcsCC = map funCC . getBinds  funCC :: Function -> ComplexityBlock funCC f = CC (getLocation $ GHC.fun_id f, getFuncName f, complexity f) -getBinds :: (Data from, Typeable from) => from -> [Function]+getBinds :: (Data from) => from -> [Function] getBinds = everythingStaged Parser (++) [] $ mkQ [] visit     where visit fun@GHC.FunBind {} = [fun]-          visit _ = []+          visit _                  = []  getLocation :: GHC.Located a -> Loc getLocation = srcSpanToLoc . GHC.getLoc@@ -39,11 +40,17 @@ complexity f = let matches = getMatches f                    query = everythingStaged Parser (+) 0 $ 0 `mkQ` visit                    visit = uncurry (+) . (visitExp &&& visitOp)-                in length matches + sumWith query matches+                in length matches + sumWith getGRHSsFromMatch matches + sumWith query matches  getMatches :: Function -> [GHC.LMatch GHC.RdrName MatchBody]-getMatches = GHC.mg_alts . GHC.fun_matches+getMatches = GHC.unLoc . GHC.mg_alts . GHC.fun_matches +getGRHSsFromMatch :: GHC.LMatch GHC.RdrName MatchBody -> Int+getGRHSsFromMatch match = length (getGRHSs' match) - 1+  where+    getGRHSs' :: GHC.LMatch GHC.RdrName MatchBody -> [GHC.LGRHS GHC.RdrName MatchBody]+    getGRHSs' = GHC.grhssGRHSs . GHC.m_grhss . GHC.unLoc+ getName :: GHC.RdrName -> String getName = GHC.occNameString . GHC.rdrNameOcc @@ -51,15 +58,20 @@ sumWith f = sum . map f  visitExp :: Exp -> Int-visitExp GHC.HsIf {} = 1+visitExp GHC.HsIf {}            = 1 visitExp (GHC.HsMultiIf _ alts) = length alts - 1-visitExp (GHC.HsLamCase _ alts) = length (GHC.mg_alts alts) - 1-visitExp (GHC.HsCase _ alts)    = length (GHC.mg_alts alts) - 1-visitExp _ = 0+#if __GLASGOW_HASKELL__ < 802+visitExp (GHC.HsCase _ alts)    = length (GHC.unLoc . GHC.mg_alts $ alts) - 1+visitExp (GHC.HsLamCase _ alts) = length (GHC.unLoc . GHC.mg_alts $ alts) - 1+#else+visitExp (GHC.HsLamCase mg)     = length (GHC.unLoc . GHC.mg_alts $ mg) - 1+visitExp (GHC.HsCase _ mg)      = length (GHC.unLoc . GHC.mg_alts $ mg) - 1+#endif+visitExp _                      = 0  visitOp :: Exp -> Int visitOp (GHC.OpApp _ (GHC.L _ (GHC.HsVar op)) _ _) =-    case getName op of+    case getName (GHC.unLoc op) of       "||" -> 1       "&&" -> 1       _    -> 0
src/Argon/Walker.hs view
@@ -1,14 +1,17 @@+{-# LANGUAGE OverloadedStrings #-} module Argon.Walker (allFiles)     where -import Pipes-import Pipes.Files-import Pipes.Safe-import qualified Pipes.Prelude as P-import Data.Monoid ((<>))-import Data.List (isSuffixOf)-import System.Directory (doesFileExist)-+import           Data.DirStream            (childOf)+import           Data.List                 (isSuffixOf)+import           Filesystem.Path.CurrentOS (decodeString, encodeString)+import           Pipes                     (ListT, MonadIO, Producer, each,+                                            every, liftIO, (>->))+import qualified Pipes.Prelude             as P+import           Pipes.Safe+import           System.Directory          (doesDirectoryExist, doesFileExist,+                                            pathIsSymbolicLink)+import           System.FilePath           (takeExtension)  -- | Starting from a path, generate a sequence of paths corresponding --   to Haskell files. The filesystem is traversed depth-first.@@ -16,4 +19,16 @@ allFiles path = do     isFile <- liftIO $ doesFileExist path     if isFile then each [path] >-> P.filter (".hs" `isSuffixOf`)-              else find path (glob "*.hs" <> regular)+              else every $ hsFilesIn path++-- | List the regular files in a directory.+hsFilesIn :: MonadSafe m => FilePath -> ListT m FilePath+hsFilesIn path = do+  child <- encodeString <$> childOf (decodeString path)+  isDir <- liftIO $ doesDirectoryExist child+  isSymLink <- liftIO $ pathIsSymbolicLink child+  if isDir && not isSymLink+    then hsFilesIn child+    else if not isSymLink && takeExtension child == ".hs"+         then return child+         else mempty
− stack-7.8.yaml
@@ -1,15 +0,0 @@-flags: {}-extra-package-dbs: []-packages:-- '.'-extra-deps:-- docopt-0.7.0.4-- syb-0.4.4-- ghc-7.8.4-- lens-simple-0.1.0.8-- lens-family-1.2.0-- pipes-files-0.1.1-- hierarchy-0.3.1-- posix-paths-0.2.1.0-- free-4.12.1-resolver: lts-2.22
stack.yaml view
@@ -1,13 +1,4 @@-flags: {}-extra-package-dbs: []-packages:-- '.'-extra-deps:-- docopt-0.7.0.4-- hierarchy-0.3.1-- pipes-files-0.1.1-- posix-paths-0.2.1.0-- aeson-0.11.0.0-- fail-4.9.0.0-- semigroups-0.16.2.2-resolver: lts-5.2+resolver: lts-11.6++extra-deps: [dirstream-1.0.3]+
test/ArgonSpec.hs view
@@ -1,28 +1,33 @@ {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP               #-} {-# LANGUAGE OverloadedStrings #-}  module ArgonSpec (spec)     where -import Data.List (sort, isPrefixOf)-import Data.Aeson (encode)-import Text.Printf (printf)+import           Data.Aeson          (encode)+import           Data.List           (sort)+import           GHC.Stack           (HasCallStack)+import           Text.Printf         (printf) #if __GLASGOW_HASKELL__ < 710-import Control.Applicative ((<$>), (<*>))+import           Control.Applicative ((<$>), (<*>)) #endif-import Test.Hspec-import Test.QuickCheck-import System.FilePath ((</>))-import System.IO.Unsafe (unsafePerformIO)-import System.Console.ANSI-import qualified SrcLoc     as GHC-import qualified FastString as GHC-import Pipes---import Pipes.Safe (SafeT, runSafeT)-import qualified Pipes.Prelude as P+import qualified FastString          as GHC+import           Pipes               (Producer, (>->), each)+import qualified SrcLoc              as GHC+import           System.Console.ANSI (Color (..), ConsoleIntensity(BoldIntensity), setSGRCode,+                                      SGR(SetColor, SetConsoleIntensity),+                                      ConsoleLayer(Foreground), ColorIntensity(Dull))+import           System.FilePath     ((</>))+import           System.IO.Unsafe    (unsafePerformIO)+import           Test.Hspec          (describe, it, Expectation, shouldBe,+                                      shouldContain, Spec, expectationFailure,+                                      shouldReturn)+import           Test.QuickCheck     (Arbitrary, arbitrary, shrink, property, elements)+import qualified Pipes.Prelude       as P+import           Data.Foldable       (traverse_) -import Argon+import           Argon  instance Arbitrary ComplexityBlock where     arbitrary = (\a b c -> CC (a, b, c)) <$> arbitrary@@ -31,7 +36,7 @@     shrink (CC t) = map CC $ shrink t  instance Arbitrary OutputMode where-+    arbitrary = elements [BareText, Colored, JSON]  ones :: Loc ones = (1, 1)@@ -43,17 +48,20 @@ realSpan a b = GHC.mkSrcSpan (mkLoc a b) $ mkLoc (-a) (b + 24)     where mkLoc = GHC.mkSrcLoc (GHC.mkFastString "real loc") -errStartsWith :: String -> (FilePath, AnalysisResult) -> Bool-errStartsWith _ (_, Right _)  = False-errStartsWith p (_, Left msg) = p `isPrefixOf` msg+shouldContainErrors :: HasCallStack => FilePath -> [String] -> Expectation+shouldContainErrors f errs = do+    r <- analyze defaultConfig (path f)+    case r of+        (_, Right _)  -> expectationFailure $ "Test did not fail" ++ show r+        (_, Left msg) -> traverse_ (msg `shouldContain`) errs  path :: String -> FilePath path f = "test" </> "data" </> f -shouldAnalyze :: String -> AnalysisResult -> Expectation+shouldAnalyze :: HasCallStack => String -> AnalysisResult -> Expectation shouldAnalyze f = shouldAnalyzeC (f, defaultConfig) -shouldAnalyzeC :: (String, Config) -> AnalysisResult -> Expectation+shouldAnalyzeC :: HasCallStack => (String, Config) -> AnalysisResult -> Expectation shouldAnalyzeC (f, config) r = analyze config p `shouldReturn` (p, r)     where p = path f @@ -138,26 +146,27 @@                 "arrows.hs" `shouldAnalyze` Right [CC (lo 7, "getAnchor", 1)]         describe "errors" $ do             it "catches syntax errors" $-                "syntaxerror.hs" `shouldAnalyze`-                    Left ("2:1 parse error (possibly incorrect indentation" ++-                          " or mismatched brackets)")+                "syntaxerror.hs" `shouldContainErrors`+                ["parse error (possibly incorrect indentation or mismatched brackets)"]             it "catches syntax errors (missing CPP)" $                 "missingcpp.hs" `shouldAnalyze`+#if __GLASGOW_HASKELL__ < 800                     Left "1:2 lexical error at character 'i'"+#else+                    Left "1:1 parse error on input \8216#\8217"+#endif+#if __GLASGOW_HASKELL__ < 800+-- The analysis of "missingmacros.hs" will succeed in newest GHC versions.             it "catches syntax errors (missing cabal macros)" $-                unsafePerformIO (analyze defaultConfig (path "missingmacros.hs"))-                    `shouldSatisfy`-                    errStartsWith ("2:0  error: missing binary operator " ++-                                   "before token ")+                "missingmacros.hs" `shouldContainErrors`+                ["error: missing binary operator before token "]+#endif             it "catches syntax errors (missing include dir)" $-                unsafePerformIO (analyze defaultConfig (path "missingincluded.hs"))-                    `shouldSatisfy`-                    errStartsWith ("2:0  fatal error: necessaryInclude.h: "-                                  ++ "No such file or directory")+                "missingincluded.hs" `shouldContainErrors`+                ["fatal error", "necessaryInclude.h"]             it "catches CPP parsing errors" $-                unsafePerformIO (analyze defaultConfig (path "cpp-error.hs"))-                    `shouldSatisfy`-                    errStartsWith "2:0  error: unterminated #else"+                 "cpp-error.hs" `shouldContainErrors`+                 ["error: unterminated"]         describe "config" $ do             it "reads default extensions from Cabal file" $                 ("missingcpp.hs", unsafePerformIO@@ -165,10 +174,24 @@                         return $ defaultConfig { exts = loadedExts }))                     `shouldAnalyzeC`                     Right [CC (lo 4, "f", 1)]+            it "reads other extensions from Cabal file" $+                ("missingcpp.hs", unsafePerformIO+                    (do loadedExts <- parseExts $ path "test-other.cabal"+                        return $ defaultConfig { exts = loadedExts }))+                    `shouldAnalyzeC`+                    Right [CC (lo 4, "f", 1)]+            it "reads old extensions from Cabal file" $+                ("missingcpp.hs", unsafePerformIO+                    (do loadedExts <- parseExts $ path "test-old.cabal"+                        return $ defaultConfig { exts = loadedExts }))+                    `shouldAnalyzeC`+                    Right [CC (lo 4, "f", 1)]+#if __GLASGOW_HASKELL__ < 800             it "includes Cabal macros for preprocessing" $                 ( "missingmacros.hs"                 , defaultConfig { headers = [path "cabal_macros.h"] }                 ) `shouldAnalyzeC` Right [CC (lo 3, "f", 2)]+#endif             it "includes directory from include-dir for preprocessing" $                 ( "missingincluded.hs"                 , defaultConfig { includeDirs = [path "include"] }
+ test/data/test-old.cabal view
@@ -0,0 +1,18 @@+name:                ftw+version:             0.0+author:              Michele Lacchia+build-type:          Simple+cabal-version:       >=1.18++library+  hs-source-dirs:      .+  extensions:          CPP+  build-depends:       base             >=4.7    && <5+  default-language:    Haskell2010+  ghc-options:         -Wall+  if impl(ghc < 7.8)+    buildable: False++source-repository head+  type:     git+  location: https://github.com/rubik/argon
+ test/data/test-other.cabal view
@@ -0,0 +1,18 @@+name:                ftw+version:             0.0+author:              Michele Lacchia+build-type:          Simple+cabal-version:       >=1.18++library+  hs-source-dirs:      .+  other-extensions:    CPP+  build-depends:       base             >=4.7    && <5+  default-language:    Haskell2010+  ghc-options:         -Wall+  if impl(ghc < 7.8)+    buildable: False++source-repository head+  type:     git+  location: https://github.com/rubik/argon