idePackageFromPath :: C.Sink ToolOutput IDEM () -> FilePath -> IDEM (Maybe IDEPackage)
idePackageFromPath log filePath = do
    mbRootPackage <- idePackageFromPath' filePath
    case mbRootPackage of
        Nothing -> return Nothing
        Just rootPackage -> do
            mvar <- liftIO newEmptyMVar
            let dir = takeDirectory filePath
            useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"
            paths <-
                if useStack
                    then liftIO $ map (dir </>) . extractStackPackageList <$> T.readFile (dir </> "stack.yaml")
                    else do
                        runExternalTool' "" "cabal" ["sandbox", "list-sources"] dir $ do
                            output <- CL.consume
                            liftIO . putMVar mvar $ case take 1 $ reverse output of
                                [ToolExit ExitSuccess] ->
                                    map (T.unpack . toolline) . takeWhile (/= ToolOutput "") . drop 1 $ dropWhile (/= ToolOutput "") output
                                _ -> []
                        liftIO $ takeMVar mvar

            sandboxSources <- catMaybes <$> forM paths (\path -> do
                exists <- liftIO (doesDirectoryExist path)
                if exists
                    then do
                        cpath <- liftIO $ canonicalizePath path
                        contents <- liftIO $ getDirectoryContents cpath
                        let mbCabalFile = find ((== ".cabal") . takeExtension) contents
                        when (isNothing mbCabalFile) $
                            ideMessage Normal ("Could not find cabal file of the add-source dependency at " <> T.pack cpath)
                        return (fmap (path </>) mbCabalFile)
                    else do
                        ideMessage Normal ("Path of add-source dependency does not exist: " <> T.pack path)
                        return Nothing)
            s <- liftM catMaybes . mapM idePackageFromPath' $ nub sandboxSources
            return . Just $ rootPackage {ipdSandboxSources = s}
idePackageFromPath :: C.Sink ToolOutput IDEM () -> FilePath -> IDEM (Maybe IDEPackage)
idePackageFromPath log filePath = do
    mbRootPackage <- idePackageFromPath' filePath
    case mbRootPackage of
        Nothing -> return Nothing
        Just rootPackage -> do
            mvar <- liftIO newEmptyMVar
            let dir = takeDirectory filePath
            useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"
            paths <-
                if useStack
                    then liftIO $ map (dir </>) . extractStackPackageList <$> T.readFile (dir </> "stack.yaml")
                    else do
                        runExternalTool' "" "cabal" ["sandbox", "list-sources"] dir $ do
                            output <- CL.consume
                            liftIO . putMVar mvar $ case take 1 $ reverse output of
                                [ToolExit ExitSuccess] ->
                                    map (T.unpack . toolline) . takeWhile (/= ToolOutput "") . drop 1 $ dropWhile (/= ToolOutput "") output
                                _ -> []
                        liftIO $ takeMVar mvar

            sandboxSources <- catMaybes <$> forM paths (\path -> do
                exists <- liftIO (doesDirectoryExist path)
                if exists
                    then do
                        cpath <- liftIO $ canonicalizePath path
                        contents <- liftIO $ getDirectoryContents cpath
                        let mbCabalFile = find ((== ".cabal") . takeExtension) contents
                        when (isNothing mbCabalFile) $
                            ideMessage Normal ("Could not find cabal file of the add-source dependency at " <> T.pack cpath)
                        return (fmap (path </>) mbCabalFile)
                    else do
                        ideMessage Normal ("Path of add-source dependency does not exist: " <> T.pack path)
                        return Nothing)
            s <- liftM catMaybes . mapM idePackageFromPath' $ nub sandboxSources
            return . Just $ rootPackage {ipdSandboxSources = s}
idePackageFromPath log filePath = do
    mbRootPackage <- idePackageFromPath' filePath
    case mbRootPackage of
        Nothing -> return Nothing
        Just rootPackage -> do
            mvar <- liftIO newEmptyMVar
            let dir = takeDirectory filePath
            useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"
            paths <-
                if useStack
                    then liftIO $ map (dir </>) . extractStackPackageList <$> T.readFile (dir </> "stack.yaml")
                    else do
                        runExternalTool' "" "cabal" ["sandbox", "list-sources"] dir $ do
                            output <- CL.consume
                            liftIO . putMVar mvar $ case take 1 $ reverse output of
                                [ToolExit ExitSuccess] ->
                                    map (T.unpack . toolline) . takeWhile (/= ToolOutput "") . drop 1 $ dropWhile (/= ToolOutput "") output
                                _ -> []
                        liftIO $ takeMVar mvar

            sandboxSources <- catMaybes <$> forM paths (\path -> do
                exists <- liftIO (doesDirectoryExist path)
                if exists
                    then do
                        cpath <- liftIO $ canonicalizePath path
                        contents <- liftIO $ getDirectoryContents cpath
                        let mbCabalFile = find ((== ".cabal") . takeExtension) contents
                        when (isNothing mbCabalFile) $
                            ideMessage Normal ("Could not find cabal file of the add-source dependency at " <> T.pack cpath)
                        return (fmap (path </>) mbCabalFile)
                    else do
                        ideMessage Normal ("Path of add-source dependency does not exist: " <> T.pack path)
                        return Nothing)
            s <- liftM catMaybes . mapM idePackageFromPath' $ nub sandboxSources
            return . Just $ rootPackage {ipdSandboxSources = s}