packages feed

gitrev (empty) → 1.0.0

raw patch · 4 files changed

+161/−0 lines, 4 filesdep +basedep +directorydep +filepathsetup-changed

Dependencies added: base, directory, filepath, process, template-haskell

Files

+ LICENSE view
@@ -0,0 +1,28 @@+Copyright (c) 2015, Adam C. Foltzer+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+  list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+  this list of conditions and the following disclaimer in the documentation+  and/or other materials provided with the distribution.++* Neither the name of gitrev nor the names of its+  contributors may be used to endorse or promote products derived from+  this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ gitrev.cabal view
@@ -0,0 +1,26 @@+name:                gitrev+version:             1.0.0+synopsis:            Compile git revision info into Haskell projects+homepage:            https://github.com/acfoltzer/gitrev+license:             BSD3+license-file:        LICENSE+author:              Adam C. Foltzer+maintainer:          acfoltzer@galois.com+category:            Development+build-type:          Simple+cabal-version:       >=1.10+description:         Some handy Template Haskell splices for including the current git hash and branch in the code of your project. Useful for including in panic messages, @--version@ output, or diagnostic info for more informative bug reports.++source-repository head+  type:     git+  location: https://github.com/acfoltzer/gitrev.git++library+  build-depends:       base >= 4.7 && < 5,+                       directory,+                       filepath,+                       template-haskell,+                       process+  hs-source-dirs:      src+  default-language:    Haskell2010+  exposed-modules:     Development.GitRev
+ src/Development/GitRev.hs view
@@ -0,0 +1,105 @@+-- |+-- Module      :  $Header$+-- Copyright   :  (c) 2015 Adam C. Foltzer+-- License     :  BSD3+-- Maintainer  :  acfoltzer@galois.com+-- Stability   :  provisional+-- Portability :  portable+--+-- Some handy Template Haskell splices for including the current git+-- hash and branch in the code of your project. Useful for including+-- in panic messages, @--version@ output, or diagnostic info for more+-- informative bug reports.+--+-- > {-# LANGUAGE TemplateHaskell #-}+-- > import Development.GitRev+-- >+-- > panic :: String -> a+-- > panic msg = error panicMsg+-- >   where panicMsg =+-- >           concat [ "[panic ", $(gitBranch), "@", $(gitHash), dirty, "] ", msg ]+-- >         dirty | $(gitDirty) = " (uncommitted files present)"+-- >               | otherwise   = ""+-- >+-- > main = panic "oh no!"+--+-- > % cabal exec runhaskell Example.hs+-- > Example.hs: [panic master@4a0a592c37ad908889bd2a7a411923a903ed05a3 (uncommitted files present)] oh no!++module Development.GitRev (gitHash, gitBranch, gitDirty) where++import Control.Applicative+import Control.Exception+import Control.Monad+import Data.Maybe+import Language.Haskell.TH+import Language.Haskell.TH.Syntax+import System.Directory+import System.Exit+import System.FilePath+import System.Process++-- | Run git with the given arguments and no stdin, returning the+-- stdout output. If git isn't available or something goes wrong,+-- return the second argument.+runGit :: [String] -> String -> Q String+runGit args def = do+  let oops :: SomeException -> IO (ExitCode, String, String)+      oops _e = return (ExitFailure 1, def, "")+  gitFound <- runIO $ isJust <$> findExecutable "git"+  if gitFound+    then do+      -- a lot of bookkeeping to record the right dependencies+      pwd <- runIO getCurrentDirectory+      let hd         = pwd </> ".git" </> "HEAD"+          index      = pwd </> ".git" </> "index"+          packedRefs = pwd </> ".git" </> "packed-refs"+      hdExists  <- runIO $ doesFileExist hd+      when hdExists $ do+        -- the HEAD file either contains the hash of a detached head+        -- or a pointer to the file that contains the hash of the head+        hdRef <- runIO $ readFile hd+        case splitAt 5 hdRef of+          -- pointer to ref+          ("ref: ", relRef) -> do+            let ref = pwd </> ".git" </> relRef+            refExists <- runIO $ doesFileExist ref+            when refExists $ addDependentFile ref+          -- detached head+          _hash -> addDependentFile hd+      -- add the index if it exists to set the dirty flag+      indexExists <- runIO $ doesFileExist index+      when indexExists $ addDependentFile index+      -- if the refs have been packed, the info we're looking for+      -- might be in that file rather than the one-file-per-ref case+      -- handled above+      packedExists <- runIO $ doesFileExist packedRefs+      when packedExists $ addDependentFile packedRefs+      runIO $ do+        (code, out, _err) <- readProcessWithExitCode "git" args "" `catch` oops+        case code of+          ExitSuccess   -> return (takeWhile (/= '\n') out)+          ExitFailure _ -> return def+    else return def++-- | Return the hash of the current git commit, or @UNKNOWN@ if not in+-- a git repository+gitHash :: ExpQ+gitHash =+  stringE =<< runGit ["rev-parse", "HEAD"] "UNKNOWN"++-- | Return the branch (or tag) name of the current git commit, or @UNKNOWN@+-- if not in a git repository. For detached heads, this will just be+-- "HEAD"+gitBranch :: ExpQ+gitBranch =+  stringE =<< runGit ["rev-parse", "--abbrev-ref", "HEAD"] "UNKNOWN"++-- | Return @True@ if there are non-committed files present in the+-- repository+gitDirty :: ExpQ+gitDirty = do+  output <- runGit ["status", "--porcelain"] ""+  case output of+    "" -> conE $ mkName "Prelude.False"+    _  -> conE $ mkName "Prelude.True"