ethereum-analyzer-cli 3.1.0 → 3.2.0
raw patch · 3 files changed
+109/−53 lines, 3 filesdep +filepathdep +hoopldep +timePVP ok
version bump matches the API change (PVP)
Dependencies added: filepath, hoopl, time
API changes (from Hackage documentation)
+ Ethereum.Executable.Analyze: analyzeMain :: IO ()
+ Ethereum.Executable.Analyze: instance GHC.Classes.Eq Ethereum.Executable.Analyze.AnalyzeFlags
+ Ethereum.Executable.Analyze: instance GHC.Show.Show Ethereum.Executable.Analyze.AnalyzeFlags
Files
- ethereum-analyzer-cli.cabal +9/−9
- exec_src/AnalyzeMain.hs +2/−44
- src/Ethereum/Executable/Analyze.hs +98/−0
ethereum-analyzer-cli.cabal view
@@ -1,5 +1,5 @@ name: ethereum-analyzer-cli-version: 3.1.0+version: 3.2.0 synopsis: A CLI frontend for ethereum-analyzer. homepage: https://github.com/zchn/ethereum-analyzer license: Apache-2.0@@ -21,7 +21,7 @@ source-repository this type: git location: https://github.com/zchn/ethereum-analyzer- tag: v3.1.0+ tag: v3.2.0 subdir: ethereum-analyzer-cli library@@ -33,18 +33,24 @@ , ethereum-analyzer , ethereum-analyzer-deps , exceptions+ , filepath , hexstring+ , hoopl , http-conduit , json-rpc , monad-logger , mtl+ , optparse-applicative+ , optparse-text , protolude , text+ , time , tostring , unordered-containers , vector - exposed-modules: Ethereum.Executable.BytecodeVisMain+ exposed-modules: Ethereum.Executable.Analyze+ Ethereum.Executable.BytecodeVisMain Ethereum.Executable.DumpCodeMain other-modules: Ethereum.Jsonrpc.Client ghc-options: -Wall@@ -57,14 +63,8 @@ executable ea-analyze main-is: AnalyzeMain.hs build-depends: base >= 4 && < 5- , ethereum-analyzer , ethereum-analyzer-cli- , ethereum-analyzer-deps- , monad-logger- , optparse-applicative- , optparse-text , protolude- , text ghc-options: -Wall hs-source-dirs: exec_src buildable: True
exec_src/AnalyzeMain.hs view
@@ -4,49 +4,7 @@ import Protolude -import qualified Data.Text as T--import Ethereum.Analyzer.Debug-import Ethereum.Analyzer.Solidity hiding (value)--import Options.Applicative-import Options.Applicative.Text--data AnalyzeFlags = AnalyzeFlags- { astJson :: Text- , debug :: Bool- } deriving (Eq, Show)--analyzeFlags :: Parser AnalyzeFlags-analyzeFlags =- AnalyzeFlags <$>- textOption- (long "astJson" <> value "" <> metavar "PATH" <>- help "Path to the ast-json file.") <*>- switch (long "debug" <> help "Whether to print debug info")+import Ethereum.Executable.Analyze main :: IO ()-main = analyze =<< execParser opts- where- opts =- info- (analyzeFlags <**> helper)- (fullDesc <>- progDesc (toS ("Analyze the contract specified at PATH" :: Text)) <>- header- (toS ("ea-analyze - CLI interface for ethereum-analyzer" :: Text)))--analyze :: AnalyzeFlags -> IO ()-analyze flags@AnalyzeFlags {astJson = theAstJson, debug = debug} = do- when debug $ putText $ show flags- content <-- if theAstJson == "" || theAstJson == "-"- then getContents- else readFile $ toS theAstJson- case decodeContracts content of- Right contracts -> do- when debug $ pprintContracts contracts- putText "Findings: \n"- putText ("\n" `T.intercalate` concatMap findingsFor contracts)- Left err -> putText err- return ()+main = analyzeMain
+ src/Ethereum/Executable/Analyze.hs view
@@ -0,0 +1,98 @@+module Ethereum.Executable.Analyze+ ( analyzeMain+ ) where++import Protolude hiding ((<.>))++import Compiler.Hoopl (runSimpleUniqueMonad)++import Data.Time.Clock+import Data.Time.Format++import Ethereum.Analyzer.Debug+import Ethereum.Analyzer.Solidity hiding (value)+import Ethereum.Analyzer.Util++import Options.Applicative+import Options.Applicative.Text++import System.Directory+import System.FilePath++import qualified Data.Text as T++data AnalyzeFlags = AnalyzeFlags+ { astJson :: Text+ , workDir :: Text+ , debug :: Bool+ } deriving (Eq, Show)++analyzeFlags :: Parser AnalyzeFlags+analyzeFlags =+ AnalyzeFlags <$>+ textOption+ (long "astJson" <> value "" <> metavar "PATH" <>+ help "Path to the ast-json file.") <*>+ textOption+ (long "workDir" <> value "work" <> metavar "PATH" <>+ help "Path to the work directory (for outputs and intermediate files).") <*>+ switch (long "debug" <> help "Whether to print debug info")++analyzeMain :: IO ()+analyzeMain = analyze =<< execParser opts+ where+ opts =+ info+ (analyzeFlags <**> helper)+ (fullDesc <>+ progDesc (toS ("Analyze the contract specified at PATH" :: Text)) <>+ header+ (toS ("ea-analyze - CLI interface for ethereum-analyzer" :: Text)))++analyze :: AnalyzeFlags -> IO ()+analyze flags@AnalyzeFlags { astJson = theAstJson+ , workDir = theWorkDir+ , debug = debug} = do+ tmpDirname <- getTmpDirname+ let sessionDir = toS theWorkDir </> toS tmpDirname+ createDirectoryIfMissing True sessionDir+ when debug $ putText $ show flags+ content <-+ if theAstJson == "" || theAstJson == "-"+ then getContents+ else readFile $ toS theAstJson+ case decodeContracts content of+ Right contracts -> do+ savePrettyContracts contracts (toS $+ sessionDir </> "contracts.ir")+ when debug $ pprintContracts contracts+ saveCfgs contracts (toS $ sessionDir </> "cfgs")+ putText "Findings: \n"+ putText ("\n" `T.intercalate` concatMap findingsFor contracts)+ Left err -> putText err+ return ()++getTmpDirname :: IO Text+getTmpDirname = do+ t <- getCurrentTime+ let formated = formatTime defaultTimeLocale (+ iso8601DateFormat (Just "%H:%M:%S")) t+ return $ toS formated++savePrettyContracts :: [Contract] -> Text -> IO ()+savePrettyContracts cs filepath =+ writeFile (toS filepath) (prettyContracts cs)++saveCfgs :: [Contract] -> Text -> IO ()+saveCfgs cs dirpath = do+ createDirectoryIfMissing True (toS dirpath)+ let hcs = runSimpleUniqueMonad $ mapM hoopleOf cs+ mapM writeContractCfgs hcs+ return ()+ where writeContractCfgs hc = do+ mapM (writeFunCfgs (toS dirpath </> toS (hcName hc))) (hcFunctions hc)+ return ()+ writeFunCfgs contractPrefix hf = do+ let dot = toDotText (hfCFG hf)+ writeFile (contractPrefix <.> (toS $ unIdfr $ hfName hf)+ <.> "CFG" <.> ".dot") dot