Commit 2f373e4a authored by Andrey Mokhov's avatar Andrey Mokhov
Browse files

Add getFile and getWay to Environment.

parent acde0ea2
...@@ -11,7 +11,9 @@ what we expose to users?). Can be made into a conditional expression ...@@ -11,7 +11,9 @@ what we expose to users?). Can be made into a conditional expression
similar to userWays, userPackages and userSettings, but is it worth it? similar to userWays, userPackages and userSettings, but is it worth it?
* knownPackages (Targets.hs) -- fix by adding knownUserPackages? A nasty * knownPackages (Targets.hs) -- fix by adding knownUserPackages? A nasty
import cycle is then created between Targets.hs and UserSettings.hs import cycle is then created between Targets.hs and UserSettings.hs. Possible
solution: add file Settings/Targets.hs which will actually put two things
together similar to what's done with userWays, userPackages and userSettings.
* integerLibraryImpl (Switches.hs) -- fix by having three integer library * integerLibraryImpl (Switches.hs) -- fix by having three integer library
packages in Targets.hs and choosing which one to build in userPackages, e.g.: packages in Targets.hs and choosing which one to build in userPackages, e.g.:
...@@ -25,10 +27,15 @@ there should only be one place for user to look: UserSettings.hs. ...@@ -25,10 +27,15 @@ there should only be one place for user to look: UserSettings.hs.
================================================ ================================================
2. When predicates are moved from configuration files to UserSettings we 2. When predicates (e.g. buildHaddock) are moved from configuration files to
no longer track their state in oracles. This may lead to inconsistent UserSettings we no longer track their state in oracles. This may lead to an
state of the build system. A more general problem: how do we accurately inconsistent state of the build system. This is a special case of a more general
track changes in the build systems, specifically in UserSettings.hs? problem: how do we accurately track changes in the build system, specifically
in UserSettings.hs? Although in general this is a hard problem, this special
case may be easier to solve: just channel everything exported from
UserSettings.hs through oracles? Another alternative which was discussed
previously: pass the final lists of arguments through oracles. Care must
be taken though as final command lines can be as large as 5Mb!
================================================ ================================================
...@@ -40,15 +47,15 @@ complete build though.) ...@@ -40,15 +47,15 @@ complete build though.)
4. I'd like interpret/interpretDiff to be total functions. It should be 4. I'd like interpret/interpretDiff to be total functions. It should be
possible to check at compile which questions a given environment can possible to check at compile which questions a given environment can
answer and raise an error if an expression needs to know more. answer and raise a *compile* error if the expression needs to know more.
For example, consider an environment envS that can only answer 'getStage' For example, consider an environment envS that can only answer 'getStage'
question, and environment envSP that can answer questions 'getStage' and question, and environment envSP that can answer questions 'getStage' and
'getPackage'. Now consider two expressions 'getPackage'. Now consider two expressions
exprS = stage0 ? foo exprS = stage0 ? arg "foo"
exprSP = stage0 ? package base ? bar exprSP = stage0 ? package base ? arg "bar"
Now I'd like the following to produce a compile error: Now I'd like the following to produce a compile error:
...@@ -61,23 +68,41 @@ interpret envSP exprS ...@@ -61,23 +68,41 @@ interpret envSP exprS
interpret envSP exprSP interpret envSP exprSP
I played with some possible solutions using type classes, but they all I played with some possible solutions using type classes, but they all
seem clumsy/heavy. seem clumsy/heavy, e.g. carrying (GetStage env, GetPackage env) constraints
with any expression similar to exprSP.
Hence, for now I have: Right now I have:
data Environment = Environment data Environment = Environment
{ {
getStage :: Stage, getStage :: Stage,
getPackage :: Package,
getBuilder :: Builder, getBuilder :: Builder,
getPackage :: Package getFile :: FilePath,
getWay :: Way
} }
defaultEnvironment :: Environment defaultEnvironment :: Environment
defaultEnvironment = Environment defaultEnvironment = Environment
{ {
getStage = error "Stage not set in the environment", getStage = error "Stage not set in the environment",
getPackage = error "Package not set in the environment",
getBuilder = error "Builder not set in the environment", getBuilder = error "Builder not set in the environment",
getPackage = error "Package not set in the environment" getFile = error "File not set in the environment",
getWay = error "Way not set in the environment"
} }
which leads to a lot of partial functions all over the build system. which is annoying and leads to many partial functions all over the build
\ No newline at end of file system. Haskell should be above that!
Any ideas? Having
(GetStage env, GetPackage env, GetBuilder env, ...) => DiffExpr env
all over the build system seems unsatisfactory.
Note, environment is (always?) built in the following order: getStage,
getPackage, getBuilder, getFile, getWay. Hence, it may be OK to have only
6 combinations of getters in a type constraint, not 2^5, e.g.: empty,
GetStage env, (GetStage env, GetPackage env), etc.
...@@ -8,7 +8,7 @@ module Expression ( ...@@ -8,7 +8,7 @@ module Expression (
Environment (..), defaultEnvironment, Environment (..), defaultEnvironment,
append, appendM, remove, appendSub, appendSubD, filterSub, removeSub, append, appendM, remove, appendSub, appendSubD, filterSub, removeSub,
interpret, interpretDiff, interpret, interpretDiff,
applyPredicate, (?), (??), stage, builder, package, applyPredicate, (?), (??), stage, package, builder, file, way,
configKeyValue, configKeyValues configKeyValue, configKeyValues
) where ) where
...@@ -22,9 +22,10 @@ import Control.Monad.Reader ...@@ -22,9 +22,10 @@ import Control.Monad.Reader
data Environment = Environment data Environment = Environment
{ {
getStage :: Stage, getStage :: Stage,
getPackage :: Package,
getBuilder :: Builder, getBuilder :: Builder,
getPackage :: Package getFile :: FilePath,
-- getWay :: Way, and maybe something else will be useful later getWay :: Way
} }
-- TODO: all readers are currently partial functions. Can use type classes to -- TODO: all readers are currently partial functions. Can use type classes to
...@@ -33,8 +34,10 @@ defaultEnvironment :: Environment ...@@ -33,8 +34,10 @@ defaultEnvironment :: Environment
defaultEnvironment = Environment defaultEnvironment = Environment
{ {
getStage = error "Stage not set in the environment", getStage = error "Stage not set in the environment",
getPackage = error "Package not set in the environment",
getBuilder = error "Builder not set in the environment", getBuilder = error "Builder not set in the environment",
getPackage = error "Package not set in the environment" getFile = error "File not set in the environment",
getWay = error "Way not set in the environment"
} }
type Expr a = ReaderT Environment Action a type Expr a = ReaderT Environment Action a
...@@ -128,11 +131,17 @@ p ?? (t, f) = p ? t <> (liftM not p) ? f ...@@ -128,11 +131,17 @@ p ?? (t, f) = p ? t <> (liftM not p) ? f
stage :: Stage -> Predicate stage :: Stage -> Predicate
stage s = liftM (s ==) (asks getStage) stage s = liftM (s ==) (asks getStage)
package :: Package -> Predicate
package p = liftM (p ==) (asks getPackage)
builder :: Builder -> Predicate builder :: Builder -> Predicate
builder b = liftM (b ==) (asks getBuilder) builder b = liftM (b ==) (asks getBuilder)
package :: Package -> Predicate file :: FilePattern -> Predicate
package p = liftM (p ==) (asks getPackage) file f = liftM (f ?==) (asks getFile)
way :: Way -> Predicate
way w = liftM (w ==) (asks getWay)
configKeyValue :: String -> String -> Predicate configKeyValue :: String -> String -> Predicate
configKeyValue key value = liftM (value ==) (lift $ askConfig key) configKeyValue key value = liftM (value ==) (lift $ askConfig key)
......
...@@ -2,6 +2,7 @@ module Targets ( ...@@ -2,6 +2,7 @@ module Targets (
targetDirectory, targetDirectory,
knownPackages, knownPackages,
customPackageSettings, customPackageSettings,
integerLibraryName,
array, base, binPackageDb, binary, bytestring, cabal, compiler, containers, array, base, binPackageDb, binary, bytestring, cabal, compiler, containers,
deepseq, directory, filepath, ghcPrim, haskeline, hoopl, hpc, deepseq, directory, filepath, ghcPrim, haskeline, hoopl, hpc,
integerLibrary, parallel, pretty, primitive, process, stm, templateHaskell, integerLibrary, parallel, pretty, primitive, process, stm, templateHaskell,
......
module UserSettings ( module UserSettings (
userSettings, userPackages, userWays, userSettings, userPackages, userWays,
buildHaddock, validating buildHaddock, validating
) where ) where
...@@ -36,9 +35,24 @@ validating = return False ...@@ -36,9 +35,24 @@ validating = return False
-- Examples: -- Examples:
userSettings' :: Settings userSettings' :: Settings
userSettings' = mconcat userSettings' = mconcat
[ package compiler ? stage0 ? arg "foo" [ package base ?
builder GhcCabal ? arg ("--flags=" ++ integerLibraryName)
, package integerLibrary ? appendCcArgs ["-Ilibraries/integer-gmp2/gmp"]
, windowsHost ?
package integerLibrary ?
builder GhcCabal ? arg "--configure-option=--with-intree-gmp"
, package compiler ?
stage0 ?
way profiling ?
file "pattern.*" ? args ["foo", "bar"]
, builder (Ghc Stage0) ? remove ["-O2"] , builder (Ghc Stage0) ? remove ["-O2"]
, builder GhcCabal ? removeSub "--configure-option=CFLAGS" ["-Werror"] ]
, builder GhcCabal ? removeSub "--configure-option=CFLAGS" ["-Werror"]
]
userPackages' :: Packages userPackages' :: Packages
userPackages' = mconcat userPackages' = mconcat
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment