如何在Shake中定义自定义规则:隐藏Development.Shake.Core

时间:2013-01-31 17:48:37

标签: shake-build-system

我正在尝试使用看起来非常有前景的Shake但是我打了一堵小墙。我对haskell很新,所以也许我错过了一些明显的东西,但这是我的问题:

我想在摇摆计划中定义一种新的规则。此规则将从依赖项计算值,并将其存储在其数据库中。因此,如果依赖项是最新的,则抖动db值始终有效。

data PrjList = PrjList FilePath deriving (Typeable,Show,Eq,Hashable,Binary,NFData)

instance Rule PrjList [(String,FilePath)] where
    validStored q a = True

-- Generate the dependency
getProjectList :: FilePath -> Action [(String,FilePath)]
getProjectList dir = apply1 $ PrjList dir

-- We want to traverse recursivly all subdir but stop once we find a BuildConfig file
defaultProjectList :: Rules ()
defaultProjectList = defaultRule $ \(PrjList dir) -> Just $ do
     -- blabla...
     return []

但是,如果我尝试import Development.Shake.Core我有

Could not find module `Development.Shake.Core'
It is a member of the hidden package `shake-0.7'.
it is a hidden module in the package `shake-0.7'
it is a hidden module in the package `shake-0.8'
Use -v to see a list of the files searched for.

如果我不导入它,我有

`validStored' is not a (visible) method of class `Rule'

那么如何定义新规则?

奖金问题是:我的想法有趣还是有更好的方法来做到这一点?在考虑如何使用摇动时,我有很多规则会产生这种行为。这样可以避免使用大量的临时文件并利用抖动数据库。实际上,我的下一步是尝试为“文件系统自由规则”定义通用规则。用户只需提供key → Maybe (Action value)功能。

1 个答案:

答案 0 :(得分:0)

在shake-0.4及以上validStored已从Rule类中移除,并替换为:

storedValue :: key -> IO (Maybe value)

因此,不是定义值是否仍然正确,而是返回存储的值。这使你想要做的更努力,但仍然可能。您可以将value类型定义为:

data MyValue a = RealResult a | Cheat
instance Eq a => Eq (MyValue a) where
    RealValue a == RealValue b = a == b
    _ == _ = True

现在您可以定义storedValue _ = return $ Just Cheat,并且现有值始终被视为有效。

使这些“缓存”规则更难的原因是因为我认为它们不是一个好主意,原因有三:

  1. 如果在编写构建系统时遇到其中一个规则错误,则必须删除Shake数据库才能返回有效状态。
  2. 您无法轻易看到已生成的内容,因此必须采用大型多线程系统中难以跟踪的跟踪。
  3. 在构建系统的每次运行中,即使无事可做,Shake也必须对整个数据库进行反序列化,包括存储在那里的任何大值。
  4. 我发现如果你只使用临时文件,一切都会变得更加直截了当。

    我可以想象有一些空间用于缓存文件内容的反序列化,例如:如果你在一个文件中存储复杂的结构,但我还没有一个很好的API来做到这一点。

    在Shake 0.9及以上

    newCache函数提供了一种缓存文件内容反序列化的方法。