{-|
Module : Analyse
Description : Main test module for program analysis
Copyright : Copyright (C) 2019 S. Kamps
License : -- This file is distributed under the terms of the Apache License 2.0.
For more information, see the file "LICENSE", which is included in the distribution.
Stability : experimental
-}
module Analyse
(analyse
) where
import qualified Control.Monad as Monad
import CsvData
import qualified Data.Set as Set
import FileOperation
import qualified MetaHS.DataModel.MetaModel as MetaModel
import MetaHS.EDSL
import MetaHS.Extensions.CBO
import MetaHS.Extensions.LCOM
import MetaHS.Extensions.LOC
import qualified ModuleLevelAnalysis as ModuleLevel
import qualified ProgramLevelAnalysis as ProgramLevel
import Settings
import System.Directory (createDirectory,
doesDirectoryExist, doesFileExist,
removeDirectoryRecursive,
removeFile)
import System.FilePath.Posix ((</>))
import Text.Printf
-- | Start analysis based on the type of required information.
-- | Type of analysis is either Evolution or Distribution.
-- | Type of metric is either LCOM, LOC or CBO
analyse :: Settings -- ^ The settings required for the Implementation Under Test.
-> IO ()
analyse settings@(Settings _ _ _ Evolution LCOM) = do
setupOutputDirectory settings
metaModel <- generate settings
let metaModelCompl = lcomAggregator metaModel
analyseEvo settings metaModelCompl
analyse settings@(Settings _ _ _ Evolution CBO) = do
setupOutputDirectory settings
metaModel <- generate settings
let metaModelCompl = cboAggregator metaModel
analyseEvo settings metaModelCompl
analyse settings@(Settings _ _ _ Evolution LOC) = do
setupOutputDirectory settings
metaModel <- generate settings
let metaModelCompl = locAggregator metaModel
analyseEvo settings metaModelCompl
analyse settings@(Settings _ _ _ Distribution LCOM) = do
setupOutputDirectory settings
metaModel <- generate settings
let metaModelCompl = lcomAggregator metaModel
analyseDist settings metaModelCompl
analyse settings@(Settings _ _ _ Distribution CBO) = do
setupOutputDirectory settings
metaModel <- generate settings
let metaModelCompl = cboAggregator metaModel
analyseDist settings metaModelCompl
analyse settings@(Settings _ _ _ Distribution LOC) = do
setupOutputDirectory settings
metaModel <- generate settings
let metaModelCompl = locAggregator metaModel
analyseDist settings metaModelCompl
-- | Analysis for information on program level. For instance to plot package evolution.
analyseEvo :: Settings -- ^ The settings required for the Implementation Under Test.
-> MetaModel.MetaModel -- ^ Metamodel complemented with specific metric
-> IO ()
analyseEvo settings mm = do
let iutName = programName settings
let metricName = show $ metricType settings
let id = versionHashId settings
let avg = ProgramLevel.calculateAverage id metricName mm
let median = ProgramLevel.calculateMedian id metricName mm
let gini = ProgramLevel.calculateGiniCoefficient id metricName mm
let cg = ProgramLevel.calculateCG id metricName mm
let ivd = ProgramLevel.calculateIvd id (metricType settings) mm
let cgTimesIvd = ivd * cg
let metricDetailInfo = ModuleLevel.extractMetricData id metricName mm
appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Detailinfo") metricDetailInfo
appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Average") [avg]
appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Median") [median]
appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Gini") [gini]
appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_CG") [cg]
appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_IVD") [ivd]
appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_CgTimesIvd") [cgTimesIvd]
printf "Analysis output located in %s\n" $ show $ outputDirectory settings
return ()
-- | Analysis for information about metric's module distribution.
analyseDist :: Settings -- ^ The settings required for the Implementation Under Test.
-> MetaModel.MetaModel -- ^ Metamodel complemented with specific metric
-> IO ()
analyseDist settings mm = do
setupOutputDirectory settings
let metricName = show $ metricType settings
printf "Analysing %s.\n" metricName
printf "\n"
writeMetaModeltoFile settings mm
let distList = ProgramLevel.calculateDistribution (commitHash settings) metricName mm
let popList = ProgramLevel.calculatePopulation (commitHash settings) metricName mm
mapM_ (f settings) distList
mapM_ (g settings) popList
printf "Analysis output located in %s\n" $ show $ outputDirectory settings
return ()
-- | helper for writing distribution to .csv file.
f :: Settings -> (Int,Int) -> IO ()
f s x = do
let z = DistPair x
appendDistToFile s ("Distribution " ++ show (metricType s)) z
-- | helper for writing population to .csv file.
g :: Settings -> Int -> IO ()
g s x = do
appendPopToFile s ("population " ++ show (metricType s)) x
-- | Generates the MetaModel based on the provided Settings.
generate :: Settings -- ^ The settings required for the Implementation Under Test.
-> IO MetaModel.MetaModel -- ^ The generated MetaModel.
generate settings = generateMetaModel pn sd pef
where
pn = programName settings
sd = sourcesDirectory settings
pef = parseErrorsFile settings
versionHashId :: Settings -> String
versionHashId s = version s ++ "," ++ commitHash s