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, spanEnd)
import Data.Maybe (mapMaybe)
import Data.Ord (comparing, Down(Down))
import Data.Tuple (swap)
import Numeric.Natural (Natural)
import Safe (headDef, readMay)
import Distribution.Fedora.Release
data Branch = EPELMinor !Natural !Natural | EPEL !Natural | EPELNext !Natural | Fedora !Natural | 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 Natural
m) (Fedora Natural
n) = Natural -> Natural -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Natural
m Natural
n
compare (EPELNext Natural
m) (EPELNext Natural
n) = Natural -> Natural -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Natural
m Natural
n
compare (EPEL Natural
m) (EPEL Natural
n) = Natural -> Natural -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Natural
m Natural
n
compare (EPELMinor Natural
m1 Natural
n1) (EPELMinor Natural
m2 Natural
n2) =
case Natural -> Natural -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Natural
m1 Natural
m2 of
Ordering
LT -> Ordering
LT
Ordering
GT -> Ordering
GT
Ordering
EQ -> Natural -> Natural -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Natural
n1 Natural
n2
compare Branch
Rawhide Branch
_ = Ordering
GT
compare Branch
_ Branch
Rawhide = Ordering
LT
compare (Fedora Natural
_) Branch
_ = Ordering
GT
compare Branch
_ (Fedora Natural
_) = Ordering
LT
compare (EPEL Natural
m) (EPELNext Natural
n) = if Natural
m Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
n then Ordering
LT else Natural -> Natural -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Natural
m Natural
n
compare (EPELNext Natural
m) (EPEL Natural
n) = if Natural
m Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
n then Ordering
GT else Natural -> Natural -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Natural
m Natural
n
compare (EPEL Natural
m) (EPELMinor Natural
maj Natural
_) = if Natural
m Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
>= Natural
maj then Ordering
GT else Ordering
LT
compare (EPELMinor Natural
maj Natural
_) (EPEL Natural
n) = if Natural
maj Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
<= Natural
n then Ordering
LT else Ordering
GT
compare (EPELMinor Natural
_ Natural
_) (EPELNext Natural
_) = Ordering
GT
compare (EPELNext Natural
_) (EPELMinor Natural
_ Natural
_) = Ordering
LT
eitherBranch :: String -> Either String Branch
eitherBranch :: String -> Either String Branch
eitherBranch String
str =
case String
str of
String
"" -> String -> Either String Branch
forall a b. a -> Either a b
Left String
str
String
"rawhide" -> Branch -> Either String Branch
forall a b. b -> Either a b
Right Branch
Rawhide
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
$ Natural -> Branch
EPELNext Natural
8
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
$ Natural -> Branch
EPELNext Natural
9
String
_ ->
case (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
spanEnd Char -> Bool
isDigit String
str of
(String
pre,String
ns) ->
case String -> Maybe Natural
forall a. Read a => String -> Maybe a
readMay String
ns of
Maybe Natural
Nothing -> String -> Either String Branch
forall a b. a -> Either a b
Left String
str
Just Natural
num ->
case String
pre of
String
"f" -> 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
$ Natural -> Branch
Fedora Natural
num
String
"epel" -> 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
$ Natural -> Branch
EPEL Natural
num
String
"epel10." -> 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
$ Natural -> Natural -> Branch
EPELMinor Natural
10 Natural
num
String
"el" -> 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
$ Natural -> Branch
EPEL Natural
num
String
_ -> String -> Either String Branch
forall a b. a -> Either a b
Left String
str
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 Natural
n) = String
"f" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Natural -> String
forall a. Show a => a -> String
show Natural
n
showBranch (EPEL Natural
n) = (if Natural
n Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
<= Natural
6 then String
"el" else String
"epel") String -> String -> String
forall a. [a] -> [a] -> [a]
++ Natural -> String
forall a. Show a => a -> String
show Natural
n
showBranch (EPELNext Natural
n) = String
"epel" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Natural -> String
forall a. Show a => a -> String
show Natural
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-next"
showBranch (EPELMinor Natural
m Natural
n) = String
"epel" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Natural -> String
forall a. Show a => a -> String
show Natural
m String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char
'.' Char -> String -> String
forall a. a -> [a] -> [a]
: Natural -> String
forall a. Show a => a -> String
show Natural
n
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 Natural
_) = String -> String -> String -> String
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace String
"epel" String
"el"
distroFix (EPELNext Natural
_) = String -> String -> String -> String
forall a. Eq a => [a] -> [a] -> [a] -> [a]
replace String
"epel" String
"el"
distroFix (EPELMinor Natural
_ Natural
_) = 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)