Skip to content

Instantly share code, notes, and snippets.

@denisshevchenko
Created February 12, 2015 21:06
Show Gist options
  • Save denisshevchenko/ec011820a5d19b73172e to your computer and use it in GitHub Desktop.
Save denisshevchenko/ec011820a5d19b73172e to your computer and use it in GitHub Desktop.
CompileFayModules.hs
{-
Модуль, предназначенный для компиляции Fay-модулей в единый .js-скрипт.
ВНИМАНИЕ! Данный модуль не является частью основного проекта, это независимый Haskell-скрипт.
Поэтому он должен запускаться отдельно, из корня репозитория:
$ runhaskell templates/FayHelpers/CompileFayModules.hs
Результатом работы этого скрипта будет файл static/js/FayModules.js, подключаемый основным проектом.
-}
module Main where
import Fay (compileFile)
import Fay.Config
import Data.List hiding (find)
import System.Process
import System.Exit
import System.FilePath.Posix
import System.FilePath.Find
import System.Directory (removeFile, renameFile)
import Control.Monad (mapM)
main :: IO ()
main = do
pathsToAllFayModules <- find always (extension ==? ".hs") "templates"
rawScripts <- mapM compileOneFayModule [path | path <- pathsToAllFayModules, notFromHelpers path]
writeFile pathToSingleFayJSRaw $ concat rawScripts
optimizeRawJS
removeFile pathToSingleFayJSRaw
putStrLn "It's done."
pathToSingleFayJSRaw :: FilePath
pathToSingleFayJSRaw = "static/js/FayModulesRaw.js"
pathToSingleFayJSOptimized :: FilePath
pathToSingleFayJSOptimized = "static/js/FayModules.js"
-- Fay-модули-помощники не должны компилироваться отдельно,
-- потому что они импортируются в другие Fay-модули.
notFromHelpers :: FilePath -> Bool
notFromHelpers pathToFayModule = not $ "/FayHelpers/" `isInfixOf` pathToFayModule
compileOneFayModule :: FilePath -> IO String
compileOneFayModule pathToFayModule =
compileFile (createConfigBasedOn pathToFayModule) pathToFayModule >>= \result ->
case result of
Left anError -> do putStrLn $ "Cannot compile Fay module '" ++ pathToFayModule ++ "': " ++ show anError
exitWith $ ExitFailure 1
Right script -> return $ script ++ "\n"
createConfigBasedOn :: FilePath -> Config
createConfigBasedOn pathToFayModule =
let includePathsWithModuleDirectory = takeDirectory pathToFayModule : ["templates/FayHelpers"]
configWithIncludes = addConfigDirectoryIncludePaths includePathsWithModuleDirectory
defaultConfig
configWithFayPackages = addConfigPackages ["fay-jquery", "fay-text", "fay-base"]
configWithIncludes
in configWithFayPackages
optimizeRawJS :: IO ()
optimizeRawJS = do
closureCompilerExists <- system "which closure-compiler > /dev/null"
if closureCompilerExists == ExitSuccess
then do
optimized <- system $ "closure-compiler --compilation_level SIMPLE --js_output_file "
++ pathToSingleFayJSOptimized
++ " "
++ pathToSingleFayJSRaw
++ " 2> /dev/null"
if optimized == ExitSuccess
then return ()
else do putStrLn $ "Fay module compiled, but optimization fault!"
exitWith $ ExitFailure 1
else
-- Google Closure Compiler отсутствует, переименовываем сырой файл
-- в конечный, который будет использоваться проектом "как есть".
renameFile pathToSingleFayJSRaw pathToSingleFayJSOptimized
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment