On Thu, 14 Aug 2014 22:50:00 +0200 Joachim Breitner <nomeata@debian.org> wrote: > the information in the PTS on package uninstallability is unfortunately > not very helpful. > > What I do to investigate such problems is > * make sure all Haskell packages are installable: > http://jenkins.debian.net/job/chroot-installation_sid_install_haskell/ > Last build mentions criterion and notmuch-web, I believe I have fixed > these yesterday and hope that the job finally succeeds (after 3 months!) > next time. But this only tests amd64. > * make sure that there are no failed builds. Follow the link from > http://wiki.debian.org/Haskell to see the status of all packages on > buildd.debian.org, and watch for Failed (icon ~). > * check if the binNMU scheduling script wants to schedule more > packages. Unfortunately, this requires access to wuiet.debian.org. > Currently, it does not detect problems. > * finally, try to make sense of > https://release.debian.org/britney/update_output.txt > Look for lines starting with "Trying easy from autohinter" that mention > haskell packages. A few lines down are lines starting with " * <some > arch>", these are packages broken by the proposed upgrade (but without > explanation). The current autohint including gettext seems to break a > lot of packages, no idea what is left to do. > > > Maybe Niels Thyker, who has worked on the autohinter, is interested in > helping you solve the problem of „why does gettext not migrate“ and > might want to improve these tools. Niels Thykier explained a little bit of "why does gettext not migrate", but more importantly: He told me how to interpret the autohinter output, in conjunction with the excuses. As it turns out, they seem to be helpful after all. After thinking about this, I made a tool that takes a packages and shows all (at least I hope it gets all of them) the useful reasons why it can't migrate. It does this as follows: -Look in the britney output for the autohint that contains the requested package. -Get all the packages it breaks. -Gather all excuses for that broken packages. -Throw all excuses away, except those that are identified as interesting. This gives a list of excuses that isn't as overwhelming as the autohinter output. The following excuses are identified as interesting: -out of date on... -introduces new bugs -Too young (It's not really interesting, but it helps to tell if there's a bug in the program or if you just have to wait until the transition can happen) The following excuses are discarded on purpose: -Depends: (because the dependency should be listed seperately.) If you find some excuses that should be also marked as interesting, please contact me. I didn't come up with a name yet. So I'm interested in your suggestions. (And it's really tedious to call it "The tool that tells you why your packages don't migrate".) I'm not sure wether to put it into the tools repository or to the package-plan. I more tend to put it to the tools, but please tell me what you're thinking. The source code is attached. The program takes very long to produce it's result, since it needs to do a lot of calls to apt-cache and grep-excuses. It uses the local cache to map binary packages to src packages. So it might fail on testing, if there is a broken package, which is not in testing. Regards Sven
import Text.Regex.PCRE
import System.Environment
import System.Exit
import System.Process
import Data.Maybe
import Data.List
import Data.Char
import qualified Data.Set as S
import Control.Exception
import Debug.Trace
data Excuses = Excuses String [String]
isEmpty :: Excuses -> Bool
isEmpty (Excuses _ []) = False
isEmpty (Excuses _ _) = True
excuses2String :: Excuses -> String
excuses2String (Excuses pkg excuses) = unlines $ (pkg ++ ":"):(map (" " ++) excuses)
main = do
(britneyout, package) <- getArgs >>= parse
output <- fmap lines $ readFile britneyout
let bins = getBinBlockers output package
result <- try (fmap nub $ mapM getSrcPackage bins) :: IO (Either ErrorCall [String])
srcBlockers <- case result of
Left e -> putStrLn packageNotFoundMsg >> exitFailure
Right pkgs -> return pkgs
excuses <- mapM getExcuse srcBlockers
let filteredExcuses = filterExcuses excuses
mapM_ putStrLn $ map excuses2String filteredExcuses
parse :: [String] -> IO (String, String)
parse [britneyout, package] = return (britneyout, package)
parse _ = printUsage >> exitFailure
printUsage :: IO ()
printUsage = do
progName <- getProgName
putStrLn $ "Usage: " ++ progName ++ " britney-output package-name"
packageNotFoundMsg :: String
packageNotFoundMsg
= "Something went wrong.\n\
\Most likely the package you requested was not processed by the \
\autohinter."
filterExcuses :: [Excuses] -> [Excuses]
filterExcuses excuses = filter isEmpty $ map filterPkgExcuses excuses
where filterPkgExcuses (Excuses pkg excuses) = Excuses pkg
$ filter isInteresting excuses
isInteresting :: String -> Bool
isInteresting excuse = "out of date on" `isPrefixOf` excuse
|| "introduces new bugs" `isInfixOf` excuse
|| "Too young" `isPrefixOf` excuse
getExcuse :: String -> IO Excuses
getExcuse pkg = do
excuses <- readProcess "/usr/bin/grep-excuses" [pkg] ""
return $ Excuses pkg $ map (dropWhile isSpace) $ tail $ lines excuses
getSrcPackage :: String -> IO String
getSrcPackage bin = do
packageDesc <- readProcess "/usr/bin/apt-cache" ["showsrc", bin] ""
return $ parseDesc packageDesc
parseDesc :: String -> String
parseDesc desc = let ls = lines desc
srcln = findSourceLine ls
in removeFieldPrefix srcln
findSourceLine :: [String] -> String
findSourceLine (curLine:rest)
| "Package: " `isPrefixOf` curLine = curLine
| otherwise = findSourceLine rest
getBinBlockers :: [String] -> String -> [String]
getBinBlockers output package = let arches = getArches package output
in nub $ map stripComma
$ concat
$ map words
$ map removeFieldPrefix arches
where stripComma str = if last str == ','
then init str
else str
removeFieldPrefix :: String -> String
removeFieldPrefix arch = drop 2 $ dropWhile (/= ':') arch
getArches :: String -> [String] -> [String]
getArches package output = get $ removeStats $ fromJust $ findAutohint package output
where get (line:rest)
| line `matches` " *\\* .*:" = line : get rest
| otherwise = []
removeStats :: [String] -> [String]
removeStats = drop 4
findAutohint :: String -> [String] -> Maybe [String]
findAutohint _ [] = Nothing
findAutohint package (curLine:rest)
| curLine `matches` ("Trying easy from autohinter.*" ++ package)
= Just rest
| otherwise = findAutohint package rest
matches :: String -> String -> Bool
str `matches` pattern = (not . null) (str =~ pattern :: String)
Attachment:
signature.asc
Description: PGP signature