import System.Environment ( getArgs, getProgName, getEnv )
import System.IO
import System.IO.Error (try)
-import Data.List ( isPrefixOf, isSuffixOf, intersperse, sortBy, nub,
- unfoldr, break, partition )
-#if __GLASGOW_HASKELL__ > 604
-import Data.List ( isInfixOf )
-#else
-import Data.List ( tails )
-#endif
+import Data.List
import Control.Concurrent
#ifdef mingw32_HOST_OS
import System.Posix
#endif
-import IO ( isPermissionError, isDoesNotExistError )
+import IO ( isPermissionError )
#if defined(GLOB)
import System.Process(runInteractiveCommand)
user_conf = dir </> subdir </> "package.conf"
user_exists <- doesFileExist user_conf
return (Just (user_conf,user_exists))
- Left ex ->
+ Left _ ->
return Nothing
-- If the user database doesn't exist, and this command isn't a
Right path
| last cs == "" -> init cs ++ sys_databases
| otherwise -> cs
- where cs = splitSearchPath path
+ where cs = parseSearchPath path
-- The "global" database is always the one at the bottom of the stack.
-- This is the database we modify by default.
let db_flags = [ f | Just f <- map is_db_flag my_flags ]
where is_db_flag FlagUser
- | Just (user_conf,user_exists) <- mb_user_conf
+ | Just (user_conf, _user_exists) <- mb_user_conf
= Just user_conf
is_db_flag FlagGlobal = Just virt_global_conf
is_db_flag (FlagConfig f) = Just f
-> Force
-> IO ()
modifyPackage fn pkgid my_flags force = do
- (db_stack, Just to_modify) <- getPkgDatabases True{-modify-} my_flags
+ (db_stack, Just _to_modify) <- getPkgDatabases True{-modify-} my_flags
((db_name, pkgs), ps) <- fmap head $ findPackagesByDB db_stack (Id pkgid)
-- let ((db_name, pkgs) : rest_of_stack) = db_stack
-- ps <- findPackages [(db_name,pkgs)] (Id pkgid)
let
old_broken = brokenPackages (allPackagesInStack db_stack)
- rest_of_stack = [ (nm,pkgs) | (nm,pkgs) <- db_stack, nm /= db_name ]
+ rest_of_stack = [ (nm, mypkgs)
+ | (nm, mypkgs) <- db_stack, nm /= db_name ]
new_stack = (db_name,new_config) : rest_of_stack
new_broken = map package (brokenPackages (allPackagesInStack new_stack))
newly_broken = filter (`notElem` map package old_broken) new_broken
-> IO [(NamedPackageDB, [InstalledPackageInfo])]
findPackagesByDB db_stack pkgarg
= case [ (db, matched)
- | db@(db_name,pkgs) <- db_stack,
+ | db@(_, pkgs) <- db_stack,
let matched = filter (pkgarg `matchesPkg`) pkgs,
not (null matched) ] of
[] -> die ("cannot find package " ++ pkg_msg pkgarg)
where
go avail not_avail =
case partition (depsAvailable avail) not_avail of
- ([], not_avail) -> not_avail
- (new_avail, not_avail) -> go (new_avail ++ avail) not_avail
+ ([], not_avail') -> not_avail'
+ (new_avail, not_avail') -> go (new_avail ++ avail) not_avail'
depsAvailable :: [InstalledPackageInfo] -> InstalledPackageInfo
-> Bool
checkPackageId pkg
checkDuplicates db_stack pkg update force
mapM_ (checkDep db_stack force) (depends pkg)
+ checkDuplicateDepends force (depends pkg)
mapM_ (checkDir force) (importDirs pkg)
mapM_ (checkDir force) (libraryDirs pkg)
mapM_ (checkDir force) (includeDirs pkg)
all_pkgs = allPackagesInStack db_stack
pkgids = map package all_pkgs
+checkDuplicateDepends :: Force -> [PackageIdentifier] -> IO ()
+checkDuplicateDepends force deps
+ | null dups = return ()
+ | otherwise = dieOrForceAll force ("package has duplicate dependencies: " ++
+ unwords (map display dups))
+ where
+ dups = [ p | (p:_:_) <- group (sort deps) ]
+
realVersion :: PackageIdentifier -> Bool
realVersion pkgid = versionBranch (pkgVersion pkgid) /= []
handler' e = Exception.throw e
#endif
+#if mingw32_HOST_OS || mingw32_TARGET_OS
throwIOIO :: Exception.IOException -> IO a
#if __GLASGOW_HASKELL__ >= 609
throwIOIO = Exception.throwIO
#else
throwIOIO ioe = Exception.throwIO (Exception.IOException ioe)
#endif
+#endif
catchError :: IO a -> (String -> IO a) -> IO a
#if __GLASGOW_HASKELL__ >= 609
--TODO: remove this when takeDirectory/splitFileName is fixed
-- to always return a valid dir
(targetDir_,targetName) = splitFileName targetFile
+
+-- | The function splits the given string to substrings
+-- using 'isSearchPathSeparator'.
+parseSearchPath :: String -> [FilePath]
+parseSearchPath path = split path
+ where
+ split :: String -> [String]
+ split s =
+ case rest' of
+ [] -> [chunk]
+ _:rest -> chunk : split rest
+ where
+ chunk =
+ case chunk' of
+#ifdef mingw32_HOST_OS
+ ('\"':xs@(_:_)) | last xs == '\"' -> init xs
+#endif
+ _ -> chunk'
+
+ (chunk', rest') = break isSearchPathSeparator s