1{-# LANGUAGE OverloadedStrings #-}
2import Control.Monad (filterM, when)
3import qualified Data.ByteString.Char8 as S8
4import qualified Data.ByteString.Lazy as L
5import Data.List (isInfixOf, isPrefixOf,
7import Network.HTTP.Client
8import Network.HTTP.Client.MultipartFormData
9import System.Directory (doesDirectoryExist,
11import System.Environment (getArgs, getEnv,
13import System.Exit (exitFailure)
14import System.Exit (ExitCode (ExitSuccess))
15import System.FilePath (takeDirectory, (</>))
16import System.Process (createProcess, cwd,
20main = withManager defaultManagerSettings $ \m -> do
22 token <- readFile "/auth-token"
25 [x, y] -> return (x, y)
31 , " <filepath> <alias name>"
35 let uploadDocs = "exclusive" `isInfixOf` alias
36 uploadHackageDistro = alias == "unstable-ghc78-exclusive"
45 req1 <- parseUrl "http://www.stackage.org/upload"
47 [ partBS "alias" $ S8.pack alias
48 , partFileSource "stackage" filepath
50 req2 <- formDataBody formData req1
54 [ ("Authorization", S8.pack token)
55 , ("Accept", "application/json")
56 ] ++ requestHeaders req2
58 , checkStatus = \_ _ _ -> Nothing
63 case lookup "x-stackage-ident" $ responseHeaders res of
65 putStrLn $ "New ident: " ++ S8.unpack snapid
67 Nothing -> error $ "An error occurred: " ++ show res
70 putStrLn "Generating index file"
71 let root = takeDirectory filepath </> "haddock"
72 contents <- getDirectoryContents root
73 dirs <- filterM (\n -> doesDirectoryExist $ root </> n)
74 $ filter (not . ("." `isPrefixOf`))
76 writeFile (root </> "index.html") $ mkIndex (S8.unpack snapid) dirs
77 writeFile (root </> "style.css") styleCss
79 putStrLn "Creating tarball"
80 (Nothing, Nothing, Nothing, ph) <- createProcess
81 (proc "tar" $ "cJf" : "haddock.tar.xz" : "index.html" : "style.css" : dirs)
84 ec <- waitForProcess ph
86 then putStrLn "Haddock tarball generated"
87 else error "Error generating Haddock tarball"
89 putStrLn "Uploading Haddocks"
91 req1 <- parseUrl $ "http://www.stackage.org/upload-haddock/"
94 [ partFileSource "tarball" $ root </> "haddock.tar.xz"
96 req2 <- formDataBody formData req1
100 [ ("Authorization", S8.pack token)
101 , ("Accept", "application/json")
102 ] ++ requestHeaders req2
104 , checkStatus = \_ _ _ -> Nothing
106 httpLbs req3 m >>= print
108 when uploadHackageDistro $ do
109 lbs <- L.readFile $ takeDirectory filepath </> "build-plan.csv"
110 let req = "http://hackage.haskell.org/distro/Stackage/packages.csv"
111 { requestHeaders = [("Content-Type", "text/csv")]
112 , requestBody = RequestBodyLBS lbs
113 , checkStatus = \_ _ _ -> Nothing
115 httpLbs req m >>= print
117mkIndex :: String -> [String] -> String
118mkIndex snapid dirs = concat
119 [ "<!DOCTYPE html>\n<html lang='en'><head><title>Haddocks index</title>"
120 , "<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'>"
121 , "<link rel='stylesheet' href='style.css'>"
122 , "<link rel='shortcut icon' href='http://www.stackage.org/static/img/favicon.ico' />"
124 , "<body><div class='container'>"
125 , "<div class='row'><div class='span12 col-md-12'>"
126 , "<h1>Haddock documentation index</h1>"
127 , "<p class='return'><a href=\"http://www.stackage.org/stackage/"
129 , "\">Return to snapshot</a></p><ul>"
130 , concatMap toLI dirs
131 , "</ul></div></div></div></body></html>"
144 [ "@media (min-width: 530px) {"
145 , "ul { -webkit-column-count: 2; -moz-column-count: 2; column-count: 2 }"
147 , "@media (min-width: 760px) {"
148 , "ul { -webkit-column-count: 3; -moz-column-count: 3; column-count: 3 }"
152 , " padding-left: 0;"
153 , " list-style-type: none;"
156 , " background: #f0f0f0;"
157 , " font-family: 'Lato', sans-serif;"
158 , " text-shadow: 1px 1px 1px #ffffff;"
159 , " font-size: 20px;"
160 , " line-height: 30px;"
161 , " padding-bottom: 5em;"
164 , " font-weight: normal;"
166 , " font-size: 45px;"
170 , " font-style: italic;"
173 , " margin-bottom: 1em;"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list