{-# LANGUAGE RecordWildCards, CPP, ViewPatterns, ForeignFunctionInterface, TupleSections #-}-- | Progress trackingmoduleDevelopment.Shake.Internal.Progress(progress ,progressSimple ,progressDisplay ,progressTitlebar ,progressProgram ,ProgressEntry (..),progressReplay ,writeProgressReport -- INTERNAL USE ONLY)whereimportControl.ApplicativeimportData.Tuple.ExtraimportControl.Exception.ExtraimportControl.Monad.ExtraimportSystem.DirectoryimportSystem.ProcessimportSystem.FilePathimportData.CharimportData.IORefimportData.ListimportData.MaybeimportDevelopment.Shake.Internal.Options importDevelopment.Shake.Internal.Core.Types importDevelopment.Shake.Internal.Core.Database importqualifiedData.ByteString.Char8asBSimportqualifiedData.ByteString.Lazy.Char8asLBSimportNumeric.ExtraimportGeneral.Template importGeneral.EscCodes importGeneral.Extra importDevelopment.Shake.Internal.Paths importSystem.Time.Extra
#ifdef mingw32_HOST_OS
importForeign.C.String
#ifdef x86_64_HOST_ARCH
#define CALLCONV ccall
#else
#define CALLCONV stdcall
#endif
foreignimportCALLCONV"Windows.h SetConsoleTitleW"c_setConsoleTitleW::CWString->IOBool
#endif
----------------------------------------------------------------------- PROGRESSprogress ::Database ->Step ->IOProgress progress :: Database -> Step -> IO Progress
progress Database
db Step
step =do[(Key, Status)]
xs <-Database -> IO [(Key, Status)]
forall k v. DatabasePoly k v -> IO [(k, v)]
getKeyValues Database
db Progress -> IO Progress
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Progress -> IO Progress) -> Progress -> IO Progress
forall a b. (a -> b) -> a -> b
$!(Progress -> Status -> Progress)
-> Progress -> [Status] -> Progress
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'Progress -> Status -> Progress
f Progress
forall a. Monoid a => a
mempty([Status] -> Progress) -> [Status] -> Progress
forall a b. (a -> b) -> a -> b
$((Key, Status) -> Status) -> [(Key, Status)] -> [Status]
forall a b. (a -> b) -> [a] -> [b]
map(Key, Status) -> Status
forall a b. (a, b) -> b
snd[(Key, Status)]
xs whereg :: Float -> Double
g =Float -> Double
floatToDoublef :: Progress -> Status -> Progress
f Progress
s (Ready Result {Float
[Depends]
[Trace]
(Value, OneShot BS_Store)
Step
result :: (Value, OneShot BS_Store)
built :: Step
changed :: Step
depends :: [Depends]
execution :: Float
traces :: [Trace]
result :: forall a. Result a -> a
built :: forall a. Result a -> Step
changed :: forall a. Result a -> Step
depends :: forall a. Result a -> [Depends]
execution :: forall a. Result a -> Float
traces :: forall a. Result a -> [Trace]
.. })=ifStep
step Step -> Step -> Bool
forall a. Eq a => a -> a -> Bool
==Step
built thenProgress
s {countBuilt =countBuilt s +1,timeBuilt =timeBuilt s +g execution }elseProgress
s {countSkipped =countSkipped s +1,timeSkipped =timeSkipped s +g execution }f Progress
s (Loaded Result {Float
[Depends]
[Trace]
OneShot BS_Store
Step
result :: forall a. Result a -> a
built :: forall a. Result a -> Step
changed :: forall a. Result a -> Step
depends :: forall a. Result a -> [Depends]
execution :: forall a. Result a -> Float
traces :: forall a. Result a -> [Trace]
result :: OneShot BS_Store
built :: Step
changed :: Step
depends :: [Depends]
execution :: Float
traces :: [Trace]
.. })=Progress
s {countUnknown =countUnknown s +1,timeUnknown =timeUnknown s +g execution }f Progress
s (Running NoShow
 (Either SomeException (Result (Value, OneShot BS_Store))
 -> Locked ())
_Maybe (Result (OneShot BS_Store))
r )=let(Double
d ,Int
c )=Progress -> (Double, Int)
timeTodo Progress
s t :: (Double, Int)
t |JustResult {Float
[Depends]
[Trace]
OneShot BS_Store
Step
result :: forall a. Result a -> a
built :: forall a. Result a -> Step
changed :: forall a. Result a -> Step
depends :: forall a. Result a -> [Depends]
execution :: forall a. Result a -> Float
traces :: forall a. Result a -> [Trace]
result :: OneShot BS_Store
built :: Step
changed :: Step
depends :: [Depends]
execution :: Float
traces :: [Trace]
.. }<-Maybe (Result (OneShot BS_Store))
r =letd2 :: Double
d2 =Double
d Double -> Double -> Double
forall a. Num a => a -> a -> a
+Float -> Double
g Float
execution inDouble
d2 Double -> (Double, Int) -> (Double, Int)
forall a b. a -> b -> b
`seq`(Double
d2 ,Int
c )|Bool
otherwise=letc2 :: Int
c2 =Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1inInt
c2 Int -> (Double, Int) -> (Double, Int)
forall a b. a -> b -> b
`seq`(Double
d ,Int
c2 )inProgress
s {countTodo =countTodo s +1,timeTodo =t }f Progress
s Status
_=Progress
s ----------------------------------------------------------------------- MEALY TYPE - for writing the progress functions-- See <https://hackage.haskell.org/package/machines-0.2.3.1/docs/Data-Machine-Mealy.html>-- | A machine that takes inputs and produces outputsnewtypeMealy i a =Mealy {forall i a. Mealy i a -> i -> (a, Mealy i a)
runMealy ::i ->(a ,Mealy i a )}instanceFunctor(Mealy i )wherefmap :: forall a b. (a -> b) -> Mealy i a -> Mealy i b
fmapa -> b
f (Mealy i -> (a, Mealy i a)
m )=(i -> (b, Mealy i b)) -> Mealy i b
forall i a. (i -> (a, Mealy i a)) -> Mealy i a
Mealy ((i -> (b, Mealy i b)) -> Mealy i b)
-> (i -> (b, Mealy i b)) -> Mealy i b
forall a b. (a -> b) -> a -> b
$\i
i ->casei -> (a, Mealy i a)
m i
i of(a
x ,Mealy i a
m )->(a -> b
f a
x ,(a -> b) -> Mealy i a -> Mealy i b
forall a b. (a -> b) -> Mealy i a -> Mealy i b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmapa -> b
f Mealy i a
m )instanceApplicative(Mealy i )wherepure :: forall a. a -> Mealy i a
purea
x =letr :: Mealy i a
r =(i -> (a, Mealy i a)) -> Mealy i a
forall i a. (i -> (a, Mealy i a)) -> Mealy i a
Mealy ((a, Mealy i a) -> i -> (a, Mealy i a)
forall a b. a -> b -> a
const(a
x ,Mealy i a
r ))inMealy i a
forall {i}. Mealy i a
r Mealy i -> (a -> b, Mealy i (a -> b))
mf <*> :: forall a b. Mealy i (a -> b) -> Mealy i a -> Mealy i b
<*>Mealy i -> (a, Mealy i a)
mx =(i -> (b, Mealy i b)) -> Mealy i b
forall i a. (i -> (a, Mealy i a)) -> Mealy i a
Mealy ((i -> (b, Mealy i b)) -> Mealy i b)
-> (i -> (b, Mealy i b)) -> Mealy i b
forall a b. (a -> b) -> a -> b
$\i
i ->casei -> (a -> b, Mealy i (a -> b))
mf i
i of(a -> b
f ,Mealy i (a -> b)
mf )->casei -> (a, Mealy i a)
mx i
i of(a
x ,Mealy i a
mx )->(a -> b
f a
x ,Mealy i (a -> b)
mf Mealy i (a -> b) -> Mealy i a -> Mealy i b
forall a b. Mealy i (a -> b) -> Mealy i a -> Mealy i b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Mealy i a
mx )echoMealy ::Mealy i i echoMealy :: forall i. Mealy i i
echoMealy =(i -> (i, Mealy i i)) -> Mealy i i
forall i a. (i -> (a, Mealy i a)) -> Mealy i a
Mealy (,Mealy i i
forall i. Mealy i i
echoMealy )scanMealy ::(a ->b ->a )->a ->Mealy i b ->Mealy i a scanMealy :: forall a b i. (a -> b -> a) -> a -> Mealy i b -> Mealy i a
scanMealy a -> b -> a
f a
z (Mealy i -> (b, Mealy i b)
m )=(i -> (a, Mealy i a)) -> Mealy i a
forall i a. (i -> (a, Mealy i a)) -> Mealy i a
Mealy ((i -> (a, Mealy i a)) -> Mealy i a)
-> (i -> (a, Mealy i a)) -> Mealy i a
forall a b. (a -> b) -> a -> b
$\i
i ->casei -> (b, Mealy i b)
m i
i of(b
x ,Mealy i b
m )->letz2 :: a
z2 =a -> b -> a
f a
z b
x in(a
z2 ,(a -> b -> a) -> a -> Mealy i b -> Mealy i a
forall a b i. (a -> b -> a) -> a -> Mealy i b -> Mealy i a
scanMealy a -> b -> a
f a
z2 Mealy i b
m )----------------------------------------------------------------------- MEALY UTILITIESoldMealy ::a ->Mealy i a ->Mealy i (a ,a )oldMealy :: forall a i. a -> Mealy i a -> Mealy i (a, a)
oldMealy a
old =((a, a) -> a -> (a, a)) -> (a, a) -> Mealy i a -> Mealy i (a, a)
forall a b i. (a -> b -> a) -> a -> Mealy i b -> Mealy i a
scanMealy (\(a
_,a
old )a
new ->(a
old ,a
new ))(a
old ,a
old )latch ::Mealy i (Bool,a )->Mealy i a latch :: forall i a. Mealy i (Bool, a) -> Mealy i a
latch Mealy i (Bool, a)
s =Maybe a -> a
forall a. Partial => Maybe a -> a
fromJust(Maybe a -> a) -> Mealy i (Maybe a) -> Mealy i a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>(Maybe a -> (Bool, a) -> Maybe a)
-> Maybe a -> Mealy i (Bool, a) -> Mealy i (Maybe a)
forall a b i. (a -> b -> a) -> a -> Mealy i b -> Mealy i a
scanMealy Maybe a -> (Bool, a) -> Maybe a
forall {a}. Maybe a -> (Bool, a) -> Maybe a
f Maybe a
forall a. Maybe a
NothingMealy i (Bool, a)
s wheref :: Maybe a -> (Bool, a) -> Maybe a
f Maybe a
old (Bool
b ,a
v )=a -> Maybe a
forall a. a -> Maybe a
Just(a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ifBool
b thena -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybea
v Maybe a
old elsea
v iff ::Mealy i Bool->Mealy i a ->Mealy i a ->Mealy i a iff :: forall i a. Mealy i Bool -> Mealy i a -> Mealy i a -> Mealy i a
iff Mealy i Bool
c Mealy i a
t Mealy i a
f =(\Bool
c a
t a
f ->ifBool
c thena
t elsea
f )(Bool -> a -> a -> a) -> Mealy i Bool -> Mealy i (a -> a -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy i Bool
c Mealy i (a -> a -> a) -> Mealy i a -> Mealy i (a -> a)
forall a b. Mealy i (a -> b) -> Mealy i a -> Mealy i b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Mealy i a
t Mealy i (a -> a) -> Mealy i a -> Mealy i a
forall a b. Mealy i (a -> b) -> Mealy i a -> Mealy i b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Mealy i a
f -- decay'd division, compute a/b, with a decay of f-- r' is the new result, r is the last result-- r' ~= a' / b'-- r' = r*b + f*(a'-a)-- --------------- b + f*(b'-b)-- when f == 1, r == r'---- both streams must only ever increasedecay ::Double->Mealy i Double->Mealy i Double->Mealy i Doubledecay :: forall i.
Double -> Mealy i Double -> Mealy i Double -> Mealy i Double
decay Double
f Mealy i Double
a Mealy i Double
b =(Double -> ((Double, Double), (Double, Double)) -> Double)
-> Double
-> Mealy i ((Double, Double), (Double, Double))
-> Mealy i Double
forall a b i. (a -> b -> a) -> a -> Mealy i b -> Mealy i a
scanMealy Double -> ((Double, Double), (Double, Double)) -> Double
step Double
0(Mealy i ((Double, Double), (Double, Double)) -> Mealy i Double)
-> Mealy i ((Double, Double), (Double, Double)) -> Mealy i Double
forall a b. (a -> b) -> a -> b
$(,)((Double, Double)
 -> (Double, Double) -> ((Double, Double), (Double, Double)))
-> Mealy i (Double, Double)
-> Mealy
 i ((Double, Double) -> ((Double, Double), (Double, Double)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Double -> Mealy i Double -> Mealy i (Double, Double)
forall a i. a -> Mealy i a -> Mealy i (a, a)
oldMealy Double
0Mealy i Double
a Mealy i ((Double, Double) -> ((Double, Double), (Double, Double)))
-> Mealy i (Double, Double)
-> Mealy i ((Double, Double), (Double, Double))
forall a b. Mealy i (a -> b) -> Mealy i a -> Mealy i b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Double -> Mealy i Double -> Mealy i (Double, Double)
forall a i. a -> Mealy i a -> Mealy i (a, a)
oldMealy Double
0Mealy i Double
b wherestep :: Double -> ((Double, Double), (Double, Double)) -> Double
step Double
r ((Double
a ,Double
a' ),(Double
b ,Double
b' ))=ifDouble -> Bool
forall a. RealFloat a => a -> Bool
isNaNDouble
r thenDouble
a' Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
b' else((Double
r Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
b )Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
f Double -> Double -> Double
forall a. Num a => a -> a -> a
*(Double
a' Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
a ))Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/(Double
b Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
f Double -> Double -> Double
forall a. Num a => a -> a -> a
*(Double
b' Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
b ))----------------------------------------------------------------------- MESSAGE GENERATORformatMessage ::Double->Double->StringformatMessage :: Double -> Double -> [Char]
formatMessage Double
secs Double
perc =(ifDouble -> Bool
forall a. RealFloat a => a -> Bool
isNaNDouble
secs Bool -> Bool -> Bool
||Double
secs Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<Double
0then[Char]
"??s"elseInt -> [Char]
showMinSec (Int -> [Char]) -> Int -> [Char]
forall a b. (a -> b) -> a -> b
$Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceilingDouble
secs )[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
" ("[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++(ifDouble -> Bool
forall a. RealFloat a => a -> Bool
isNaNDouble
perc Bool -> Bool -> Bool
||Double
perc Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<Double
0Bool -> Bool -> Bool
||Double
perc Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>Double
100then[Char]
"??"elseInteger -> [Char]
forall a. Show a => a -> [Char]
show(Integer -> [Char]) -> Integer -> [Char]
forall a b. (a -> b) -> a -> b
$Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
floorDouble
perc )[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"%)"showMinSec ::Int->StringshowMinSec :: Int -> [Char]
showMinSec Int
secs =(ifInt
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0then[Char]
""elseInt -> [Char]
forall a. Show a => a -> [Char]
showInt
m [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"m"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char
'0'|Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
10])[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Int -> [Char]
forall a. Show a => a -> [Char]
showInt
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"s"where(Int
m ,Int
s )=Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
divModInt
secs Int
60liftA2' ::Applicativem =>m a ->m b ->(a ->b ->c )->m c liftA2' :: forall (m :: * -> *) a b c.
Applicative m =>
m a -> m b -> (a -> b -> c) -> m c
liftA2' m a
a m b
b a -> b -> c
f =(a -> b -> c) -> m a -> m b -> m c
forall a b c. (a -> b -> c) -> m a -> m b -> m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2a -> b -> c
f m a
a m b
b -- | return (number of seconds, percentage, explanation)message ::Mealy (Double,Progress )(Double,Progress )->Mealy (Double,Progress )(Double,Double,String)message :: Mealy (Double, Progress) (Double, Progress)
-> Mealy (Double, Progress) (Double, Double, [Char])
message Mealy (Double, Progress) (Double, Progress)
input =(Double -> Double -> [Char] -> (Double, Double, [Char]))
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) [Char]
-> Mealy (Double, Progress) (Double, Double, [Char])
forall (f :: * -> *) a b c d.
Applicative f =>
(a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3(,,)Mealy (Double, Progress) Double
time Mealy (Double, Progress) Double
perc Mealy (Double, Progress) [Char]
debug whereprogress :: Mealy (Double, Progress) Progress
progress =(Double, Progress) -> Progress
forall a b. (a, b) -> b
snd((Double, Progress) -> Progress)
-> Mealy (Double, Progress) (Double, Progress)
-> Mealy (Double, Progress) Progress
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) (Double, Progress)
input secs :: Mealy (Double, Progress) Double
secs =(Double, Progress) -> Double
forall a b. (a, b) -> a
fst((Double, Progress) -> Double)
-> Mealy (Double, Progress) (Double, Progress)
-> Mealy (Double, Progress) Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) (Double, Progress)
input debug :: Mealy (Double, Progress) [Char]
debug =(\Double
donePerSec Double
ruleTime (Double
todoKnown ,Int
todoUnknown )->[Char]
"Progress: "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"((known="[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Int -> Double -> [Char]
forall a. RealFloat a => Int -> a -> [Char]
showDPInt
2Double
todoKnown [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"s) + "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"(unknown="[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Int -> [Char]
forall a. Show a => a -> [Char]
showInt
todoUnknown [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
" * time="[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Int -> Double -> [Char]
forall a. RealFloat a => Int -> a -> [Char]
showDPInt
2Double
ruleTime [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"s)) "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"(rate="[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Int -> Double -> [Char]
forall a. RealFloat a => Int -> a -> [Char]
showDPInt
2Double
donePerSec [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"))")(Double -> Double -> (Double, Int) -> [Char])
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) (Double -> (Double, Int) -> [Char])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Double
donePerSec Mealy (Double, Progress) (Double -> (Double, Int) -> [Char])
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) ((Double, Int) -> [Char])
forall a b.
Mealy (Double, Progress) (a -> b)
-> Mealy (Double, Progress) a -> Mealy (Double, Progress) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Mealy (Double, Progress) Double
ruleTime Mealy (Double, Progress) ((Double, Int) -> [Char])
-> Mealy (Double, Progress) (Double, Int)
-> Mealy (Double, Progress) [Char]
forall a b.
Mealy (Double, Progress) (a -> b)
-> Mealy (Double, Progress) a -> Mealy (Double, Progress) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>(Progress -> (Double, Int)
timeTodo (Progress -> (Double, Int))
-> Mealy (Double, Progress) Progress
-> Mealy (Double, Progress) (Double, Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Progress
progress )-- Number of seconds work completed in this build run-- Ignores timeSkipped which would be more truthful, but it makes the % drop sharply-- which isn't what users wantdone :: Mealy (Double, Progress) Double
done =Progress -> Double
timeBuilt (Progress -> Double)
-> Mealy (Double, Progress) Progress
-> Mealy (Double, Progress) Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Progress
progress -- Work done per second, don't divide by 0 and don't update if 'done' doesn't changedonePerSec :: Mealy (Double, Progress) Double
donePerSec =Mealy (Double, Progress) Bool
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall i a. Mealy i Bool -> Mealy i a -> Mealy i a -> Mealy i a
iff (Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
(==)Double
0(Double -> Bool)
-> Mealy (Double, Progress) Double -> Mealy (Double, Progress) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Double
done )(Double -> Mealy (Double, Progress) Double
forall a. a -> Mealy (Double, Progress) a
forall (f :: * -> *) a. Applicative f => a -> f a
pureDouble
1)Mealy (Double, Progress) Double
perSecStable whereperSecStable :: Mealy (Double, Progress) Double
perSecStable =Mealy (Double, Progress) (Bool, Double)
-> Mealy (Double, Progress) Double
forall i a. Mealy i (Bool, a) -> Mealy i a
latch (Mealy (Double, Progress) (Bool, Double)
 -> Mealy (Double, Progress) Double)
-> Mealy (Double, Progress) (Bool, Double)
-> Mealy (Double, Progress) Double
forall a b. (a -> b) -> a -> b
$(Bool -> Double -> (Bool, Double))
-> Mealy (Double, Progress) Bool
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) (Bool, Double)
forall a b c.
(a -> b -> c)
-> Mealy (Double, Progress) a
-> Mealy (Double, Progress) b
-> Mealy (Double, Progress) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2(,)((Double -> Double -> Bool) -> (Double, Double) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurryDouble -> Double -> Bool
forall a. Eq a => a -> a -> Bool
(==)((Double, Double) -> Bool)
-> Mealy (Double, Progress) (Double, Double)
-> Mealy (Double, Progress) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) (Double, Double)
forall a i. a -> Mealy i a -> Mealy i (a, a)
oldMealy Double
0Mealy (Double, Progress) Double
done )Mealy (Double, Progress) Double
perSecRaw perSecRaw :: Mealy (Double, Progress) Double
perSecRaw =Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall i.
Double -> Mealy i Double -> Mealy i Double -> Mealy i Double
decay Double
1.2Mealy (Double, Progress) Double
done Mealy (Double, Progress) Double
secs -- Predicted build time for a rule that has never been built before-- The high decay means if a build goes in "phases" - lots of source files, then lots of compiling-- we reach a reasonable number fairly quickly, without bouncing too muchruleTime :: Mealy (Double, Progress) Double
ruleTime =((Int, Double) -> (Int, Double) -> Double)
-> Mealy (Double, Progress) (Int, Double)
-> Mealy (Double, Progress) (Int, Double)
-> Mealy (Double, Progress) Double
forall a b c.
(a -> b -> c)
-> Mealy (Double, Progress) a
-> Mealy (Double, Progress) b
-> Mealy (Double, Progress) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2(Int, Double) -> (Int, Double) -> Double
weightedAverage ((Mealy (Double, Progress) Double
 -> Mealy (Double, Progress) Double
 -> Mealy (Double, Progress) Double)
-> (Progress -> Double)
-> (Progress -> Int)
-> Mealy (Double, Progress) (Int, Double)
forall {b} {b}.
(Mealy (Double, Progress) b
 -> Mealy (Double, Progress) Double -> Mealy (Double, Progress) b)
-> (Progress -> b)
-> (Progress -> Int)
-> Mealy (Double, Progress) (Int, b)
f (Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall i.
Double -> Mealy i Double -> Mealy i Double -> Mealy i Double
decay Double
10)Progress -> Double
timeBuilt Progress -> Int
countBuilt )((Mealy (Double, Progress) Double
 -> Mealy (Double, Progress) Double
 -> Mealy (Double, Progress) Double)
-> (Progress -> Double)
-> (Progress -> Int)
-> Mealy (Double, Progress) (Int, Double)
forall {b} {b}.
(Mealy (Double, Progress) b
 -> Mealy (Double, Progress) Double -> Mealy (Double, Progress) b)
-> (Progress -> b)
-> (Progress -> Int)
-> Mealy (Double, Progress) (Int, b)
f ((Double -> Double -> Double)
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall a b c.
(a -> b -> c)
-> Mealy (Double, Progress) a
-> Mealy (Double, Progress) b
-> Mealy (Double, Progress) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2Double -> Double -> Double
forall a. Fractional a => a -> a -> a
(/))((Double, Int) -> Double
forall a b. (a, b) -> a
fst((Double, Int) -> Double)
-> (Progress -> (Double, Int)) -> Progress -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Progress -> (Double, Int)
timeTodo )(\Progress {Double
Int
Maybe [Char]
(Double, Int)
countBuilt :: Progress -> Int
timeBuilt :: Progress -> Double
countSkipped :: Progress -> Int
timeSkipped :: Progress -> Double
countUnknown :: Progress -> Int
timeUnknown :: Progress -> Double
timeTodo :: Progress -> (Double, Int)
countTodo :: Progress -> Int
isFailure :: Maybe [Char]
countSkipped :: Int
countBuilt :: Int
countUnknown :: Int
countTodo :: Int
timeSkipped :: Double
timeBuilt :: Double
timeUnknown :: Double
timeTodo :: (Double, Int)
isFailure :: Progress -> Maybe [Char]
.. }->Int
countTodo Int -> Int -> Int
forall a. Num a => a -> a -> a
-(Double, Int) -> Int
forall a b. (a, b) -> b
snd(Double, Int)
timeTodo ))-- don't call decay on todo, since it goes up and down (as things get done)whereweightedAverage :: (Int, Double) -> (Int, Double) -> Double
weightedAverage (Int
w1 ,Double
x1 )(Int
w2 ,Double
x2 )|Int
w1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0Bool -> Bool -> Bool
&&Int
w2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0=Double
0|Bool
otherwise=((Int
w1 Int -> Double -> Double
*. Double
x1 )Double -> Double -> Double
forall a. Num a => a -> a -> a
+(Int
w2 Int -> Double -> Double
*. Double
x2 ))Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Int -> Double
intToDouble(Int
w1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
w2 )whereInt
i *. :: Int -> Double -> Double
*. Double
d =ifInt
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0thenDouble
0elseInt -> Double
intToDoubleInt
i Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
d -- since d might be NaNf :: (Mealy (Double, Progress) b
 -> Mealy (Double, Progress) Double -> Mealy (Double, Progress) b)
-> (Progress -> b)
-> (Progress -> Int)
-> Mealy (Double, Progress) (Int, b)
f Mealy (Double, Progress) b
-> Mealy (Double, Progress) Double -> Mealy (Double, Progress) b
divide Progress -> b
time Progress -> Int
count =letxs :: Mealy (Double, Progress) Int
xs =Progress -> Int
count (Progress -> Int)
-> Mealy (Double, Progress) Progress
-> Mealy (Double, Progress) Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Progress
progress in(Int -> b -> (Int, b))
-> Mealy (Double, Progress) Int
-> Mealy (Double, Progress) b
-> Mealy (Double, Progress) (Int, b)
forall a b c.
(a -> b -> c)
-> Mealy (Double, Progress) a
-> Mealy (Double, Progress) b
-> Mealy (Double, Progress) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2(,)Mealy (Double, Progress) Int
xs (Mealy (Double, Progress) b -> Mealy (Double, Progress) (Int, b))
-> Mealy (Double, Progress) b -> Mealy (Double, Progress) (Int, b)
forall a b. (a -> b) -> a -> b
$Mealy (Double, Progress) b
-> Mealy (Double, Progress) Double -> Mealy (Double, Progress) b
divide (Progress -> b
time (Progress -> b)
-> Mealy (Double, Progress) Progress -> Mealy (Double, Progress) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Progress
progress )(Int -> Double
intToDouble(Int -> Double)
-> Mealy (Double, Progress) Int -> Mealy (Double, Progress) Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Int
xs )-- Number of seconds work remaining, ignoring multiple threadstodo :: Mealy (Double, Progress) Double
todo =Progress -> Double -> Double
f (Progress -> Double -> Double)
-> Mealy (Double, Progress) Progress
-> Mealy (Double, Progress) (Double -> Double)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Progress
progress Mealy (Double, Progress) (Double -> Double)
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall a b.
Mealy (Double, Progress) (a -> b)
-> Mealy (Double, Progress) a -> Mealy (Double, Progress) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>Mealy (Double, Progress) Double
ruleTime wheref :: Progress -> Double -> Double
f Progress {Double
Int
Maybe [Char]
(Double, Int)
countBuilt :: Progress -> Int
timeBuilt :: Progress -> Double
countSkipped :: Progress -> Int
timeSkipped :: Progress -> Double
countUnknown :: Progress -> Int
timeUnknown :: Progress -> Double
timeTodo :: Progress -> (Double, Int)
countTodo :: Progress -> Int
isFailure :: Progress -> Maybe [Char]
isFailure :: Maybe [Char]
countSkipped :: Int
countBuilt :: Int
countUnknown :: Int
countTodo :: Int
timeSkipped :: Double
timeBuilt :: Double
timeUnknown :: Double
timeTodo :: (Double, Int)
.. }Double
ruleTime =(Double, Int) -> Double
forall a b. (a, b) -> a
fst(Double, Int)
timeTodo Double -> Double -> Double
forall a. Num a => a -> a -> a
+(Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral((Double, Int) -> Int
forall a b. (a, b) -> b
snd(Double, Int)
timeTodo )Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
ruleTime )-- Display informationtime :: Mealy (Double, Progress) Double
time =(Double -> Double -> Double)
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall a b c.
(a -> b -> c)
-> Mealy (Double, Progress) a
-> Mealy (Double, Progress) b
-> Mealy (Double, Progress) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2Double -> Double -> Double
forall a. Fractional a => a -> a -> a
(/)Mealy (Double, Progress) Double
todo Mealy (Double, Progress) Double
donePerSec perc :: Mealy (Double, Progress) Double
perc =Mealy (Double, Progress) Bool
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall i a. Mealy i Bool -> Mealy i a -> Mealy i a -> Mealy i a
iff (Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
(==)Double
0(Double -> Bool)
-> Mealy (Double, Progress) Double -> Mealy (Double, Progress) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Mealy (Double, Progress) Double
done )(Double -> Mealy (Double, Progress) Double
forall a. a -> Mealy (Double, Progress) a
forall (f :: * -> *) a. Applicative f => a -> f a
pureDouble
0)(Mealy (Double, Progress) Double
 -> Mealy (Double, Progress) Double)
-> Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
forall a b. (a -> b) -> a -> b
$Mealy (Double, Progress) Double
-> Mealy (Double, Progress) Double
-> (Double -> Double -> Double)
-> Mealy (Double, Progress) Double
forall (m :: * -> *) a b c.
Applicative m =>
m a -> m b -> (a -> b -> c) -> m c
liftA2' Mealy (Double, Progress) Double
done Mealy (Double, Progress) Double
todo ((Double -> Double -> Double) -> Mealy (Double, Progress) Double)
-> (Double -> Double -> Double) -> Mealy (Double, Progress) Double
forall a b. (a -> b) -> a -> b
$\Double
done Double
todo ->Double
100Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
done Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/(Double
done Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
todo )----------------------------------------------------------------------- EXPOSED FUNCTIONS-- | Given a sampling interval (in seconds) and a way to display the status message,-- produce a function suitable for using as 'Development.Shake.shakeProgress'.-- This function polls the progress information every /n/ seconds, produces a status-- message and displays it using the display function.---- Typical status messages will take the form of @1m25s (15%)@, indicating that the build-- is predicted to complete in 1 minute 25 seconds (85 seconds total), and 15% of the necessary build time has elapsed.-- This function uses past observations to predict future behaviour, and as such, is only-- guessing. The time is likely to go up as well as down, and will be less accurate from a-- clean build (as the system has fewer past observations).---- The current implementation is to predict the time remaining (based on 'timeTodo') and the-- work already done ('timeBuilt'). The percentage is then calculated as @remaining / (done + remaining)@,-- while time left is calculated by scaling @remaining@ by the observed work rate in this build,-- roughly @done / time_elapsed@.progressDisplay ::Double->(String->IO())->IOProgress ->IO()progressDisplay :: Double -> ([Char] -> IO ()) -> IO Progress -> IO ()
progressDisplay Double
sample [Char] -> IO ()
disp IO Progress
prog =do[Char] -> IO ()
disp [Char]
"Starting..."-- no useful info at this stageIO Double
time <-IO (IO Double)
offsetTime(AsyncException -> Maybe ()) -> IO () -> (() -> IO ()) -> IO ()
forall e b a.
Exception e =>
(e -> Maybe b) -> IO a -> (b -> IO a) -> IO a
catchJust(\AsyncException
x ->ifAsyncException
x AsyncException -> AsyncException -> Bool
forall a. Eq a => a -> a -> Bool
==AsyncException
ThreadKilledthen() -> Maybe ()
forall a. a -> Maybe a
Just()elseMaybe ()
forall a. Maybe a
Nothing)(IO Double
-> Mealy (Double, Progress) (Double, Double, [Char]) -> IO ()
loop IO Double
time (Mealy (Double, Progress) (Double, Double, [Char]) -> IO ())
-> Mealy (Double, Progress) (Double, Double, [Char]) -> IO ()
forall a b. (a -> b) -> a -> b
$Mealy (Double, Progress) (Double, Progress)
-> Mealy (Double, Progress) (Double, Double, [Char])
message Mealy (Double, Progress) (Double, Progress)
forall i. Mealy i i
echoMealy )(IO () -> () -> IO ()
forall a b. a -> b -> a
const(IO () -> () -> IO ()) -> IO () -> () -> IO ()
forall a b. (a -> b) -> a -> b
$doDouble
t <-IO Double
time ;[Char] -> IO ()
disp ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$[Char]
"Finished in "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Double -> [Char]
showDurationDouble
t )whereloop ::IODouble->Mealy (Double,Progress )(Double,Double,String)->IO()loop :: IO Double
-> Mealy (Double, Progress) (Double, Double, [Char]) -> IO ()
loop IO Double
time Mealy (Double, Progress) (Double, Double, [Char])
mealy =doDouble -> IO ()
sleepDouble
sample Progress
p <-IO Progress
prog Double
t <-IO Double
time ((Double
secs ,Double
perc ,[Char]
_debug ),Mealy (Double, Progress) (Double, Double, [Char])
mealy )<-((Double, Double, [Char]),
 Mealy (Double, Progress) (Double, Double, [Char]))
-> IO
 ((Double, Double, [Char]),
 Mealy (Double, Progress) (Double, Double, [Char]))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(((Double, Double, [Char]),
 Mealy (Double, Progress) (Double, Double, [Char]))
 -> IO
 ((Double, Double, [Char]),
 Mealy (Double, Progress) (Double, Double, [Char])))
-> ((Double, Double, [Char]),
 Mealy (Double, Progress) (Double, Double, [Char]))
-> IO
 ((Double, Double, [Char]),
 Mealy (Double, Progress) (Double, Double, [Char]))
forall a b. (a -> b) -> a -> b
$Mealy (Double, Progress) (Double, Double, [Char])
-> (Double, Progress)
-> ((Double, Double, [Char]),
 Mealy (Double, Progress) (Double, Double, [Char]))
forall i a. Mealy i a -> i -> (a, Mealy i a)
runMealy Mealy (Double, Progress) (Double, Double, [Char])
mealy (Double
t ,Progress
p )-- putStrLn _debugletdone :: Int
done =Progress -> Int
countSkipped Progress
p Int -> Int -> Int
forall a. Num a => a -> a -> a
+Progress -> Int
countBuilt Progress
p lettodo :: Int
todo =Int
done Int -> Int -> Int
forall a. Num a => a -> a -> a
+Progress -> Int
countUnknown Progress
p Int -> Int -> Int
forall a. Num a => a -> a -> a
+Progress -> Int
countTodo Progress
p [Char] -> IO ()
disp ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$[Char]
"Running for "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Double -> [Char]
showDurationSecs Double
t [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
" ["[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Int -> [Char]
forall a. Show a => a -> [Char]
showInt
done [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"/"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Int -> [Char]
forall a. Show a => a -> [Char]
showInt
todo [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"]"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
", predicted "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Double -> Double -> [Char]
formatMessage Double
secs Double
perc [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char] -> ([Char] -> [Char]) -> Maybe [Char] -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe[Char]
""([Char]
", Failure! "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++)(Progress -> Maybe [Char]
isFailure Progress
p )IO Double
-> Mealy (Double, Progress) (Double, Double, [Char]) -> IO ()
loop IO Double
time Mealy (Double, Progress) (Double, Double, [Char])
mealy dataProgressEntry =ProgressEntry {ProgressEntry -> Double
idealSecs ::Double,ProgressEntry -> Double
idealPerc ::Double,ProgressEntry -> Double
actualSecs ::Double,ProgressEntry -> Double
actualPerc ::Double}isInvalid ::ProgressEntry ->BoolisInvalid :: ProgressEntry -> Bool
isInvalid ProgressEntry {Double
idealSecs :: ProgressEntry -> Double
idealPerc :: ProgressEntry -> Double
actualSecs :: ProgressEntry -> Double
actualPerc :: ProgressEntry -> Double
idealSecs :: Double
idealPerc :: Double
actualSecs :: Double
actualPerc :: Double
.. }=Double -> Bool
forall a. RealFloat a => a -> Bool
isNaNDouble
actualSecs Bool -> Bool -> Bool
||Double -> Bool
forall a. RealFloat a => a -> Bool
isNaNDouble
actualPerc -- | Given a list of progress inputs, what would you have suggested (seconds, percentage)progressReplay ::[(Double,Progress )]->[ProgressEntry ]progressReplay :: [(Double, Progress)] -> [ProgressEntry]
progressReplay []=[]progressReplay [(Double, Progress)]
ps =(Mealy (Double, Progress) (Double, Double, [Char]),
 [ProgressEntry])
-> [ProgressEntry]
forall a b. (a, b) -> b
snd((Mealy (Double, Progress) (Double, Double, [Char]),
 [ProgressEntry])
 -> [ProgressEntry])
-> (Mealy (Double, Progress) (Double, Double, [Char]),
 [ProgressEntry])
-> [ProgressEntry]
forall a b. (a -> b) -> a -> b
$(Mealy (Double, Progress) (Double, Double, [Char])
 -> (Double, Progress)
 -> (Mealy (Double, Progress) (Double, Double, [Char]),
 ProgressEntry))
-> Mealy (Double, Progress) (Double, Double, [Char])
-> [(Double, Progress)]
-> (Mealy (Double, Progress) (Double, Double, [Char]),
 [ProgressEntry])
forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
mapAccumLMealy (Double, Progress) (Double, Double, [Char])
-> (Double, Progress)
-> (Mealy (Double, Progress) (Double, Double, [Char]),
 ProgressEntry)
forall {b} {c}.
Mealy (Double, b) (Double, Double, c)
-> (Double, b)
-> (Mealy (Double, b) (Double, Double, c), ProgressEntry)
f (Mealy (Double, Progress) (Double, Progress)
-> Mealy (Double, Progress) (Double, Double, [Char])
message Mealy (Double, Progress) (Double, Progress)
forall i. Mealy i i
echoMealy )[(Double, Progress)]
ps whereend :: Double
end =(Double, Progress) -> Double
forall a b. (a, b) -> a
fst((Double, Progress) -> Double) -> (Double, Progress) -> Double
forall a b. (a -> b) -> a -> b
$[(Double, Progress)] -> (Double, Progress)
forall a. Partial => [a] -> a
last[(Double, Progress)]
ps f :: Mealy (Double, b) (Double, Double, c)
-> (Double, b)
-> (Mealy (Double, b) (Double, Double, c), ProgressEntry)
f Mealy (Double, b) (Double, Double, c)
a (Double
time ,b
p )=(Mealy (Double, b) (Double, Double, c)
a2 ,Double -> Double -> Double -> Double -> ProgressEntry
ProgressEntry (Double
end Double -> Double -> Double
forall a. Num a => a -> a -> a
-Double
time )(Double
time Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
100Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
end )Double
secs Double
perc )where((Double
secs ,Double
perc ,c
_),Mealy (Double, b) (Double, Double, c)
a2 )=Mealy (Double, b) (Double, Double, c)
-> (Double, b)
-> ((Double, Double, c), Mealy (Double, b) (Double, Double, c))
forall i a. Mealy i a -> i -> (a, Mealy i a)
runMealy Mealy (Double, b) (Double, Double, c)
a (Double
time ,b
p )-- | Given a trace, display information about how well we didwriteProgressReport ::FilePath->[(FilePath,[(Double,Progress )])]->IO()writeProgressReport :: [Char] -> [([Char], [(Double, Progress)])] -> IO ()
writeProgressReport [Char]
out ((([Char], [(Double, Progress)]) -> ([Char], [ProgressEntry]))
-> [([Char], [(Double, Progress)])] -> [([Char], [ProgressEntry])]
forall a b. (a -> b) -> [a] -> [b]
map(([(Double, Progress)] -> [ProgressEntry])
-> ([Char], [(Double, Progress)]) -> ([Char], [ProgressEntry])
forall b b' a. (b -> b') -> (a, b) -> (a, b')
second[(Double, Progress)] -> [ProgressEntry]
progressReplay )->[([Char], [ProgressEntry])]
xs )|([Char]
bad ,[ProgressEntry]
_):[([Char], [ProgressEntry])]
_<-(([Char], [ProgressEntry]) -> Bool)
-> [([Char], [ProgressEntry])] -> [([Char], [ProgressEntry])]
forall a. (a -> Bool) -> [a] -> [a]
filter((ProgressEntry -> Bool) -> [ProgressEntry] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
anyProgressEntry -> Bool
isInvalid ([ProgressEntry] -> Bool)
-> (([Char], [ProgressEntry]) -> [ProgressEntry])
-> ([Char], [ProgressEntry])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([Char], [ProgressEntry]) -> [ProgressEntry]
forall a b. (a, b) -> b
snd)[([Char], [ProgressEntry])]
xs =[Char] -> IO ()
forall a. Partial => [Char] -> IO a
errorIO([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$[Char]
"Progress generates NaN for "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
bad |[Char] -> [Char]
takeExtension[Char]
out [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
==[Char]
".js"=[Char] -> [Char] -> IO ()
writeFile[Char]
out ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$[Char]
"var shake = \n"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[([Char], [ProgressEntry])] -> [Char]
generateJSON [([Char], [ProgressEntry])]
xs |[Char] -> [Char]
takeExtension[Char]
out [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
==[Char]
".json"=[Char] -> [Char] -> IO ()
writeFile[Char]
out ([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$[([Char], [ProgressEntry])] -> [Char]
generateJSON [([Char], [ProgressEntry])]
xs |[Char]
out [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
==[Char]
"-"=[Char] -> IO ()
putStr([Char] -> IO ()) -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$[[Char]] -> [Char]
unlines([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$[([Char], [ProgressEntry])] -> [[Char]]
generateSummary [([Char], [ProgressEntry])]
xs |Bool
otherwise=[Char] -> ByteString -> IO ()
LBS.writeFile[Char]
out (ByteString -> IO ()) -> IO ByteString -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<[([Char], [ProgressEntry])] -> IO ByteString
generateHTML [([Char], [ProgressEntry])]
xs generateSummary ::[(FilePath,[ProgressEntry ])]->[String]generateSummary :: [([Char], [ProgressEntry])] -> [[Char]]
generateSummary [([Char], [ProgressEntry])]
xs =((([Char], [ProgressEntry]) -> [[Char]])
 -> [([Char], [ProgressEntry])] -> [[Char]])
-> [([Char], [ProgressEntry])]
-> (([Char], [ProgressEntry]) -> [[Char]])
-> [[Char]]
forall a b c. (a -> b -> c) -> b -> a -> c
flip(([Char], [ProgressEntry]) -> [[Char]])
-> [([Char], [ProgressEntry])] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap[([Char], [ProgressEntry])]
xs ((([Char], [ProgressEntry]) -> [[Char]]) -> [[Char]])
-> (([Char], [ProgressEntry]) -> [[Char]]) -> [[Char]]
forall a b. (a -> b) -> a -> b
$\([Char]
file ,[ProgressEntry]
xs )->[[Char]
"# "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
file ,[ProgressEntry]
-> [Char]
-> (ProgressEntry -> Double)
-> (ProgressEntry -> Double)
-> [Char]
forall {a} {a}.
RealFrac a =>
[a] -> [Char] -> (a -> a) -> (a -> a) -> [Char]
f [ProgressEntry]
xs [Char]
"Seconds"ProgressEntry -> Double
idealSecs ProgressEntry -> Double
actualSecs ,[ProgressEntry]
-> [Char]
-> (ProgressEntry -> Double)
-> (ProgressEntry -> Double)
-> [Char]
forall {a} {a}.
RealFrac a =>
[a] -> [Char] -> (a -> a) -> (a -> a) -> [Char]
f [ProgressEntry]
xs [Char]
"Percent"ProgressEntry -> Double
idealPerc ProgressEntry -> Double
actualPerc ]wherelevels :: [Int]
levels =[Int
100,Int
90,Int
80,Int
50]f :: [a] -> [Char] -> (a -> a) -> (a -> a) -> [Char]
f [a]
xs [Char]
lbl a -> a
ideal a -> a
actual =[Char]
lbl [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
": "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate[Char]
", "[Int -> [Char]
forall a. Show a => a -> [Char]
showInt
l [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"% within "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++Integer -> [Char]
forall a. Show a => a -> [Char]
show(a -> Integer
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling(a -> Integer) -> a -> Integer
forall a b. (a -> b) -> a -> b
$[a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$a
0a -> [a] -> [a]
forall a. a -> [a] -> [a]
:Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take(([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length[a]
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
l )Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div`Int
100)[a]
diff )|Int
l <-[Int]
levels ]wherediff :: [a]
diff =[a] -> [a]
forall a. Ord a => [a] -> [a]
sort[a -> a
forall a. Num a => a -> a
abs(a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$a -> a
ideal a
x a -> a -> a
forall a. Num a => a -> a -> a
-a -> a
actual a
x |a
x <-[a]
xs ]generateHTML ::[(FilePath,[ProgressEntry ])]->IOLBS.ByteStringgenerateHTML :: [([Char], [ProgressEntry])] -> IO ByteString
generateHTML [([Char], [ProgressEntry])]
xs =doByteString
report <-[Char] -> IO ByteString
readDataFileHTML [Char]
"progress.html"letf :: [Char] -> f ByteString
f [Char]
"data/progress-data.js"=ByteString -> f ByteString
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(ByteString -> f ByteString) -> ByteString -> f ByteString
forall a b. (a -> b) -> a -> b
$[Char] -> ByteString
LBS.pack([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$[Char]
"var progress =\n"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[([Char], [ProgressEntry])] -> [Char]
generateJSON [([Char], [ProgressEntry])]
xs ([Char] -> IO ByteString) -> ByteString -> IO ByteString
runTemplate [Char] -> IO ByteString
forall {f :: * -> *}. Applicative f => [Char] -> f ByteString
f ByteString
report generateJSON ::[(FilePath,[ProgressEntry ])]->StringgenerateJSON :: [([Char], [ProgressEntry])] -> [Char]
generateJSON =[[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat([[Char]] -> [Char])
-> ([([Char], [ProgressEntry])] -> [[Char]])
-> [([Char], [ProgressEntry])]
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[[Char]] -> [[Char]]
jsonList ([[Char]] -> [[Char]])
-> ([([Char], [ProgressEntry])] -> [[Char]])
-> [([Char], [ProgressEntry])]
-> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(([Char], [ProgressEntry]) -> [Char])
-> [([Char], [ProgressEntry])] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map(([Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"}")([Char] -> [Char])
-> (([Char], [ProgressEntry]) -> [Char])
-> ([Char], [ProgressEntry])
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[[Char]] -> [Char]
unlines([[Char]] -> [Char])
-> (([Char], [ProgressEntry]) -> [[Char]])
-> ([Char], [ProgressEntry])
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([Char], [ProgressEntry]) -> [[Char]]
f )wheref :: ([Char], [ProgressEntry]) -> [[Char]]
f ([Char]
file ,[ProgressEntry]
ps )=([Char]
"{\"name\":"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char] -> [Char]
forall a. Show a => a -> [Char]
show([Char] -> [Char]
takeFileName[Char]
file )[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
", \"values\":")[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
:[[Char]] -> [[Char]]
indent ([[Char]] -> [[Char]]
jsonList ([[Char]] -> [[Char]]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> a -> b
$(ProgressEntry -> [Char]) -> [ProgressEntry] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
mapProgressEntry -> [Char]
g [ProgressEntry]
ps )shw :: Double -> [Char]
shw =Int -> Double -> [Char]
forall a. RealFloat a => Int -> a -> [Char]
showDPInt
1g :: ProgressEntry -> [Char]
g ProgressEntry {Double
idealSecs :: ProgressEntry -> Double
idealPerc :: ProgressEntry -> Double
actualSecs :: ProgressEntry -> Double
actualPerc :: ProgressEntry -> Double
idealSecs :: Double
idealPerc :: Double
actualSecs :: Double
actualPerc :: Double
.. }=[([Char], [Char])] -> [Char]
forall {a}. Show a => [(a, [Char])] -> [Char]
jsonObject [([Char]
"idealSecs",Double -> [Char]
shw Double
idealSecs ),([Char]
"idealPerc",Double -> [Char]
shw Double
idealPerc ),([Char]
"actualSecs",Double -> [Char]
shw Double
actualSecs ),([Char]
"actualPerc",Double -> [Char]
shw Double
actualPerc )]indent :: [[Char]] -> [[Char]]
indent =([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map([Char]
" "[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++)jsonList :: [[Char]] -> [[Char]]
jsonList [[Char]]
xs =(Char -> [Char] -> [Char]) -> [Char] -> [[Char]] -> [[Char]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith(:)(Char
'['Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char -> [Char]
forall a. a -> [a]
repeatChar
',')[[Char]]
xs [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++[[Char]
"]"]jsonObject :: [(a, [Char])] -> [Char]
jsonObject [(a, [Char])]
xs =[Char]
"{"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate[Char]
", "[a -> [Char]
forall a. Show a => a -> [Char]
showa
a [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
":"[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
b |(a
a ,[Char]
b )<-[(a, [Char])]
xs ][Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
"}"-- | Set the title of the current console window to the given text. If the-- environment variable @$TERM@ is set to @xterm@ this uses xterm escape sequences.-- On Windows, if not detected as an xterm, this function uses the @SetConsoleTitle@ API.progressTitlebar ::String->IO()progressTitlebar :: [Char] -> IO ()
progressTitlebar [Char]
x =IO Bool -> IO () -> IO ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessMIO Bool
win IO ()
lin where
#ifdef mingw32_HOST_OS
win=withCWStringxc_setConsoleTitleW
#else
win :: IO Bool
win =Bool -> IO Bool
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pureBool
False
#endif
lin :: IO ()
lin =IO Bool -> IO () -> IO ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenMIO Bool
checkEscCodes (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$OneShot BS_Store -> IO ()
BS.putStr(OneShot BS_Store -> IO ()) -> OneShot BS_Store -> IO ()
forall a b. (a -> b) -> a -> b
$[Char] -> OneShot BS_Store
BS.pack([Char] -> OneShot BS_Store) -> [Char] -> OneShot BS_Store
forall a b. (a -> b) -> a -> b
$[Char] -> [Char]
escWindowTitle [Char]
x -- | Call the program @shake-progress@ if it is on the @$PATH@. The program is called with-- the following arguments:---- * @--title=string@ - the string passed to @progressProgram@.---- * @--state=Normal@, or one of @NoProgress@, @Normal@, or @Error@ to indicate-- what state the progress bar should be in.---- * @--value=25@ - the percent of the build that has completed, if not in @NoProgress@ state.---- The program will not be called consecutively with the same @--state@ and @--value@ options.---- Windows 7 or higher users can get taskbar progress notifications by placing the following-- program in their @$PATH@: <https://github.com/ndmitchell/shake/releases>.progressProgram ::IO(String->IO())progressProgram :: IO ([Char] -> IO ())
progressProgram =doMaybe [Char]
exe <-[Char] -> IO (Maybe [Char])
findExecutable[Char]
"shake-progress"caseMaybe [Char]
exe ofMaybe [Char]
Nothing->([Char] -> IO ()) -> IO ([Char] -> IO ())
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(([Char] -> IO ()) -> IO ([Char] -> IO ()))
-> ([Char] -> IO ()) -> IO ([Char] -> IO ())
forall a b. (a -> b) -> a -> b
$IO () -> [Char] -> IO ()
forall a b. a -> b -> a
const(IO () -> [Char] -> IO ()) -> IO () -> [Char] -> IO ()
forall a b. (a -> b) -> a -> b
$() -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure()Just[Char]
exe ->doIORef (Maybe [[Char]])
lastArgs <-Maybe [[Char]] -> IO (IORef (Maybe [[Char]]))
forall a. a -> IO (IORef a)
newIORefMaybe [[Char]]
forall a. Maybe a
Nothing-- the arguments we passed to shake-progress last time([Char] -> IO ()) -> IO ([Char] -> IO ())
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure(([Char] -> IO ()) -> IO ([Char] -> IO ()))
-> ([Char] -> IO ()) -> IO ([Char] -> IO ())
forall a b. (a -> b) -> a -> b
$\[Char]
msg ->doletfailure :: Bool
failure =[Char]
" Failure! "[Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf`[Char]
msg letperc :: [Char]
perc =let([Char]
a ,[Char]
b )=(Char -> Bool) -> [Char] -> ([Char], [Char])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break(Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'%')[Char]
msg inif[Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null[Char]
b then[Char]
""else[Char] -> [Char]
forall a. [a] -> [a]
reverse([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$(Char -> Bool) -> [Char] -> [Char]
forall a. (a -> Bool) -> [a] -> [a]
takeWhileChar -> Bool
isDigit([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$[Char] -> [Char]
forall a. [a] -> [a]
reverse[Char]
a letstate :: [Char]
state |[Char]
perc [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
==[Char]
""=[Char]
"NoProgress"|Bool
failure =[Char]
"Error"|Bool
otherwise=[Char]
"Normal"letargs :: [[Char]]
args =[[Char]
"--title="[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
msg ,[Char]
"--state="[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
state ][[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++[[Char]
"--value="[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char]
perc |[Char]
perc [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
/=[Char]
""]Bool
same <-IORef (Maybe [[Char]])
-> (Maybe [[Char]] -> (Maybe [[Char]], Bool)) -> IO Bool
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORefIORef (Maybe [[Char]])
lastArgs ((Maybe [[Char]] -> (Maybe [[Char]], Bool)) -> IO Bool)
-> (Maybe [[Char]] -> (Maybe [[Char]], Bool)) -> IO Bool
forall a b. (a -> b) -> a -> b
$\Maybe [[Char]]
old ->([[Char]] -> Maybe [[Char]]
forall a. a -> Maybe a
Just[[Char]]
args ,Maybe [[Char]]
old Maybe [[Char]] -> Maybe [[Char]] -> Bool
forall a. Eq a => a -> a -> Bool
==[[Char]] -> Maybe [[Char]]
forall a. a -> Maybe a
Just[[Char]]
args )Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unlessBool
same (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$IO ExitCode -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void(IO ExitCode -> IO ()) -> IO ExitCode -> IO ()
forall a b. (a -> b) -> a -> b
$[Char] -> [[Char]] -> IO ExitCode
rawSystem[Char]
exe [[Char]]
args -- | A simple method for displaying progress messages, suitable for using as 'Development.Shake.shakeProgress'.-- This function writes the current progress to the titlebar every five seconds using 'progressTitlebar',-- and calls any @shake-progress@ program on the @$PATH@ using 'progressProgram'.progressSimple ::IOProgress ->IO()progressSimple :: IO Progress -> IO ()
progressSimple IO Progress
p =do[Char] -> IO ()
program <-IO ([Char] -> IO ())
progressProgram Double -> ([Char] -> IO ()) -> IO Progress -> IO ()
progressDisplay Double
5(\[Char]
s ->[Char] -> IO ()
progressTitlebar [Char]
s IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>[Char] -> IO ()
program [Char]
s )IO Progress
p 

AltStyle によって変換されたページ (->オリジナル) /