Skip to content
This repository has been archived by the owner on Feb 3, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/vlatkoB/stackage-curator
Browse files Browse the repository at this point in the history
…into vlatkoB-master
  • Loading branch information
snoyberg committed Jul 28, 2015
2 parents 06fe259 + eaab2fb commit bf8006e
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 59 deletions.
163 changes: 129 additions & 34 deletions Stackage/DiffPlans.hs
Original file line number Diff line number Diff line change
@@ -1,66 +1,161 @@
{-# LANGUAGE OverloadedStrings, NoImplicitPrelude #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleContexts, GADTs, NoImplicitPrelude, OverloadedStrings,
ScopedTypeVariables #-}
module Stackage.DiffPlans
( diffPlans
) where

import Stackage.Prelude
import Data.Yaml (decodeFileEither)
import Data.Map (filterWithKey)
import Data.Text (Text, justifyLeft)
import qualified Data.Text as T
import Data.Yaml (decodeFileEither)
import qualified Distribution.Text as DT
import Network.HTTP.Client
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Stackage.Prelude

import Data.Maybe
import Lucid
import System.Directory

data Change = Added | Deleted | MajorBump | MinorBump | Unchanged
deriving (Show, Eq, Ord)

data AndOr a = Old a | New a | Both a a
deriving Show
instance Semigroup (AndOr a) where
Old x <> New y = Both x y
New y <> Old x = Both x y
Old x <> Old _ = Old x
New x <> New _ = New x
Both x y <> _ = Both x y
Old x <> New y = Both x y
New y <> Old x = Both x y
Old x <> Old _ = Old x
New x <> New _ = New x
Both x y <> _ = Both x y

type DiffMap = Map Change (Map PackageName (Text,Maybe Text))

diffPlans :: FilePath -- ^ old YAML build plan file
-> FilePath -- ^ new YAML build plan file
-> Bool -- ^ show just changed packages
-> Bool -- ^ use colours
-> Bool -- ^ fetch YAML files from GitHub repo
-> Bool -- ^ wrap output in HTML
-> IO ()
diffPlans oldFP newFP = do
diffPlans oldFP newFP diffsOnly useColor True asHtml = do
(oldFP', newFP') <- (,) <$> getLTS (fpToString oldFP) <*> getLTS (fpToString newFP)
diffPlans oldFP' newFP' diffsOnly useColor False asHtml
delFile $ fpToString oldFP'
delFile $ fpToString newFP'

where
delFile fp = removeFile fp `catch` \(_::SomeException) -> return ()

diffPlans oldFP newFP diffsOnly useColor False asHtml = do
old <- fmap Old <$> parse oldFP
new <- fmap New <$> parse newFP
let combined = unionWith (<>) old new
m :: Map Change (Map PackageName Text)
m = unionsWith mappend $ map go $ mapToList combined
m :: DiffMap
m = f . unionsWith mappend . map go $ mapToList combined
f = if diffsOnly
then filterWithKey (\k _ -> k /= Unchanged)
else id

forM_ (mapToList m) $ \(change, m') -> do
print change
forM_ (mapToList m') $ \(pkg, msg) -> do
putStrLn $ concat
[ display pkg
, ": "
, msg
]
putStrLn ""
if asHtml
then print $ htmlOut True m
else consoleOut useColor m
where
parse fp = decodeFileEither (fpToString fp)
>>= either throwIO (return . toSimple)

toSimple = fmap ppVersion . bpPackages

go (name, Old x) = singletonMap Deleted $ singletonMap name $ display x
go (name, New x) = singletonMap Added $ singletonMap name $ display x
go (name, Old x) = singletonMap Deleted $ singletonMap name (display x, Nothing)
go (name, New x) = singletonMap Added $ singletonMap name (display x, Nothing)
go (name, Both x y)
| x == y = singletonMap Unchanged $ singletonMap name $ display x
| otherwise = singletonMap
(if isMajor x y then MajorBump else MinorBump)
(singletonMap name (concat
[ display x
, " ==> "
, display y
]))
| x == y = singletonMap Unchanged $ singletonMap name (display x, Nothing)
| otherwise = singletonMap
(if isMajor x y then MajorBump else MinorBump)
(singletonMap name $ (display x, Just $ display y))

isMajor :: Version -> Version -> Bool
isMajor (Version old _) (Version new _) =
toPair old /= toPair new
where
toPair [] = (0, 0)
toPair [i] = (i, 0)
toPair [] = (0, 0)
toPair [i] = (i, 0)
toPair (i:j:_) = (i, j)


-- | Download LTS file from GitHub to TMP dir
-- LTS should not contain extension nor path, i.e. just "lts-2.19"
getLTS :: String -> IO FilePath
getLTS lts = do
createDirectoryIfMissing True tmpDir
withManager tlsManagerSettings $ \man -> do
req <- parseUrl $ ltsRepo <> lts <> ".yaml"
res <- httpLbs req man
writeFile fName $ responseBody res
return fName
where
fName = fpFromString $ tmpDir <> lts <> ".yaml"
ltsRepo = "https://raw.githubusercontent.com/fpco/lts-haskell/master/"
tmpDir = "/tmp/stackage-curator/"


-- | Return coloured string, or html colour style, depending on *change* param
colorize :: Bool -> Change -> Text -> Text
colorize useHtml change s =
case change of
Deleted -> red s
Added -> green s
Unchanged -> s
MajorBump -> yellow s
MinorBump -> blue s
where
showInColor consCol htmlColor s
| useHtml = "color: " <> htmlColor
| otherwise = "\ESC[" <> consCol <> "m" <> s <> "\ESC[0m"

black = showInColor "30" "black"
red = showInColor "31" "red"
green = showInColor "32" "green"
yellow = showInColor "33" "yellow"
blue = showInColor "34" "blue"
magenta = showInColor "35" "magenta"
cyan = showInColor "36" "cyan"
white = showInColor "37" "white"


-- | Display to console
consoleOut :: Bool -> DiffMap -> IO ()
consoleOut useColor m =
forM_ (mapToList m) $ \(change, m') -> do
print change
forM_ (mapToList m') $ \(pkg, (x,y)) ->
let pkgName = (if useColor then colorize False change else id)
$ justifyLeft 25 ' ' $ display pkg
in putStrLn $ pkgName <>
justifyLeft 9 ' ' x <>
if isJust y
then " => " <> fromJust y
else ""
putStrLn ""


-- | Display as HTML. If fullPage is True, display as complete page
htmlOut :: Bool -> DiffMap -> Html ()
htmlOut fullPage m = do
when fullPage $
doctypehtml_$ head_ $ do
meta_ [charset_ "utf-8"]
style_ "table, th, td {border : 1px solid black; border-collapse: collapse;}\
\th, td {padding: 5px; text-align: left;}"
body_ $
div_ [class_ "ltsDiffs"] $ do
h3_ "Differences"
forM_ (mapToList m) $ \(change, m') -> do
p_ [style_ $ colorize True change ""] $ toHtml $ show change
table_ $ forM_ (mapToList m') $ \(pkg, (x,y)) ->
tr_ $ do
td_ $ toHtml $ display pkg
td_ $ toHtml $ x
when (isJust y) $
td_ $ toHtml $ fromJust y
br_ []
70 changes: 45 additions & 25 deletions app/stackage.hs
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE NoImplicitPrelude, TemplateHaskell, TupleSections #-}

module Main where

import Control.Monad
import Data.String (fromString)
import Data.Text (pack, stripPrefix)
import qualified Data.Text as T
import Data.Text.Read (decimal)
import Data.Version
import Filesystem.Path.CurrentOS (decodeString)
import Network.HTTP.Client (withManager)
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Options.Applicative
import Paths_stackage_curator (version)
import qualified Prelude
import Control.Monad
import Data.String (fromString)
import Data.Version
import Data.Text (pack, stripPrefix)
import Data.Text.Read (decimal)
import Options.Applicative
import Filesystem.Path.CurrentOS (decodeString)
import Paths_stackage_curator (version)
import Stackage.CLI
import Stackage.CompleteBuild
import Stackage.DiffPlans
import Stackage.Upload
import Stackage.Update
import Stackage.InstallBuild
import Stackage.Prelude hiding ((<>))
import Stackage.Stats
import Network.HTTP.Client (withManager)
import Network.HTTP.Client.TLS (tlsManagerSettings)
import qualified Data.Text as T
import System.IO (hSetBuffering, stdout, BufferMode (LineBuffering))
import Stackage.Curator.UploadIndex
import Stackage.CLI
import Stackage.CompleteBuild
import Stackage.Curator.UploadIndex
import Stackage.DiffPlans
import Stackage.InstallBuild
import Stackage.Prelude hiding ((<>))
import Stackage.Stats
import Stackage.Update
import Stackage.Upload
import System.IO (BufferMode (LineBuffering), hSetBuffering,
stdout)

main :: IO ()
main = do
Expand Down Expand Up @@ -65,7 +64,8 @@ main = do
addCommand "stats" "Print statistics on a build plan" id
(printStats <$> planFile)
addCommand "diff" "Show the high-level differences between two build plans" id
(diffPlans <$> planFileArg <*> planFileArg)
(diffPlans <$> planFileArg <*> planFileArg
<*> diffsOnly <*> useColor <*> githubFetch <*> html)
addCommand "upload-index" "Upload the 00-index.tar.gz file to S3" id
(uploadIndex
<$> planFile
Expand Down Expand Up @@ -262,3 +262,23 @@ main = do
case simpleParse $ T.pack s of
Nothing -> fail $ "Invalid constraint: " ++ s
Just d -> return d

diffsOnly =
switch
(long "diffsOnly" <> short 'd' <>
help "Show changed packages only")

useColor =
switch
(long "useColor" <> short 'c' <>
help "Show differences in color")

githubFetch =
switch
(long "githubFetch" <> short 'g' <>
help "Fetch YAML files from GitHub")

html =
switch
(long "html" <> short 'h' <>
help "Wrap the output in HTML <ul>/<li> tags")
1 change: 1 addition & 0 deletions stackage-curator.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ library
, resourcet
, stackage-metadata >= 0.3
, stackage-install >= 0.1.1
, lucid

executable stackage-curator
default-language: Haskell2010
Expand Down

0 comments on commit bf8006e

Please sign in to comment.