gpt4 book ai didi

haskell - 如何使用darcs库查询补丁信息?

转载 作者:行者123 更新时间:2023-12-03 21:47:11 25 4
gpt4 key购买 nike

我想编写一个 Haskell 程序来查询有关 darcs 存储库的信息。我宁愿直接使用 darcs 库,而不是调用 darcs 可执行文件并解析结果。是said to be “很多工作正在进行中”和“缺乏稳定的 API”,但似乎可用。

我想我可以通过研究 darcsden 源代码来回答我的问题,例如,从 this module 开始,但我认为,如果有知识渊博的人提供评论介绍来补充这样的研究,这不仅对我有帮助。

所以,这里有一个具体的例子。

如何为给定文件计算影响它的最新补丁以及补丁的日期、作者和名称?如果您解释解决方案中使用的关键库函数,这将非常有用。

编辑:

这里有一些对不熟悉 darcs 源代码的人可能不明显的评论。我是从 Jason Dagit's master thesis 那里学到的并希望他们有助于理解 Ganesh 给出的答案。

在 Darcs 中,补丁有一个前后上下文,表示应用补丁之前和之后存储库的状态。在源代码中,这些上下文是在补丁类型上使用幻像类型建模的。这些幻像类型称为见证人和 seal2用于摆脱它们。

在补丁列表中,只有第一个前上下文和最后一个后上下文在类型中表示。所有其他上下文都使用存在类型隐藏。 Darcs 定义了前向列表(称为 FL)和反向列表(称为 RL)。反向列表以反向(按时间顺序)顺序存储补丁(由 darcs 完成的模补丁重新排序)。反向列表可用于访问头部位置的最新补丁。所有名称中带有 RL 的函数都会创建或操作此类反向列表。

最佳答案

-- This works with darcs 2.9.5 (a tag in the development repo
-- at http://darcs.net/screened).
--
-- It should work with darcs 2.8.2 with the following changes:
-- - some minor namespace changes
-- - change withRepositoryDirectory to pass [] instead of YesUseCache
-- - comment out the line below that uses the "patch index"

import Control.Applicative ( (<$>) )

import Darcs.Patch.Info ( PatchInfo )
import Darcs.Patch.Inspect ( listTouchedFiles )
import Darcs.Patch.PatchInfoAnd ( info )
import Darcs.Patch.Set ( newset2RL )
import Darcs.Patch.Witnesses.Ordered ( mapRL )
import Darcs.Patch.Witnesses.Sealed ( seal2, unseal2 )

import Darcs.Repository
( withRepositoryDirectory, RepoJob(..), readRepo )
import Darcs.Repository.FileMod ( filterPatches )
import Darcs.Repository.Flags ( UseCache(..) )

import Data.Maybe ( listToMaybe )

getChange
:: FilePath -- ^repository directory
-> FilePath -- ^file path
-> IO (Maybe PatchInfo) -- ^patch metadata
getChange repoDir fileName =

-- Select the repository from repositoryDirectory.
--
-- The function parameter to 'RepoJob' needs to be polymorphic
-- in the underlying patch type (darcs-1 or darcs-2).

withRepositoryDirectory YesUseCache repoDir $ RepoJob $ \repo -> do

-- 'readRepo' gives us a PatchSet, a lazy witnessed list of all
-- the patches structured by "clean tags".
--
-- We use 'newset2RL' to get rid of the tag structure as we don't
-- need it, and 'mapRL seal2' to get rid of the witnesses which we
-- also don't need. The result is of type '[Sealed2 p]', where 'p'
-- is the underlying patch type of the repository we are reading
-- (either darcs-1 or darcs-2)

patches <- mapRL seal2 . newset2RL <$> readRepo repo


-- Use the recently introduced "patch index" to filter the list of
-- patches from the repo down to ones that just touch 'fileName'.
--
-- This step is optional: we can remove it and the result will be
-- the same, but substantially slower on large repositories where
-- the patch we want is far back in the repo.

patches <- filterPatches repo [fileName] patches

-- Use 'filter' and 'listToMaybe' to get the first patch that touches
-- 'fileName'.
--
-- The filter is superfluous in this simple case if the patch
-- index was used, but doesn't cost much if so.
--
-- Note that this doesn't track renames, so isn't suitable for
-- finding anything but the last patch that touched 'fileName'.
--
-- 'unseal2' is used to lift a function that works on witnessed
-- patches to one that works on "sealed" patches.

let wanted = unseal2 (\patch -> fileName `elem` listTouchedFiles patch)
let thepatch = listToMaybe . filter wanted $ patches

-- Finally, return the metadata of the patch.
--
-- Things get a little bit more complex if we want to deal
-- with the contents of the patch, because the specific
-- patch type isn't known statically - it might be
-- darcs-1 or darcs-2.
--
-- The best approach is to write a polymorphic function that
-- can accept any instance of 'RepoPatch'.

return (fmap (unseal2 info) thepatch)

关于haskell - 如何使用darcs库查询补丁信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12941793/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com