-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathShakefile.hs
182 lines (154 loc) · 8.1 KB
/
Shakefile.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
import Development.Shake
import Development.Shake.Command
import Development.Shake.FilePath
import Development.Shake.Util
import qualified GHC.IO.Encoding
import qualified System.IO
main :: IO ()
main = do
-- Work around `hGetContents: invalid argument (invalid byte sequence)` bug on
-- Nix: /~https://github.com/dhall-lang/dhall-haskell/issues/865
GHC.IO.Encoding.setLocaleEncoding System.IO.utf8
shakeArgs
shakeOptions
{ shakeFiles = "_build",
shakeThreads = 0,
shakeChange = ChangeModtimeAndDigest,
-- we ignore a lot of generated/downloaded dependency files so
-- that the output of `shake --lint-fsatrace` is usable. There
-- are probably a few untracked dependencies due to these ignores
-- (in particular relying on scripts in `node_modules`) but the
-- additional benefits are marginal compared to the effort required
-- to get everything 100% buttoned down. Long term, it'd be better to
-- move node dependencies into nix (either by using proper packages
-- where available or npm2nix where not.)
shakeLintIgnore =
[ "node_modules/**/*",
"elm-stuff/**/*",
"component-catalog/elm-stuff/**/*"
]
}
$ do
want ["test"]
-- phonies. These provide a nice public API for using shake (`shake
-- clean`, `shake test`, etc.)
phony "clean" $ do
removeFilesAfter "elm-stuff" ["//*"]
removeFilesAfter "log" ["//*"]
removeFilesAfter "node_modules" ["//*"]
removeFilesAfter "public" ["//*"]
removeFilesAfter "component-catalog" ["elm.js", "bundle.js", "elm-stuff"]
phony "public" $ need ["log/public.txt"]
phony "test" $ do
need
[ "log/npm-install.txt",
"tests/elm-verify-examples.json",
"log/elm-verify-examples.txt",
"log/elm-test.txt",
"log/elm-test-component-catalog.txt",
"log/elm-review.txt",
"log/elm-review-component-catalog.txt",
"log/puppeteer-tests.txt",
"log/forbidden-imports-report.txt",
"log/check-exposed.txt",
"log/format.txt",
"log/documentation.json"
]
phony "ci" $ do need ["test", "public"]
-- things that should be kept under version control
"tests/elm-verify-examples.json" %> \out -> do
need ["elm.json"]
cmd (WithStdout True) (FileStdout out) "jq" "--indent" "4" ["{ root: \"../src\", tests: .[\"exposed-modules\"] }"] "elm.json"
"deprecated-modules.csv" %> \out -> do
need ["elm.json", "script/deprecated-modules-csv.py"]
cmd (WithStdout True) (FileStdout out) "script/deprecated-modules-csv.py"
"forbidden-imports.toml" %> \out -> do
-- we always want to consume our own published deprecated modules list
-- so that we're not presenting outdated stuff in the Component Catalog! This
-- file can change separately from the CSV, but should always have at
-- least the deprecated modules in it.
need ["deprecated-modules.csv"]
cmd "elm-forbid-import" "forbid-from-csv" "deprecated-modules.csv"
-- temporary files, used to produce CI reports
"log/elm-test.txt" %> \out -> do
elmFiles <- getDirectoryFiles "." ["tests/**/*.elm"]
-- I'm not sure why elm-test needs package.json, but fsatracing it
-- reveals the dep, so in it goes!
need (["package.json", "elm.json"] ++ elmFiles)
cmd (WithStdout True) (FileStdout out) "elm-test"
"log/elm-test-component-catalog.txt" %> \out -> do
elmFiles <- getDirectoryFiles "." ["component-catalog/tests/**/*.elm"]
need (["package.json", "component-catalog/elm.json"] ++ elmFiles)
cmd (Cwd "component-catalog") (WithStdout True) (FileStdout out) "elm-test"
"log/elm-review.txt" %> \out -> do
elmFiles <- getDirectoryFiles "." ["src/**/*.elm", "tests/**/*.elm"]
need (["package.json", "elm.json"] ++ elmFiles)
cmd (WithStdout True) (FileStdout out) "elm-review"
"log/elm-review-component-catalog.txt" %> \out -> do
elmFiles <- getDirectoryFiles "." ["component-catalog/**/*.elm"]
need (["package.json", "component-catalog/elm.json"] ++ elmFiles)
cmd (Cwd "component-catalog") (WithStdout True) (FileStdout out) "elm-review"
"log/elm-verify-examples.txt" %> \out -> do
elmFiles <- getDirectoryFiles "." ["src/**/*.elm"]
need (["tests/elm-verify-examples.json"] ++ elmFiles)
cmd (WithStdout True) (FileStdout out) "elm-verify-examples"
"log/format.txt" %> \out -> do
need ["log/elm-format.txt", "log/prettier.txt"]
writeFileChanged out "formatting checks passed"
"log/elm-format.txt" %> \out -> do
let placesToLook = ["src", "tests", "component-catalog"]
elmFiles <- getDirectoryFiles "." (map (\place -> place </> "**" </> "*.elm") placesToLook)
need elmFiles
cmd (WithStdout True) (FileStdout out) "elm-format" "--validate" placesToLook
"log/prettier.txt" %> \out -> do
(Stdout trackedFilesOut) <- cmd "git" "ls-files"
let trackedFiles = lines trackedFilesOut
let jsFiles = filter (\name -> takeExtension name == ".js") trackedFiles
need ("log/npm-install.txt" : jsFiles)
cmd (WithStdout True) (FileStdout out) "./node_modules/.bin/prettier" "--check" jsFiles
"log/puppeteer-tests.txt" %> \out -> do
-- `getEnv` looks like a no-op, but it actually makes Shake pay
-- attention to this variable so that if it changes this command will be
-- re-run with the new token.
getEnv "PERCY_TOKEN"
need ["log/npm-install.txt", "log/public.txt"]
cmd (WithStdout True) (FileStdout out) "script/puppeteer-tests.sh"
"log/forbidden-imports-report.txt" %> \out -> do
need ["forbidden-imports.toml"]
elmFiles <- getDirectoryFiles "." ["src/**/*.elm", "tests/**/*.elm"]
need (["forbidden-imports.toml"] ++ elmFiles)
cmd (WithStdout True) (FileStdout out) "elm-forbid-import" "check"
"log/check-exposed.txt" %> \out -> do
elmFiles <- getDirectoryFiles "." ["src/**/*.elm"]
need (["elm.json", "script/check-exposed.py"] ++ elmFiles)
cmd (WithStdout True) (FileStdout out) "script/check-exposed.py"
"log/documentation.json" %> \out -> do
elmFiles <- getDirectoryFiles "." ["src/**/*.elm"]
need elmFiles
cmd_ "elm" "make" "--docs" out
"public/bundle.js" %> \out -> do
libJsFiles <- getDirectoryFiles "." ["lib/**/*.js"]
need (["package.json", "lib/index.js", "component-catalog/manifest.js", "log/npm-install.txt"] ++ libJsFiles)
cmd_ "./node_modules/.bin/browserify" "--entry" "component-catalog/manifest.js" "--outfile" out
"public/elm.js" %> \out -> do
elmSources <- getDirectoryFiles "." ["component-catalog/src/**/*.elm", "src/**/*.elm"]
need elmSources
cmd_ (Cwd "component-catalog") "elm" "make" "src/Main.elm" "--output" (".." </> out)
"public/package.json" %> \out -> do
copyFileChanged "elm.json" out
"public/application.json" %> \out -> do
copyFileChanged "component-catalog/elm.json" out
"public/**/*" %> \out ->
copyFileChanged (replaceDirectory1 out "component-catalog") out
"log/public.txt" %> \out -> do
need (["public/index.html", "public/favicon.svg", "public/elm.js", "public/bundle.js", "public/package.json", "public/application.json"])
writeFileChanged out "built component-catalog app successfully"
-- dev deps we get dynamically instead of from Nix (frowny face)
"log/npm-install.txt" %> \out -> do
-- npm looks in some unrelated files for whatever reason. We mark
-- them as used here to avoid getting linter errors.
gitHeads <- getDirectoryFiles "." [".git/refs/heads/*"]
trackRead (["README.md", ".git/HEAD"] ++ gitHeads)
-- now that we've satisfied the linter, let's build.
need ["package.json", "package-lock.json"]
cmd (WithStdout True) (FileStdout out) (FileStderr out) "npm" "install"