{-| Copyright : (C) 2022 , Google Inc. License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V. Produce static files that are useful when working with Clash designs. -} {-# LANGUAGE QuasiQuotes #-} module Main where import Control.Monad (when) import Control.Monad.Extra (whenM, unlessM) import Prelude import System.Console.Docopt (Docopt, docopt, isPresent, getArg, longOption, parseArgsOrExit) import System.Directory (copyFile, doesDirectoryExist, doesFileExist) import System.Environment (getArgs) import System.Exit (die) import System.FilePath (takeDirectory) import Clash.DataFiles patterns :: Docopt patterns = [docopt| Obtain static files useful when working with Clash designs Currently, only the Tcl connector is available. Usage: static-files [--force] [--verbose] --tcl-connector= Options: -f, --force Overwrite existing files -v, --verbose Explain what is being done --tcl-connector= Write a Tcl script to a file that can parse Clash manifest JSON files and emit the correct commands for loading the design into Vivado |] -- Checks whether it looks like we can write a file in the location @path@, -- accounting for the @--force@ command line argument. Exit with a descriptive -- error message if something's amiss. createOkayOrDie :: FilePath -> Bool -> IO () createOkayOrDie path force = do let pathDir = takeDirectory path unlessM (doesDirectoryExist pathDir) $ die $ "Directory not found: " ++ pathDir whenM (doesDirectoryExist path) $ die $ path ++ " is a directory. Please specify a file name." exists <- doesFileExist path when (exists && not force) $ die $ path ++ " already exists and --force not specified. " ++ "Refusing to overwrite." main :: IO () main = do args <- parseArgsOrExit patterns =<< getArgs -- Since we got here, we know we got invoked with the sole mandatory option -- @--tcl-connector@ and its mandatory argument let force = args `isPresent` (longOption "force") verbose = args `isPresent` (longOption "verbose") Just outFile = args `getArg` (longOption "tcl-connector") createOkayOrDie outFile force inFile <- tclConnector copyFile inFile outFile when verbose $ putStrLn $ "Tcl Connector written to " ++ outFile