packages feed

multi-cabal (empty) → 0.1.0.0

raw patch · 15 files changed

+519/−0 lines, 15 filesdep +AAIdep +HUnitdep +aesonsetup-changed

Dependencies added: AAI, HUnit, aeson, base, bytestring, directory, filepath, mtl, multi-cabal, process, strict, test-framework, test-framework-hunit

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Nils 'bash0r' Jonsson++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,1 @@+# multi-cabal
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ changelog.md view
@@ -0,0 +1,4 @@+# v0.1.0.0++Initial release.+
+ multi-cabal.cabal view
@@ -0,0 +1,58 @@+name:                   multi-cabal+version:                0.1.0.0+synopsis:               A tool supporting multi cabal project builds.+description:            A tool supporting multi cabal project builds.+homepage:               https://github.com/aka-bash0r/multi-cabal+license:                MIT+license-file:           LICENSE+author:                 Nils 'bash0r' Jonsson+maintainer:             aka.bash0r@gmail.com+-- copyright:           +category:               Development+build-type:             Simple+extra-source-files:     LICENSE+                  ,     README.md+                  ,     changelog.md+cabal-version:          >=1.10++library+  exposed-modules:      Data.Model.Project+                 ,      Data.Model.Utility+                 ,      Logic.Dependency.Resolution+  build-depends:        base        >=4.8  && <4.9+               ,        aeson       >=0.9  && <0.10+               ,        filepath    >=1.4  && <1.5+               ,        mtl         >=2.2  && <2.3+  hs-source-dirs:       src-lib+  default-language:     Haskell2010 ++executable multi-cabal+  main-is:              Main.hs+  other-modules:        MultiCabal.Commands+               ,        MultiCabal.Commands.Help+               ,        MultiCabal.Commands.Install+               ,        MultiCabal.Commands.Version+               ,        MultiCabal.Instruction+               ,        Paths_multi_cabal+  build-depends:        base        >=4.8  && <4.9+               ,        aeson       >=0.9  && <0.10+               ,        filepath    >=1.4  && <1.5+               ,        directory   >=1.2  && <1.3+               ,        bytestring  >=0.10 && <0.11+               ,        process     >=1.2  && <1.3+               ,        strict      >=0.3  && <0.4+               ,        AAI         >=0.2  && <0.3+               ,        multi-cabal+  hs-source-dirs:       src+  default-language:     Haskell2010++Test-Suite multi-cabal-tests+  type:                 exitcode-stdio-1.0+  main-is:              Main.hs+  hs-source-dirs:       src-test+  build-depends:        base        >=4.8 && <4.9+               ,        test-framework+               ,        test-framework-hunit+               ,        HUnit+               ,        multi-cabal+
+ src-lib/Data/Model/Project.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE OverloadedStrings #-}++{- |+Module      :  $Header$+Description :  ADT describing a project.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++A simple ADT describing a project.+-}+module Data.Model.Project+( Project (..)+) where++import Data.Aeson+import Data.Model.Utility+++-- | A representation of a project.+data Project+    -- | A basic representation of a project.    +    = Project ProjectName ProjectRoot [ProjectName]+    deriving (Show, Eq)+++instance ToJSON Project where+    toJSON (Project pName pDirectory pDependencies) =+      object [ "name"         .= pName+             , "root"         .= pDirectory+             , "dependencies" .= pDependencies+             ]++instance FromJSON Project where+    parseJSON = withObject "Project Description" $ \o ->+      Project <$> o .: "name"+              <*> o .: "root"+              <*> o .: "dependencies"+
+ src-lib/Data/Model/Utility.hs view
@@ -0,0 +1,27 @@+{- |+Module      :  $Header$+Description :  A collection of utility declarations.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++A collection of utility declarations.+-}+module Data.Model.Utility+( ProjectName+, ProjectRoot+) where++import System.FilePath.Posix+++-- | The name of a project.+type ProjectName = String++-- | The root directory of the project.+type ProjectRoot = FilePath+
+ src-lib/Logic/Dependency/Resolution.hs view
@@ -0,0 +1,87 @@+{-# LANGUAGE FlexibleContexts #-}++{- |+Module      :  $Header$+Description :  Contains dependency resolution algorithms.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++This module contains all dependency resolution algorithms.+-}+module Logic.Dependency.Resolution+( resolve+) where++import Control.Applicative+import Control.Monad+import Control.Monad.State.Lazy++import Data.List+import Data.Model.Project+import Data.Model.Utility+++resolve :: [Project] -> Maybe [Project]+resolve =+    evalState resolver++resolver =+    findRootProjects >>= (resolveProjects . reverse)++findRootProjects :: State [Project] [Project]+findRootProjects = do+    xs <- get+    let (rootProjects,remaining) = findRootProjects' xs [] []+    put remaining+    return rootProjects+  where+    hasDependencies (Project _ _ []) =+      False+    hasDependencies (Project {}    ) =+      True++    findRootProjects' []     rp rem =+      (reverse rp, reverse rem)+    findRootProjects' (x:xs) rp rem =+      if hasDependencies x+         then findRootProjects' xs rp     (x:rem)+         else findRootProjects' xs (x:rp) rem++resolveProjects :: [Project] -> State [Project] (Maybe [Project])+resolveProjects rs =+    resolveProjects' rs >>= \res -> return (fmap reverse res)+  where+    resolveProjects' :: [Project] -> State [Project] (Maybe [Project])+    resolveProjects' rs = do+      xs <- get+      if null xs+         then (return . return) rs+         else do+           let (rs', xs') = traverse xs rs []+           put xs'+           if genericLength xs == genericLength xs'+              then return empty+              else resolveProjects' rs'++    traverse []                         rs rem =+      (rs, rem)+    traverse (x@(Project name _ ds):xs) rs rem =+      if rs `hasDependencies` ds+         then traverse xs (x:rs) rem+         else traverse xs rs     (x:rem)++    hasDependencies _  []     =+      True+    hasDependencies rs (d:ds) =+      d `isContainedIn` rs && rs `hasDependencies` ds++    isContainedIn d []                     =+      False+    isContainedIn d (Project name _ _ :xs) =+      d == name || d `isContainedIn` xs+
+ src-test/Main.hs view
@@ -0,0 +1,28 @@+{- |+Module      :  $Header$+Description :  Entrypoint of the application.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++The 'Main' module is the entrypoint of the application.+-}+module Main+( main+) where++import Test.HUnit+import Test.Framework+import Test.Framework.Providers.HUnit++import qualified Tests.Dependencies as TD++main :: IO ()+main = defaultMainWithOpts tests mempty++tests = [ TD.tests ]+
+ src/Main.hs view
@@ -0,0 +1,38 @@+{- |+Module      :  $Header$+Description :  Entrypoint of the application.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++The 'Main' module is the entrypoint of the application.+-}+module Main+( main+) where++import Control.Applicative+import Control.Command+import Control.Monad+import Control.Router++import System.Environment++import MultiCabal.Instruction+import MultiCabal.Commands+++main :: IO ()+main = getArgs >>= invoke >> return ()+  where+    invoke []         =+      execute Help []+    invoke (cmd:args) =+      case route availableCommands cmd of+        Just a  -> execute a args+        Nothing -> putStrLn ("Command " ++ cmd ++ " is not available.\n")+
+ src/MultiCabal/Commands.hs view
@@ -0,0 +1,42 @@+{- |+Module      :  $Header$+Description :  A simple data type representing commands.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++A simple data type representing commands in the application.+-}+module MultiCabal.Commands+(+) where++import Control.Command+import Control.Router++import MultiCabal.Instruction++import qualified MultiCabal.Commands.Help    as CH+import qualified MultiCabal.Commands.Install as CI+import qualified MultiCabal.Commands.Version as CV+++instance Command Instruction where+    execute Install xs = CI.invokeExec xs+    execute Version xs = CV.invokeExec xs+    execute Help    xs = CH.invokeExec xs+ +    help    Install    = CI.invokeHelp+    help    Version    = CV.invokeHelp+    help    Help       = CH.invokeHelp++instance Router Instruction where+    routes Help    "help"    = True+    routes Install "install" = True+    routes Version "version" = True+    routes _       _         = False+
+ src/MultiCabal/Commands/Help.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE FlexibleContexts #-}++{- |+Module      :  $Header$+Description :  A simple help command.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++A simple help command.+-}+module MultiCabal.Commands.Help+( invokeExec+, invokeHelp+) where++import Control.Applicative+import Control.Monad++import Control.Command+import Control.Router++import MultiCabal.Instruction++invokeExec :: (Command Instruction, Router Instruction) => [String] -> IO ()+invokeExec [cmd] = case route availableCommands cmd of+    Just a  -> putStrLn (help a)+    Nothing -> putStrLn ("The command " ++ cmd ++ " does not exist.")+invokeExec _     = mapM_ putStrLn (fmap help availableCommands) >> putStrLn ""++invokeHelp :: String+invokeHelp =+    "multi-cabal help\n" +++    "  shows a general help dialog\n" +++    "multi-cabal help COMMAND\n" +++    "  shows the specific help dialog of COMMAND"+
+ src/MultiCabal/Commands/Install.hs view
@@ -0,0 +1,69 @@+{- |+Module      :  $Header$+Description :  A simple installation command.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++A simple installation command.+-}+module MultiCabal.Commands.Install+( invokeExec+, invokeHelp+) where++import Data.Aeson++import qualified Data.ByteString.Lazy as BS++import System.Directory+import System.FilePath.Posix+import System.IO hiding (hGetContents)+import System.IO.Strict (hGetContents)+import System.Process+++import Data.Model.Project+import Data.Model.Utility++import Logic.Dependency.Resolution+++invokeExec :: [String] -> IO ()+invokeExec [] = do+    cwd <- getCurrentDirectory+    let projectFile = cwd </> "project.json"+    exists <- doesFileExist projectFile+    if exists+       then do+         h <- openFile projectFile ReadMode+         c <- BS.hGetContents h+         let result = decode c >>= resolve+         case result of+           Just a  -> do+             mapM_ installProject a+             return ()+           Nothing ->+             putStrLn "Your project.json is corrupt or contains circular dependencies."+         hClose h+       else do+         putStrLn "No project.json in the current working directory."+         putStrLn "Create a project.json and try again."+  where+    installProject (Project name dir _) = do+      putStrLn ("Installing project " ++ name ++ "...")+      cwd <- getCurrentDirectory+      (_, Just hout, _, _) <- createProcess_ "" (proc "cabal" ["install", cwd </> dir]){ std_out = CreatePipe }+      putStrLn =<< hGetContents hout+invokeExec _  =+    putStrLn invokeHelp++invokeHelp :: String+invokeHelp =+    "multi-cabal install\n" +++    "  installs the multi cabal project"+
+ src/MultiCabal/Commands/Version.hs view
@@ -0,0 +1,32 @@+{- |+Module      :  $Header$+Description :  A simple version output command.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++Prints the version to the standard output.+-}+module MultiCabal.Commands.Version+( invokeExec+, invokeHelp+) where++import Data.Version++import Paths_multi_cabal (version)+++invokeExec :: [String] -> IO ()+invokeExec [] = (putStrLn . showVersion) version+invokeExec _  = putStrLn invokeHelp++invokeHelp :: String+invokeHelp =+    "multi-cabal version\n" +++    "  shows the version string of the application"+
+ src/MultiCabal/Instruction.hs view
@@ -0,0 +1,27 @@+{- |+Module      :  $Header$+Description :  Basic instruction definitions.+Author      :  Nils 'bash0r' Jonsson+Copyright   :  (c) 2015 Nils 'bash0r' Jonsson+License     :  MIT++Maintainer  :  aka.bash0r@gmail.com+Stability   :  unstable+Portability :  non-portable (Portability is untested.)++The basic definition of instructions exposed by this application.+-}+module MultiCabal.Instruction+( Instruction (..)+, availableCommands+) where++-- | A simple instruction collection+data Instruction+    = Help+    | Install+    | Version+    deriving (Show, Eq)++availableCommands = [Install, Version, Help]+