git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Integrate 'go build' with psgo tool
commit6f188537c535b5a0b8b2a9abc4be1c7b283fbe32 authorAndy Arvanitis <andyarvanitis@gmail.com> dateFri 12 Jul 2019, 17:54 (7 years ago) parente7cb2a9
1 file changed+57−30
app/Main.hs+57−30
app/Main.hs+57−30
@@ -10,7 +10,7 @@ import Data.Aeson
1010import Data.Aeson.Types
1111import Data.Char
1212import Data.FileEmbed (embedFile)
13−import Data.List (delete, isPrefixOf, partition)
13+import Data.List (delete, intercalate, isPrefixOf, nub, partition)
1414import Data.Maybe
1515import Data.Monoid ((<>))
1616import Data.Version
@@ -20,8 +20,9 @@ import Text.Printf
2020
2121import System.Environment
2222import System.Directory (createDirectoryIfMissing, doesDirectoryExist, doesFileExist, getCurrentDirectory, getModificationTime)
23−import System.FilePath ((</>), joinPath, splitDirectories, takeDirectory)
23+import System.FilePath ((</>), joinPath, searchPathSeparator, splitDirectories, takeDirectory)
2424import System.FilePath.Find
25+import System.Process
2526
2627import Data.Text (Text)
2728import qualified Data.Text as T
@@ -40,6 +41,8 @@ import CodeGen.IL.Printer
4041
4142import Tests
4243
44+data Command = Build | Run
45+
4346parseJson :: Text -> Value
4447parseJson text
4548 | Just fileJson <- decode . L.encodeUtf8 $ L.fromStrict text = fileJson
@@ -59,34 +62,32 @@ main = do
5962 if "--tests" `elem` opts'
6063 then runTests
6164 else do
62− when ("--makefile" `elem` opts') $
63− B.writeFile "Makefile" $(embedFile "support/Makefile")
64− when ("--help" `elem` opts') $
65− putStrLn help
66− if null files then
67− when (null opts) $ do
68− currentDir <- getCurrentDirectory
69− processFiles opts' [currentDir]
70− else
71− processFiles opts' files
72− return ()
65+ if "--help" `elem` opts'
66+ then putStrLn help
67+ else do
68+ if null files
69+ then do
70+ currentDir <- getCurrentDirectory
71+ processFiles opts' [currentDir]
72+ else
73+ processFiles opts' files
74+ if "--run" `elem` opts
75+ then runBuildTool Run
76+ else when ("--no-build" `notElem` opts) $
77+ runBuildTool Build
78+ return ()
7379 where
7480 processFiles :: [String] -> [FilePath] -> IO ()
7581 processFiles opts [file] = do
7682 isDir <- doesDirectoryExist file
7783 if isDir then do
7884 files <- find always (fileName ==? corefn) file
79− if null files then do
80− noneFound
81− else do
82− generateFiles opts files
83− else do
84− generateFiles opts [file]
85+ if null files
86+ then errorNoCorefnFiles
87+ else generateFiles opts files
88+ else generateFiles opts [file]
8589 processFiles opts files = do
86− let baseOutpath = basePath files
87− writeRuntimeFiles baseOutpath
88− Par.mapM (generateCode opts baseOutpath) files
89− return ()
90+ generateFiles opts files
9091 basePath :: [FilePath] -> FilePath
9192 basePath files =
9293 let filepath = takeDirectory (head files) in
@@ -97,6 +98,27 @@ main = do
9798 writeRuntimeFiles baseOutpath
9899 Par.mapM (generateCode opts baseOutpath) files
99100 return ()
101+ runBuildTool :: Command -> IO ()
102+ runBuildTool cmd = do
103+ let command = case cmd of
104+ Build -> "build"
105+ Run -> "run"
106+ currentDir <- getCurrentDirectory
107+ files <- find always (extension ==? goSrc) currentDir
108+ let fileDirs = nub $ joinPath . init <$> filter isSrc (getDir <$> files)
109+ currentEnv <- getEnvironment
110+ let searchPath = intercalate [searchPathSeparator] fileDirs
111+ env = ("GOPATH", searchPath) : currentEnv
112+ (_, _, _, p) <- createProcess (proc "go" [command, "Main"]){ env = Just env }
113+ waitForProcess p
114+ return ()
115+ where
116+ getDir :: FilePath -> [FilePath]
117+ getDir file =
118+ let filepath = takeDirectory file in
119+ init $ splitDirectories filepath
120+ isSrc :: [FilePath] -> Bool
121+ isSrc components = (last components) == "src"
100122
101123generateCode :: [String] -> FilePath -> FilePath -> IO ()
102124generateCode opts baseOutpath jsonFile = do
@@ -144,12 +166,12 @@ implFileName mn = T.unpack $ mn <> ".go"
144166
145167help :: String
146168help = "Usage: psgo OPTIONS COREFN-FILES\n\
147− \ PureScript-to-go compiler\n\n\
169+ \ PureScript to native (via go) compiler\n\n\
148170 \Available options:\n\
149171 \ --help Show this help text\n\n\
150− \ --makefile Generate a GNU Makefile which can be used for compiling\n\
151− \ a PureScript program and libraries to a native binary via\n\
152− \ purs corefn output and C++\n\n\
172+ \ --run Run the generated go code directly, without building an\n\
173+ \ executable\n\
174+ \ --no-build Generate go source files, but do not build an executable\n\
153175 \ --tests Run test cases (under construction)\n\n\
154176 \See also:\n\
155177 \ purs compile --help\n"
@@ -157,6 +179,11 @@ help = "Usage: psgo OPTIONS COREFN-FILES\n\
157179corefn :: String
158180corefn = "corefn.json"
159181
160−noneFound :: IO ()
161−noneFound = do
162− putStrLn $ "No compiled purescript files (" <> corefn <> ") found"
182+goSrc :: String
183+goSrc = ".go"
184+
185+errorNoCorefnFiles :: IO ()
186+errorNoCorefnFiles = do
187+ ioError . userError $ "no compiled purescript '" <> corefn <> "' files found –\n" <>
188+ " make sure to use the '--codegen corefn' option with your purs\n" <>
189+ " project build tool"