-
Notifications
You must be signed in to change notification settings - Fork 21
/
Shake.hs
189 lines (158 loc) · 5.41 KB
/
Shake.hs
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
{-# LANGUAGE DeriveDataTypeable #-}
import Control.Monad (forM_, replicateM_, when)
import Data.Functor ((<$>))
import Data.List (find, isPrefixOf)
import Data.Monoid ((<>))
import Development.Shake
import Development.Shake.FilePath
import System.Cmd (system)
import System.Console.CmdArgs
import System.Directory (doesDirectoryExist)
import System.FilePath (takeFileName)
data CIS194Mode =
Build
| Preview
| Clean
| Deploy
deriving (Show, Data, Typeable)
cis194Modes = modes
[ Build &= auto
, Preview
, Clean
, Deploy
]
main :: IO ()
main = (shake shakeOptions . chooseMode) =<< cmdArgs cis194Modes
chooseMode :: CIS194Mode -> Rules ()
chooseMode mode = cis194Rules <> choose mode
where
choose (Build {}) = doBuild
choose (Preview {}) = doPreview
choose (Clean {}) = doClean
choose (Deploy {}) = doDeploy
cis194Rules :: Rules ()
cis194Rules = genericRules <> webRules <> weekRules
doBuild = action $ requireBuild
doClean = action $ do
alwaysRerun
system' "rm" ["-rf", "web/_site", "web/_cache"]
doPreview = action $ do
alwaysRerun
requireBuild
need ["web/hakyll.hs.exe"]
systemCwd "web" ("./hakyll.hs.exe") ["preview", "8000"]
doDeploy = action $ do
alwaysRerun
liftIO $ system "rsync -tvr web/_site/* [email protected]:html/ && ssh [email protected] chmod -R o+rX html/"
--------------------------------------------------
webRules :: Rules ()
webRules = do
"web/lectures/*.markdown" *> \out -> do
let base = takeBaseName out
f = weekFile base "" "markdown"
copyFile' f out
"web/lectures/*.lhs" *> \out -> do
let base = takeBaseName out
f = weekFile base "lec" "lhs"
copyFile' f out
"web/lectures/*.html" *> \out -> do
let base = takeBaseName out
f = weekFile base "lec" "lhs"
need [f, "tools/processLec.hs.exe"]
system' "tools/processLec.hs.exe"
[ "html", f, "-o", out ]
"web/hw/*.pdf" *> \out -> do
let base = takeBaseName out
f = weekFile base "hw" "pdf"
copyFile' f out
"web/docs/*" *> \out -> do
copyFile' (dropDirectory1 out) out
"web/extras//*" *> \out -> do
let (week,f) = splitFileName . dropDirectory1 . dropDirectory1 $ out
loc = "weeks" </> week </> "hw" </> "skel" </> f
e <- doesFileExist loc
let loc' = case e of
True -> loc
False -> "weeks" </> week </> "hw" </> f
copyFile' loc' out
weekRules :: Rules ()
weekRules = do
"weeks//*.inclass.lhs" *> \out -> do
let base = takeBaseName . takeBaseName $ out
f = weekFile base "lec" "lhs"
need [f, "tools/processLec.hs.exe"]
system' "tools/processLec.hs.exe"
[ "class", f, "-o", out ]
requireBuild :: Action ()
requireBuild = do
weekDirs <- getDirectoryDirs "weeks"
mapM_ copyImages weekDirs
need =<< (concat <$> mapM mkWeek weekDirs)
need ["web/docs/inthelarge.pdf", "web/docs/style.pdf"]
where
copyImages week = do
let imgDir = "weeks" </> week </> "images"
exists <- doesFileExist imgDir
when exists $ do
imgFiles <- getDirectoryFiles imgDir ["*"]
mapM_ (\f -> copyFile' (imgDir </> f) ("web/images" </> f)) imgFiles
mkWeek week = do
extras <- getExtras week
solsExist <- doesFileExist (weekFile week "sols" "lhs")
slidesExist <- doesFileExist (weekFile week "slides" "lhs")
return $
[ weekFile week "hw" "pdf"
, weekFile week "inclass" "lhs"]
++
[ weekFile week "sols" "pdf" | solsExist ]
++
[ weekFile week "slides" "pdf" | slidesExist ]
++
[ "web/lectures" </> week <.> "markdown"
, "web/lectures" </> week <.> "lhs"
, "web/lectures" </> week <.> "html"
, "web/hw" </> week <.> "pdf"
]
++
map (("web/extras" </> week </>) . takeFileName) extras
weekFile :: FilePath -> String -> String -> FilePath
weekFile week tag ext = "weeks" </> week </> (week <.> tag) <.> ext
getExtras :: FilePath -> Action [FilePath]
getExtras week = do
wws <- map words <$> readFileLines (weekFile week "" "markdown")
case find (\ws -> (not . null $ ws) && (head ws == "extras:")) wws of
Nothing -> return []
Just fs -> return (tail fs)
--------------------------------------------------
genericRules :: Rules ()
genericRules = do
"//*.hs.exe" *> \out -> do
let hs = dropExtension out
need [hs]
system' "ghc" ["--make", "-o", out, hs]
["docs//*.pdf", "weeks//*.pdf"] **> \out -> do
let tex = replaceExtension out "tex"
dir = takeDirectory out
need [tex]
pkgs <- ( map (takeWhile (/= '}') . drop 1 . dropWhile (/= '{'))
. filter ("\\usepackage" `isPrefixOf`)
)
<$> readFileLines tex
forM_ pkgs $ \pkg -> do
let sty = dir </> pkg <.> "sty"
e <- doesFileExist sty
when e $ need [sty]
hs <- getDirectoryFiles dir ["*.hs"]
need (map (dir </>) hs)
let tex' = takeFileName tex
replicateM_ 2 $
systemCwd dir "pdflatex"
["--enable-write18", tex']
"//*.tex" *> \out -> do
let lhs = replaceExtension out "lhs"
dir = takeDirectory out
useLhs <- doesFileExist lhs
when useLhs $ do
need [lhs]
system' "lhs2TeX" ["--verb", lhs, "-o", out]
--------------------------------------------------