noredink-ui/Shakefile.hs
2020-12-03 20:39:45 -06:00

161 lines
7.0 KiB
Haskell

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/**/*",
"styleguide-app/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 "styleguide-app" ["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/axe-report.txt",
"log/percy-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 styleguide! 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-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
let placesToLook = ["src", "tests", "styleguide-app"]
elmFiles <- getDirectoryFiles "." (map (\place -> place </> "**" </> "*.elm") placesToLook)
need elmFiles
cmd (WithStdout True) (FileStdout out) "elm-format" "--validate" placesToLook
"log/percy-tests.txt" %> \out -> do
percyToken <- getEnv "PERCY_TOKEN"
case percyToken of
Nothing -> do
writeFileChanged out "Skipped running Percy tests, PERCY_TOKEN not set."
Just _ -> do
need ["log/npm-install.txt"]
cmd (WithStdout True) (FileStdout out) "script/percy-tests.js"
"log/axe-report.json" %> \out -> do
need ["log/npm-install.txt", "script/run-axe.sh", "script/axe-puppeteer.js", "log/public.txt"]
cmd (WithStdout True) (FileStdout out) "script/run-axe.sh"
"log/axe-report.txt" %> \out -> do
need ["log/axe-report.json", "script/format-axe-report.sh", "script/axe-report.jq"]
cmd (WithStdout True) (FileStdout out) "script/format-axe-report.sh" "log/axe-report.json"
"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", "styleguide-app/manifest.js", "log/npm-install.txt"] ++ libJsFiles)
cmd_ "./node_modules/.bin/browserify" "--entry" "styleguide-app/manifest.js" "--outfile" out
"public/elm.js" %> \out -> do
elmSources <- getDirectoryFiles "." ["styleguide-app/**/*.elm", "src/**/*.elm"]
need elmSources
cmd_ (Cwd "styleguide-app") "elm" "make" "Main.elm" "--output" (".." </> out)
"public/**/*" %> \out ->
copyFileChanged (replaceDirectory1 out "styleguide-app") out
"log/public.txt" %> \out -> do
styleguideAssets <- getDirectoryFiles ("styleguide-app" </> "assets") ["**/*"]
need
( ["public/index.html", "public/elm.js", "public/bundle.js"]
++ map (("public" </> "assets") </>) styleguideAssets
)
writeFileChanged out "built styleguide 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"