packages feed

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 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