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