module Distribution.Fedora.Branch
( Branch(..)
, readBranch
, showBranch
, eitherBranch
, readActiveBranch
, eitherActiveBranch
, newerBranch
, getActiveBranches
, getActiveBranched
, getLatestFedoraBranch
, branchDestTag
, branchDistTag
, branchRelease
, partitionBranches
)
where
import Data.Char (isDigit)
import Data.Either (partitionEithers)
import Data.List.Extra (delete, elemIndex, replace, sortBy)
import Data.Maybe (mapMaybe)
import Data.Ord (comparing, Down(Down))
import Data.Tuple (swap)
import Safe (headDef)
import Distribution.Fedora.Release
data Branch = EPEL !Int | EPELNext !Int | Fedora !Int | Rawhide
deriving (Branch -> Branch -> Bool
(Branch -> Branch -> Bool)
-> (Branch -> Branch -> Bool) -> Eq Branch
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Branch -> Branch -> Bool
== :: Branch -> Branch -> Bool
$c/= :: Branch -> Branch -> Bool
/= :: Branch -> Branch -> Bool
Eq)
instance Ord Branch where
compare :: Branch -> Branch -> Ordering
compare Branch
Rawhide Branch
Rawhide = Ordering
EQ
compare (Fedora Int
m) (Fedora Int
n) = Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
m Int
n
compare (EPELNext Int
m) (EPELNext Int
n) = Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
m Int
n
compare (EPEL Int
m) (EPEL Int
n) = Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
m Int
n
compare Branch
Rawhide Branch
_ = Ordering
GT
compare Branch
_ Branch
Rawhide = Ordering
LT
compare (Fedora Int
_) Branch
_ = Ordering
GT
compare Branch
_ (Fedora Int
_) = Ordering
LT
compare (EPEL Int
m) (EPELNext Int
n) = if Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n then Ordering
LT else Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
m Int
n
compare (EPELNext Int
m) (EPEL Int
n) = if Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n then Ordering
GT else Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
m Int
n
eitherBranch :: String -> Either String Branch
eitherBranch :: String -> Either String Branch
eitherBranch String
"rawhide" = Branch -> Either String Branch
forall a b. b -> Either a b
Right Branch
Rawhide
eitherBranch (Char
'f':String
ns) | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit String
ns = let br :: Branch
br = Int -> Branch
Fedora (String -> Int
forall a. Read a => String -> a
read String
ns) in Branch -> Either String Branch
forall a b. b -> Either a b
Right Branch
br
eitherBranch String
"epel8-next" = Branch -> Either String Branch
forall a b. b -> Either a b
Right (Branch -> Either String Branch) -> Branch -> Either String Branch
forall a b. (a -> b) -> a -> b
$ Int -> Branch
EPELNext Int
8
eitherBranch String
"epel9-next" = Branch -> Either String Branch
forall a b. b -> Either a b
Right (Branch -> Either String Branch) -> Branch -> Either String Branch
forall a b. (a -> b) -> a -> b
$ Int -> Branch
EPELNext Int
9
eitherBranch (Char
'e':Char
'p':Char
'e':Char
'l':String
n) | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit String
n = let br :: Branch
br = Int -> Branch
EPEL (String -> Int
forall a. Read a => String -> a
read String
n) in Branch -> Either String Branch
forall a b. b -> Either a b
Right Branch
br
eitherBranch (Char
'e':Char
'l':String
n) | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit String
n = let br :: Branch
br = Int -> Branch
EPEL (String -> Int
forall a. Read a => String -> a
read String
n) in Branch -> Either String Branch
forall a b. b -> Either a b
Right Branch
br
eitherBranch String
cs = String -> Either String Branch
forall a b. a -> Either a b
Left String
cs
readBranch :: String -> Maybe Branch
readBranch :: String -> Maybe Branch
readBranch String
bs =
case String -> Either String Branch
eitherBranch String
bs of
Left String
_ -> Maybe Branch
forall a. Maybe a
Nothing
Right Branch
br -> Branch -> Maybe Branch
forall a. a -> Maybe a
Just Branch
br
eitherActiveBranch :: [Branch] -> String -> Either String Branch
eitherActiveBranch :: [Branch] -> String -> Either String Branch
eitherActiveBranch [Branch]
active String
bs =
case String -> Either String Branch
eitherBranch String
bs of
Left String
e -> String -> Either String Branch
forall a b. a -> Either a b
Left String
e
Right Branch
br -> if Branch
br Branch -> [Branch] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Branch]
active
then Branch -> Either String Branch
forall a b. b -> Either a b
Right Branch
br
else String -> Either String Branch
forall a b. a -> Either a b
Left String
bs
readActiveBranch :: [Branch] -> String -> Maybe Branch
readActiveBranch :: [Branch] -> String -> Maybe Branch
readActiveBranch [Branch]
active String
cs =
case [Branch] -> String -> Either String Branch
eitherActiveBranch [Branch]
active String
cs of
Left String
_ -> Maybe Branch
forall a. Maybe a
Nothing
Right Branch
br -> Branch -> Maybe Branch
forall a. a -> Maybe a
Just Branch
br
showBranch :: Branch -> String
showBranch :: Branch -> String
showBranch Branch
Rawhide = String
"rawhide"
showBranch (Fedora Int
n) = String
"f" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
showBranch (EPEL Int
n) = (if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
6 then String
"el" else String
"epel") String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
showBranch (EPELNext Int
n) = String
"epel" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-next"
branchRelease :: Branch -> IO Release
branchRelease :: Branch -> IO Release
branchRelease = String -> IO Release
getBranchRelease (String -> IO Release)
-> (Branch -> String) -> Branch -> IO Release
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Branch -> String
showBranch
branchDestTag :: Branch -> IO String
branchDestTag :: Branch -> IO String
branchDestTag Branch
br = Release -> String
releaseCandidateTag (Release -> String) -> IO Release -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Branch -> IO Release
branchRelease Branch
br
branchDistTag :: Branch -> IO String
branchDistTag :: Branch -> IO String
branchDistTag Branch
br = do
String
dist <- Release -> String
releaseDistTag (Release -> String) -> IO Release -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Branch -> IO Release
branchRelease Branch
br
String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$ Char
'.' Char -> String -> String
forall a. a -> [a] -> [a]
: (Branch -> String -> String
distroFix Branch
br (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String -> String
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace String
"." String
"_") String
dist
where
distroFix :: Branch -> String -> String
distroFix (EPEL Int
_) = String -> String -> String -> String
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace String
"epel" String
"el"
distroFix Branch
_ = String -> String -> String -> String
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace String
"f" String
"fc"
newerBranch :: Branch -> [Branch] -> Maybe Branch
newerBranch :: Branch -> [Branch] -> Maybe Branch
newerBranch Branch
Rawhide [Branch]
_ = Maybe Branch
forall a. Maybe a
Nothing
newerBranch Branch
br [Branch]
branches =
case Branch -> [Branch] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex Branch
br [Branch]
branches of
Just Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 -> Branch -> Maybe Branch
forall a. a -> Maybe a
Just (Branch -> Maybe Branch) -> Branch -> Maybe Branch
forall a b. (a -> b) -> a -> b
$ [Branch]
branches [Branch] -> Int -> Branch
forall a. HasCallStack => [a] -> Int -> a
!! (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
Maybe Int
_ -> Maybe Branch
forall a. Maybe a
Nothing
getActiveBranches :: IO [Branch]
getActiveBranches :: IO [Branch]
getActiveBranches =
[Branch] -> [Branch]
forall a. Ord a => [a] -> [a]
reverseSort ([Branch] -> [Branch])
-> ([Release] -> [Branch]) -> [Release] -> [Branch]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Release -> Maybe Branch) -> [Release] -> [Branch]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (String -> Maybe Branch
readBranch (String -> Maybe Branch)
-> (Release -> String) -> Release -> Maybe Branch
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Release -> String
releaseBranch) ([Release] -> [Branch]) -> IO [Release] -> IO [Branch]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO [Release]
getActiveReleases
getActiveBranched :: IO [Branch]
getActiveBranched :: IO [Branch]
getActiveBranched = Branch -> [Branch] -> [Branch]
forall a. Eq a => a -> [a] -> [a]
delete Branch
Rawhide ([Branch] -> [Branch]) -> IO [Branch] -> IO [Branch]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO [Branch]
getActiveBranches
error' :: String -> a
error' :: forall a. String -> a
error' = String -> a
forall a. String -> a
errorWithoutStackTrace
partitionBranches :: [String] -> ([Branch],[String])
partitionBranches :: [String] -> ([Branch], [String])
partitionBranches [String]
args =
([String], [Branch]) -> ([Branch], [String])
forall a b. (a, b) -> (b, a)
swap (([String], [Branch]) -> ([Branch], [String]))
-> ([Either String Branch] -> ([String], [Branch]))
-> [Either String Branch]
-> ([Branch], [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Either String Branch] -> ([String], [Branch])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either String Branch] -> ([Branch], [String]))
-> [Either String Branch] -> ([Branch], [String])
forall a b. (a -> b) -> a -> b
$ (String -> Either String Branch)
-> [String] -> [Either String Branch]
forall a b. (a -> b) -> [a] -> [b]
map String -> Either String Branch
eitherBranch [String]
args
getLatestFedoraBranch :: IO Branch
getLatestFedoraBranch :: IO Branch
getLatestFedoraBranch =
Branch -> [Branch] -> Branch
forall a. a -> [a] -> a
headDef (String -> Branch
forall a. String -> a
error' String
"no active branched!") ([Branch] -> Branch) -> IO [Branch] -> IO Branch
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO [Branch]
getActiveBranched
reverseSort :: Ord a => [a] -> [a]
reverseSort :: forall a. Ord a => [a] -> [a]
reverseSort = (a -> a -> Ordering) -> [a] -> [a]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((a -> Down a) -> a -> a -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing a -> Down a
forall a. a -> Down a
Down)