1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
{-|
Copyright : (C) 2022 , Google Inc.
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <devops@qbaylogic.com>
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=<outfile>
Options:
-f, --force Overwrite existing files
-v, --verbose Explain what is being done
--tcl-connector=<outfile> 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
|