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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Build ( buildLibrary
, buildProgram
)
import Data.Text ( Text
, unpack
)
import qualified Data.Text.IO as TIO
import Development.Shake ( FilePattern
, (<//>)
, getDirectoryFilesIO
)
import Development.Shake.FilePath ( (</>) )
import Options.Applicative ( Parser
, (<**>)
, command
, execParser
, fullDesc
, info
, header
, helper
, progDesc
, subparser
)
import Toml ( TomlCodec
, (.=)
)
import qualified Toml
newtype Arguments = Arguments { command' :: Command }
data Settings = Settings { compiler :: !Text }
data Command = Run | Test | Build
main :: IO ()
main = do
args <- getArguments
fpmContents <- TIO.readFile "fpm.toml"
let settings = Toml.decode settingsCodec fpmContents
case settings of
Left err -> print err
Right settings -> app args settings
app :: Arguments -> Settings -> IO ()
app args settings = case command' args of
Run -> putStrLn "Run"
Test -> putStrLn "Test"
Build -> build settings
build :: Settings -> IO ()
build settings = do
putStrLn "Building"
buildLibrary "src"
[".f90", ".f", ".F", ".F90", ".f95", ".f03"]
("build" </> "library")
(unpack $ compiler settings)
["-g", "-Wall", "-Wextra", "-Werror", "-pedantic"]
"library"
[]
buildProgram "app"
["build" </> "library"]
[".f90", ".f", ".F", ".F90", ".f95", ".f03"]
("build" </> "app")
(unpack $ compiler settings)
["-g", "-Wall", "-Wextra", "-Werror", "-pedantic"]
"example_project"
"main.f90"
getArguments :: IO Arguments
getArguments = execParser
(info
(arguments <**> helper)
(fullDesc <> progDesc "Work with Fortran projects" <> header
"fpm - A Fortran package manager and build system"
)
)
arguments :: Parser Arguments
arguments = subparser
( command "run" (info runArguments (progDesc "Run the executable"))
<> command "test" (info testArguments (progDesc "Run the tests"))
<> command "build" (info buildArguments (progDesc "Build the executable"))
)
runArguments :: Parser Arguments
runArguments = pure $ Arguments Run
testArguments :: Parser Arguments
testArguments = pure $ Arguments Test
buildArguments :: Parser Arguments
buildArguments = pure $ Arguments Build
getDirectoriesFiles :: [FilePath] -> [FilePattern] -> IO [FilePath]
getDirectoriesFiles dirs exts = getDirectoryFilesIO "" newPatterns
where
newPatterns = concatMap appendExts dirs
appendExts dir = map ((dir <//> "*") ++) exts
settingsCodec :: TomlCodec Settings
settingsCodec = Settings <$> Toml.text "compiler" .= compiler
|