Skip to content

Commit

Permalink
Faster cabal update
Browse files Browse the repository at this point in the history
Contributed by Hideyuki Tanaka.
  • Loading branch information
tibbe committed Aug 11, 2012
1 parent 80cc9b6 commit 85ad9f8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
8 changes: 4 additions & 4 deletions cabal-install/Distribution/Client/Update.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import Distribution.Client.FetchUtils
import qualified Distribution.Client.PackageIndex as PackageIndex
import Distribution.Client.IndexUtils
( getSourcePackages, updateRepoIndexCache )
import Distribution.Client.Utils
( writeFileAtomic )
import qualified Paths_cabal_install
( version )

Expand All @@ -29,12 +31,11 @@ import Distribution.Package
import Distribution.Version
( anyVersion, withinRange )
import Distribution.Simple.Utils
( warn, notice, writeFileAtomic )
( warn, notice )
import Distribution.Verbosity
( Verbosity )

import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.Char8 as BS.Char8
import Distribution.Client.GZipUtils (maybeDecompress)
import qualified Data.Map as Map
import System.FilePath (dropExtension)
Expand All @@ -57,8 +58,7 @@ updateRepo verbosity repo = case repoKind repo of
notice verbosity $ "Downloading the latest package list from "
++ remoteRepoName remoteRepo
indexPath <- downloadIndex verbosity remoteRepo (repoLocalDir repo)
writeFileAtomic (dropExtension indexPath) . BS.Char8.unpack
. maybeDecompress
writeFileAtomic (dropExtension indexPath) . maybeDecompress
=<< BS.readFile indexPath
updateRepoIndexCache verbosity repo

Expand Down
30 changes: 27 additions & 3 deletions cabal-install/Distribution/Client/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@

module Distribution.Client.Utils ( MergeResult(..)
, mergeBy, duplicates, duplicatesBy
, moreRecentFile, inDir, numberOfProcessors )
, moreRecentFile, inDir, numberOfProcessors
, writeFileAtomic )
where

import Data.List
( sortBy, groupBy )
import Foreign.C.Types ( CInt(..) )
import System.Directory
( doesFileExist, getModificationTime
, getCurrentDirectory, setCurrentDirectory )
, getCurrentDirectory, setCurrentDirectory
, renameFile, removeFile )
import System.FilePath ( splitFileName, (<.>) )
import System.IO ( openBinaryTempFile, hClose )
import System.IO.Unsafe ( unsafePerformIO )
import qualified Control.Exception as Exception
( finally )
( bracketOnError, finally )
import qualified Data.ByteString.Lazy as BS

-- | Generic merging utility. For sorted input lists this is a full outer join.
--
Expand Down Expand Up @@ -72,3 +77,22 @@ foreign import ccall "getNumberOfProcessors" c_getNumberOfProcessors :: IO CInt
-- program, so unsafePerformIO is safe here.
numberOfProcessors :: Int
numberOfProcessors = fromEnum $ unsafePerformIO c_getNumberOfProcessors

-- | Writes a file atomically.
--
-- The file is either written sucessfully or an IO exception is raised and
-- the original file is left unchanged.
--
-- On windows it is not possible to delete a file that is open by a process.
-- This case will give an IO exception but the atomic property is not affected.
--
writeFileAtomic :: FilePath -> BS.ByteString -> IO ()
writeFileAtomic targetPath content = do
let (targetDir, targetFile) = splitFileName targetPath
Exception.bracketOnError
(openBinaryTempFile targetDir $ targetFile <.> "tmp")
(\(tmpPath, handle) -> hClose handle >> removeFile tmpPath)
(\(tmpPath, handle) -> do
BS.hPut handle content
hClose handle
renameFile tmpPath targetPath)

0 comments on commit 85ad9f8

Please sign in to comment.