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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
{-# 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 {
settingsCompiler :: !Text
, settingsProjectName :: !Text
, settingsDebugOptions :: ![Text]
, settingsLibrary :: !Library }
data Library = Library { librarySourceDir :: !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 -> do
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"
let compiler = unpack $ settingsCompiler settings
let projectName = unpack $ settingsProjectName settings
let flags = map unpack $ settingsDebugOptions settings
let librarySettings = settingsLibrary settings
let librarySourceDir' = unpack $ librarySourceDir librarySettings
buildLibrary librarySourceDir'
[".f90", ".f", ".F", ".F90", ".f95", ".f03"]
("build" </> "library")
compiler
flags
projectName
[]
buildProgram "app"
["build" </> "library"]
[".f90", ".f", ".F", ".F90", ".f95", ".f03"]
("build" </> "app")
compiler
flags
projectName
"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"
.= settingsCompiler
<*> Toml.text "name"
.= settingsProjectName
<*> Toml.arrayOf Toml._Text "debug-options"
.= settingsDebugOptions
<*> Toml.table libraryCodec "library"
.= settingsLibrary
libraryCodec :: TomlCodec Library
libraryCodec = Library <$> Toml.text "source-dir" .= librarySourceDir
|