Permalink
Browse files

code drop

  • Loading branch information...
0 parents commit 6e84a89a2903618fea6457beb2c6ef2d6aa1c2d9 @gregwebs gregwebs committed Mar 2, 2012
Showing with 151 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +25 −0 LICENSE
  3. +38 −0 README.md
  4. +28 −0 cabal-meta.cabal
  5. +59 −0 cabal-meta.hs
@@ -0,0 +1 @@
+dist/
@@ -0,0 +1,25 @@
+The following license covers this documentation, and the source code, except
+where otherwise indicated.
+
+Copyright 2010, Michael Snoyman. 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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "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 HOLDERS 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.
@@ -0,0 +1,38 @@
+If you run this command, you can easily get a failure:
+
+ cabal install foo && cabal install bar
+
+ Whereas if you run this command it should almost always work:
+
+ cabal install foo bar
+
+cabal-meta facilitates installing everything at once.
+When invoked, it looks for a file `sources.txt`.
+Each line of `sources.txt` is either a directory to install or contains another `sources.txt` to recurse into.
+cabal-meta won't continue to recurse if a cabal file is found.
+cabal-meta automatically uses cabal-src-install also.
+
+
+# Example
+
+To build a Yesod web application using the source from github, I have a sources.txt in my project consisting of
+
+ ./
+ path/to/yesod/sources
+
+`./` means the current project
+`path/to/yesod/sources` contains a `sources.txt` with:
+
+ hamlet
+ persistent
+ wai
+ yesod
+
+Each of these directories have a `sources.txt` listing several dirctories containing cabal packages.
+
+Confused? It is just recursion, although we are interleaving IO :)
+
+
+# TODO
+
+* support github and tar.gz urls: this lets us do beta releases and work with hackage
@@ -0,0 +1,28 @@
+name: cabal-meta
+version: 0.0
+license: BSD3
+license-file: LICENSE
+author: Greg Weber <greg@gregweber.info>
+maintainer: Greg Weber <greg@gregweber.info>
+synopsis: build multiple packages at once
+description: build multiple packages at once
+
+stability: Beta
+cabal-version: >= 1.8
+build-type: Simple
+homepage: http://www.yesodweb.com/
+
+flag ghc7
+
+executable cabal-meta
+ main-is: cabal-meta.hs
+
+ if flag(ghc7)
+ build-depends: base >= 4.3 && < 5
+ cpp-options: -DGHC7
+ else
+ build-depends: base >= 4 && < 4.3
+ build-depends: shelly, filepath, text
+
+ ghc-options: -Wall
+
@@ -0,0 +1,59 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+-- TODO:
+-- * use --only-dependencies. otherwise a simple build failure will prevent a cabal-src-install
+-- support git & tar.gz urls
+
+import Shelly
+import Data.Text.Lazy (Text, pack, unpack)
+import qualified Data.Text.Lazy as LT
+import Control.Monad (forM, forM_, when)
+import System.Environment (getArgs)
+import System.FilePath (takeExtension)
+
+source_file :: FilePath
+source_file = "sources.txt"
+
+cabal_install :: [Text] -> ShIO Text
+cabal_install = command "cabal" ["install"]
+
+headDef :: a -> [a] -> a
+headDef d [] = d
+headDef _ (x:_) = x
+
+main :: IO ()
+main = do
+ args <- fmap (map pack) getArgs
+ shelly $ verbosely $ do
+ pkgs <- readPackages True $ headDef "." args
+ echo "Installing packages:"
+ forM_ pkgs echo
+ _<-cabal_install pkgs
+ forM_ pkgs $ \pkg ->
+ chdir (unpack pkg) $ "cabal-src-install" # ["--src-only"]
+ return ()
+
+readPackages :: Bool -> Text -> ShIO [Text]
+readPackages allowCabals dir = do
+ fullDir <- path (unpack dir)
+ chdir fullDir $ do
+ cabalPresent <- if allowCabals then return False else isCabalPresent
+ if cabalPresent then return [] else do
+ pkgs <- getSources
+ child_pkgs <- forM pkgs $ \pkg -> do
+ b <- fmap (== fullDir) (path $ unpack pkg)
+ if b then return [] else readPackages False pkg
+ return $ concatMap (\(p, ps) -> if null ps then [p] else ps) $ zip pkgs child_pkgs
+ where
+ isCabalFile f = ".cabal" == takeExtension f
+ isCabalPresent = do
+ cabals <- fmap (filter isCabalFile) $ ls "."
+ return $ not $ null cabals
+
+ getSources :: ShIO [Text]
+ getSources = do
+ relative_pkgs <- fmap LT.lines $ readfile source_file
+ when (null relative_pkgs) $ error $ "empty " ++ source_file
+ mapM (liftAsString path) relative_pkgs
+ where
+ liftAsString f = fmap pack . f . unpack

0 comments on commit 6e84a89

Please sign in to comment.