packages feed

cabal-dependency-licenses (empty) → 0.1.0.0

raw patch · 5 files changed

+193/−0 lines, 5 filesdep +Cabaldep +basedep +containerssetup-changed

Dependencies added: Cabal, base, containers, directory, filepath

Files

+ CHANGELOG view
@@ -0,0 +1,2 @@+- 0.1.0.0+    * Initial release
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Jasper Van der Jeugt <m@jaspervdj.be>++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 Jasper Van der Jeugt <m@jaspervdj.be> nor the names of other+      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+OWNER 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
+ cabal-dependency-licenses.cabal view
@@ -0,0 +1,29 @@+Name:     cabal-dependency-licenses+Version:  0.1.0.0+Synopsis: Compose a list of a project's dependencies with their licenses++Description:+  Compose a list of a project's dependencies with their licenses++License:             BSD3+License-file:        LICENSE+Author:              Jasper Van der Jeugt <m@jaspervdj.be>+Maintainer:          Jasper Van der Jeugt <m@jaspervdj.be>+Copyright:           2014 Jasper Van der Jeugt+Category:            Distribution+Build-type:          Simple+Extra-source-files:  CHANGELOG+Cabal-version:       >= 1.10++Executable cabal-dependency-licenses+  Hs-source-dirs:      src+  Main-is:             Main.hs+  Default-language:    Haskell98+  Ghc-options:         -Wall++  Build-depends:+    Cabal      >= 1.20 && < 1.21,+    containers >= 0.5  && < 0.6,+    base       >= 4    && < 5,+    directory  >= 1.2  && < 1.3,+    filepath   >= 1.3  && < 1.4
+ src/Main.hs view
@@ -0,0 +1,130 @@+--------------------------------------------------------------------------------+module Main+    ( main+    ) where+++--------------------------------------------------------------------------------+import           Control.Monad                      (forM_, unless)+import           Data.List                          (foldl', sort)+import           Data.Maybe                         (catMaybes)+import           Data.Set                           (Set)+import qualified Data.Set                           as Set+import           Distribution.InstalledPackageInfo  (InstalledPackageInfo)+import qualified Distribution.InstalledPackageInfo  as InstalledPackageInfo+import qualified Distribution.License               as Cabal+import qualified Distribution.Package               as Cabal+import qualified Distribution.Simple.Configure      as Cabal+import qualified Distribution.Simple.LocalBuildInfo as Cabal+import qualified Distribution.Simple.PackageIndex   as Cabal+import qualified Distribution.Text                  as Cabal+import           System.Directory                   (getDirectoryContents)+import           System.Exit                        (exitFailure)+import           System.FilePath                    (takeExtension)+import           System.IO                          (hPutStrLn, stderr)+++--------------------------------------------------------------------------------+putErrLn :: String -> IO ()+putErrLn = hPutStrLn stderr+++--------------------------------------------------------------------------------+existsCabalFile :: IO Bool+existsCabalFile = do+    contents <- getDirectoryContents "."+    return $ any ((== ".cabal") . takeExtension) contents+++--------------------------------------------------------------------------------+findTransitiveDependencies+    :: Cabal.PackageIndex+    -> Set Cabal.InstalledPackageId+    -> Set Cabal.InstalledPackageId+findTransitiveDependencies pkgIdx set0 = go Set.empty (Set.toList set0)+  where+    go set []  = set+    go set (q : queue)+        | q `Set.member` set = go set queue+        | otherwise          =+            case Cabal.lookupInstalledPackageId pkgIdx q of+                Nothing  ->+                    -- Not found can mean that the package still needs to be+                    -- installed (e.g. a component of the target cabal package).+                    -- We can ignore those.+                    go set queue+                Just ipi ->+                    go (Set.insert q set)+                        (InstalledPackageInfo.depends ipi ++ queue)+++--------------------------------------------------------------------------------+getDependencyInstalledPackageIds+    :: Cabal.LocalBuildInfo -> Set Cabal.InstalledPackageId+getDependencyInstalledPackageIds lbi =+    findTransitiveDependencies (Cabal.installedPkgs lbi) $+        Set.fromList+            [ installedPackageId+            | (_, componentLbi, _)    <- Cabal.componentsConfigs lbi+            , (installedPackageId, _) <- Cabal.componentPackageDeps componentLbi+            ]+++--------------------------------------------------------------------------------+getDependencyInstalledPackageInfos+    :: Cabal.LocalBuildInfo -> [InstalledPackageInfo]+getDependencyInstalledPackageInfos lbi = catMaybes $+    map (Cabal.lookupInstalledPackageId pkgIdx) $+    Set.toList (getDependencyInstalledPackageIds lbi)+  where+    pkgIdx = Cabal.installedPkgs lbi+++--------------------------------------------------------------------------------+groupByLicense+    :: [InstalledPackageInfo]+    -> [(Cabal.License, [InstalledPackageInfo])]+groupByLicense = foldl'+    (\assoc ipi -> insert (InstalledPackageInfo.license ipi) ipi assoc) []+  where+    -- 'Cabal.License' doesn't have an 'Ord' instance so we need to use an+    -- association list instead of 'Map'. The number of licenses probably won't+    -- exceed 100 so I think we're alright.+    insert :: Eq k => k -> v -> [(k, [v])] -> [(k, [v])]+    insert k v []   = [(k, [v])]+    insert k v ((k', vs) : kvs)+        | k == k'   = (k, v : vs) : kvs+        | otherwise = (k', vs) : insert k v kvs+++--------------------------------------------------------------------------------+printDependencyLicenseList+    :: [(Cabal.License, [InstalledPackageInfo])]+    -> IO ()+printDependencyLicenseList byLicense =+    forM_ byLicense $ \(license, ipis) -> do+        putStrLn $ "# " ++ Cabal.display license+        putStrLn ""++        let sortedNames = sort $ map getName ipis+        forM_ sortedNames $ \name -> putStrLn $ "- " ++ name+        putStrLn ""+  where+    getName =+        Cabal.display . Cabal.pkgName . InstalledPackageInfo.sourcePackageId+++--------------------------------------------------------------------------------+main :: IO ()+main = do+    -- Check that we're in a directory with a cabal file+    existsCabalFile' <- existsCabalFile+    unless existsCabalFile' $ do+        putErrLn "No cabal file found in the current directory"+        exitFailure++    -- Get info and print dependency license list+    lbi <- Cabal.getPersistBuildConfig "dist"+    printDependencyLicenseList $+        groupByLicense $+        getDependencyInstalledPackageInfos lbi