Ticket #1839: Main.hs.diff
| File Main.hs.diff, 10.7 KB (added by guest, 5 years ago) |
|---|
-
utils/ghc-pkg/Main.hs
old new 46 46 import System ( getArgs, getProgName, getEnv, exitWith, ExitCode(..) ) 47 47 import System.IO 48 48 import System.IO.Error (try) 49 import Data.List ( isPrefixOf, isSuffixOf, intersperse, sortBy ) 49 import Data.List ( isPrefixOf, isSuffixOf, intersperse, sortBy, unfoldr, break ) 50 import Text.Regex 50 51 51 52 #ifdef mingw32_HOST_OS 52 53 import Foreign … … 100 101 | FlagDefinedName String String 101 102 | FlagSimpleOutput 102 103 | FlagNamesOnly 104 | FlagBulkQueries 103 105 deriving Eq 104 106 105 107 flags :: [OptDescr Flag] … … 127 129 Option [] ["simple-output"] (NoArg FlagSimpleOutput) 128 130 "print output in easy-to-parse format for some commands", 129 131 Option [] ["names-only"] (NoArg FlagNamesOnly) 130 "only print package names, not versions; can only be used with list --simple-output" 132 "only print package names, not versions; can only be used with list --simple-output", 133 Option [] ["bulk"] (NoArg FlagBulkQueries) 134 "enable bulk queries" 131 135 ] 132 136 where 133 137 toDefined str = … … 162 166 " $p list [pkg]\n" ++ 163 167 " List registered packages in the global database, and also the\n" ++ 164 168 " user database if --user is given. If a package name is given\n" ++ 165 " all the registered versions will be listed in ascending order.\n" ++ 169 " All the registered versions will be listed in ascending order.\n" ++ 170 " Accepts package patterns if --bulk is given.\n" ++ 171 " Accepts the --simple-output flag.\n" ++ 172 "\n" ++ 173 " $p find-module {module}\n" ++ 174 " List registered packages exposing module {module} in the global\n" ++ 175 " database, and also the user database if --user is given. \n" ++ 176 " All the registered versions will be listed in ascending order.\n" ++ 177 " Accepts module patterns if --bulk is given.\n" ++ 166 178 " Accepts the --simple-output flag.\n" ++ 167 179 "\n" ++ 168 180 " $p latest pkg\n" ++ … … 175 187 " $p describe {pkg-id}\n" ++ 176 188 " Give the registered description for the specified package. The\n" ++ 177 189 " description is returned in precisely the syntax required by $p\n" ++ 178 " register. \n" ++190 " register. Accepts package patterns if --bulk is given.\n" ++ 179 191 "\n" ++ 180 192 " $p field {pkg-id} {field}\n" ++ 181 193 " Extract the specified field of the package description for the\n" ++ 182 " specified package.\n" ++ 194 " specified package. Accepts package patterns and comma-separated\n" ++ 195 " multiple fields if --bulk is given.\n" ++ 183 196 "\n" ++ 184 197 " The following optional flags are also accepted:\n" 185 198 … … 193 206 194 207 data Force = ForceAll | ForceFiles | NoForce 195 208 209 data PackageArg = Id PackageIdentifier | Pattern String 210 196 211 runit :: [Flag] -> [String] -> IO () 197 212 runit cli nonopts = do 198 213 prog <- getProgramName … … 203 218 | otherwise = NoForce 204 219 auto_ghci_libs = FlagAutoGHCiLibs `elem` cli 205 220 defines = [ (nm,val) | FlagDefinedName nm val <- cli ] 221 splitFields fields = unfoldr splitComma (',':fields) 222 where splitComma "" = Nothing 223 splitComma fs = Just $ break (==',') (tail fs) 206 224 -- 207 225 -- first, parse the command 208 226 case nonopts of … … 220 238 pkgid <- readGlobPkgId pkgid_str 221 239 hidePackage pkgid cli 222 240 ["list"] -> do 223 listPackages cli Nothing 241 listPackages cli Nothing Nothing 242 ["list", pkgid_pattern_str] | FlagBulkQueries `elem` cli -> do 243 listPackages cli (Just (Pattern pkgid_pattern_str)) Nothing 224 244 ["list", pkgid_str] -> do 225 245 pkgid <- readGlobPkgId pkgid_str 226 listPackages cli (Just pkgid) 246 listPackages cli (Just (Id pkgid)) Nothing 247 ["find-module", moduleName] -> do 248 listPackages cli Nothing (Just moduleName) 227 249 ["latest", pkgid_str] -> do 228 250 pkgid <- readGlobPkgId pkgid_str 229 251 latestPackage cli pkgid 252 ["describe", pkgid_pattern_str] | FlagBulkQueries `elem` cli -> do 253 describePackage cli (Pattern pkgid_pattern_str) 230 254 ["describe", pkgid_str] -> do 231 255 pkgid <- readGlobPkgId pkgid_str 232 describePackage cli pkgid 256 describePackage cli (Id pkgid) 257 ["field", pkgid_pattern_str, fields] | FlagBulkQueries `elem` cli -> do 258 describeField cli (Pattern pkgid_pattern_str) (splitFields fields) 233 259 ["field", pkgid_str, field] -> do 234 260 pkgid <- readGlobPkgId pkgid_str 235 describeField cli pkgid field261 describeField cli (Id pkgid) [field] 236 262 ["check"] -> do 237 263 checkConsistency cli 238 264 [] -> do … … 445 471 modifyPackage fn pkgid flags = do 446 472 db_stack <- getPkgDatabases True{-modify-} flags 447 473 let ((db_name, pkgs) : _) = db_stack 448 ps <- findPackages [(db_name,pkgs)] pkgid474 ps <- findPackages [(db_name,pkgs)] (Id pkgid) 449 475 let pids = map package ps 450 476 let new_config = concat (map modify pkgs) 451 477 modify pkg … … 457 483 -- ----------------------------------------------------------------------------- 458 484 -- Listing packages 459 485 460 listPackages :: [Flag] -> Maybe Package Identifier-> IO ()461 listPackages flags mPackageName = do486 listPackages :: [Flag] -> Maybe PackageArg -> Maybe String -> IO () 487 listPackages flags mPackageName mModuleName = do 462 488 let simple_output = FlagSimpleOutput `elem` flags 463 489 db_stack <- getPkgDatabases False flags 464 490 let db_stack_filtered -- if a package is given, filter out all other packages 465 491 | Just this <- mPackageName = 466 492 map (\(conf,pkgs) -> (conf, filter (this `matchesPkg`) pkgs)) 467 493 db_stack 494 | Just this <- mModuleName = -- packages which expose mModuleName 495 map (\(conf,pkgs) -> (conf, filter (this `exposedInPkg`) pkgs)) 496 db_stack 468 497 | otherwise = db_stack 469 498 470 499 db_stack_sorted … … 501 530 when (null pkgs) $ die "no matches" 502 531 hPutStrLn stdout $ concat $ intersperse " " pkgs 503 532 533 exposedInPkg :: String -> InstalledPackageInfo -> Bool 534 moduleName `exposedInPkg` pkg | FlagBulkQueries `elem` flags 535 = any (isJust . (mkRegex moduleName `matchRegex`)) (exposedModules pkg) 536 moduleName `exposedInPkg` pkg 537 = moduleName `elem` exposedModules pkg 538 539 504 540 -- ----------------------------------------------------------------------------- 505 541 -- Prints the highest (hidden or exposed) version of a package 506 542 507 543 latestPackage :: [Flag] -> PackageIdentifier -> IO () 508 544 latestPackage flags pkgid = do 509 545 db_stack <- getPkgDatabases False flags 510 ps <- findPackages db_stack pkgid546 ps <- findPackages db_stack (Id pkgid) 511 547 show_pkg (sortBy compPkgIdVer (map package ps)) 512 548 where 513 549 show_pkg [] = die "no matches" … … 516 552 -- ----------------------------------------------------------------------------- 517 553 -- Describe 518 554 519 describePackage :: [Flag] -> Package Identifier-> IO ()520 describePackage flags pkg id= do555 describePackage :: [Flag] -> PackageArg -> IO () 556 describePackage flags pkgarg = do 521 557 db_stack <- getPkgDatabases False flags 522 ps <- findPackages db_stack pkg id558 ps <- findPackages db_stack pkgarg 523 559 mapM_ (putStrLn . showInstalledPackageInfo) ps 524 560 525 561 -- PackageId is can have globVersion for the version 526 findPackages :: PackageDBStack -> Package Identifier-> IO [InstalledPackageInfo]527 findPackages db_stack pkg id528 = case [ p | p <- all_pkgs, pkg id`matchesPkg` p ] of529 [] -> die ("cannot find package " ++ showPackageId pkgid)562 findPackages :: PackageDBStack -> PackageArg -> IO [InstalledPackageInfo] 563 findPackages db_stack pkgarg 564 = case [ p | p <- all_pkgs, pkgarg `matchesPkg` p ] of 565 [] -> die ("cannot find package " ++ pkg_msg pkgarg) 530 566 ps -> return ps 531 567 where 532 568 all_pkgs = concat (map snd db_stack) 569 pkg_msg (Id pkgid) = showPackageId pkgid 570 pkg_msg (Pattern pkgpat) = "matching "++pkgpat 533 571 534 572 matches :: PackageIdentifier -> PackageIdentifier -> Bool 535 573 pid `matches` pid' 536 574 = (pkgName pid == pkgName pid') 537 575 && (pkgVersion pid == pkgVersion pid' || not (realVersion pid)) 538 576 539 matchesPkg :: PackageIdentifier -> InstalledPackageInfo -> Bool 540 pid `matchesPkg` pkg = pid `matches` package pkg 577 pat_matches :: String -> PackageIdentifier -> Bool 578 pat `pat_matches` pid 579 = maybe False (const True) (mkRegex pat `matchRegex` pkgName pid) 580 581 matchesPkg :: PackageArg -> InstalledPackageInfo -> Bool 582 (Id pid) `matchesPkg` pkg = pid `matches` package pkg 583 (Pattern pat) `matchesPkg` pkg = pat `pat_matches` package pkg 541 584 542 585 compPkgIdVer :: PackageIdentifier -> PackageIdentifier -> Ordering 543 586 compPkgIdVer p1 p2 = pkgVersion p1 `compare` pkgVersion p2 … … 545 588 -- ----------------------------------------------------------------------------- 546 589 -- Field 547 590 548 describeField :: [Flag] -> Package Identifier -> String-> IO ()549 describeField flags pkg id field= do591 describeField :: [Flag] -> PackageArg -> [String] -> IO () 592 describeField flags pkgarg fields = do 550 593 db_stack <- getPkgDatabases False flags 551 case toField field of 552 Nothing -> die ("unknown field: " ++ field) 553 Just fn -> do 554 ps <- findPackages db_stack pkgid 555 let top_dir = takeDirectory (fst (last db_stack)) 556 mapM_ (putStrLn . fn) (mungePackagePaths top_dir ps) 594 fns <- toFields fields 595 ps <- findPackages db_stack pkgarg 596 let top_dir = takeDirectory (fst (last db_stack)) 597 mapM_ (selectFields fns) (mungePackagePaths top_dir ps) 598 where toFields [] = return [] 599 toFields (f:fs) = case toField f of 600 Nothing -> die ("unknown field: " ++ f) 601 Just fn -> do fns <- toFields fs 602 return (fn:fns) 603 selectFields fns info = mapM_ (\fn->putStrLn (fn info)) fns 557 604 558 605 mungePackagePaths :: String -> [InstalledPackageInfo] -> [InstalledPackageInfo] 559 606 -- Replace the strings "$topdir" and "$httptopdir" at the beginning of a path … … 947 994 defines = [ (nm,val) | OF_DefinedName nm val <- clis ] 948 995 949 996 case [ c | c <- clis, isAction c ] of 950 [ OF_List ] -> listPackages new_flags Nothing 951 [ OF_ListLocal ] -> listPackages new_flags Nothing 997 [ OF_List ] -> listPackages new_flags Nothing Nothing 998 [ OF_ListLocal ] -> listPackages new_flags Nothing Nothing 952 999 [ OF_Add upd ] -> 953 1000 registerPackage input_file defines new_flags auto_ghci_libs upd force 954 1001 [ OF_Remove pkgid_str ] -> do … … 957 1004 [ OF_Show pkgid_str ] 958 1005 | null fields -> do 959 1006 pkgid <- readPkgId pkgid_str 960 describePackage new_flags pkgid1007 describePackage new_flags (Id pkgid) 961 1008 | otherwise -> do 962 1009 pkgid <- readPkgId pkgid_str 963 mapM_ (describeField new_flags pkgid) fields1010 mapM_ (describeField new_flags (Id pkgid)) [fields] 964 1011 _ -> do 965 1012 prog <- getProgramName 966 1013 die (usageInfo (usageHeader prog) flags)
