packages feed

distribution-nixpkgs (empty) → 1

raw patch · 9 files changed

+420/−0 lines, 9 filesdep +Cabaldep +QuickCheckdep +aesonsetup-changed

Dependencies added: Cabal, QuickCheck, aeson, base, bytestring, containers, deepseq, distribution-nixpkgs, doctest, hspec, language-nix, lens, pretty, process, split

Files

+ LICENSE view
@@ -0,0 +1,30 @@+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.++  * The names of its contributors may not 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.lhs view
@@ -0,0 +1,8 @@+#!/usr/bin/env runhaskell++> module Main (main) where+>+> import Distribution.Simple+>+> main :: IO ()+> main = defaultMain
+ distribution-nixpkgs.cabal view
@@ -0,0 +1,70 @@+-- This file has been generated from package.yaml by hpack version 0.14.0.+--+-- see: https://github.com/sol/hpack++name:           distribution-nixpkgs+version:        1+synopsis:       Types and functions to manipulate the Nixpkgs distribution.+description:    Types and functions to represent, query, and manipulate the Nixpkgs distribution.+category:       Distribution+homepage:       https://github.com/peti/distribution-nixpkgs#readme+bug-reports:    https://github.com/peti/distribution-nixpkgs/issues+maintainer:     Peter Simons <simons@cryp.to>+license:        BSD3+license-file:   LICENSE+tested-with:    GHC > 7.10 && < 8.1+build-type:     Simple+cabal-version:  >= 1.10++source-repository head+  type: git+  location: https://github.com/peti/distribution-nixpkgs++library+  hs-source-dirs:+      src+  ghc-options: -Wall+  build-depends:+      aeson+    , base > 4.2 && < 5+    , bytestring+    , Cabal > 1.24+    , containers+    , deepseq >= 1.4+    , language-nix > 2+    , lens+    , pretty >= 1.1.2+    , process+    , split+  exposed-modules:+      Distribution.Nixpkgs.License+      Distribution.Nixpkgs.Meta+      Distribution.Nixpkgs.PackageMap+      Language.Nix.PrettyPrinting+  other-modules:+      Internal.OrphanInstances+  default-language: Haskell2010++test-suite spec+  type: exitcode-stdio-1.0+  main-is: Main.hs+  hs-source-dirs:+      test+  ghc-options: -Wall+  build-depends:+      aeson+    , base > 4.2 && < 5+    , bytestring+    , Cabal > 1.24+    , containers+    , deepseq >= 1.4+    , language-nix > 2+    , lens+    , pretty >= 1.1.2+    , process+    , split+    , distribution-nixpkgs+    , doctest+    , hspec+    , QuickCheck+  default-language: Haskell2010
+ src/Distribution/Nixpkgs/License.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE DeriveGeneric #-}++{- |+   Known licenses in Nix expressions are represented using the+   attributes defined in @pkgs\/lib\/licenses.nix@, and unknown licenses+   are represented as a literal string.+ -}++module Distribution.Nixpkgs.License ( License(..) ) where++import Control.DeepSeq+import Data.Maybe+import GHC.Generics ( Generic )+import Language.Nix.PrettyPrinting++-- | The representation for licenses used in Nix derivations. Known+-- licenses are Nix expressions -- such as @stdenv.lib.licenses.bsd3@+-- --, so their exact \"name\" is not generally known, because the path+-- to @stdenv@ depends on the context defined in the expression. In+-- Cabal expressions, for example, the BSD3 license would have to be+-- referred to as @self.stdenv.lib.licenses.bsd3@. Other expressions,+-- however, use different paths to the @licenses@ record. Because of tat+-- situation, the library cannot provide an abstract data type that+-- encompasses all known licenses. Instead, the @License@ type just+-- distinguishes references to known and unknown licenses. The+-- difference between the two is in the way they are pretty-printed:+--+-- > > putStrLn (display (Known "stdenv.lib.license.gpl2"))+-- > stdenv.lib.license.gpl2+-- >+-- > > putStrLn (display (Unknown (Just "GPL")))+-- > "GPL"+-- >+-- > > putStrLn (display (Unknown Nothing))+-- > "unknown"+--+-- Note that the "Text" instance definition provides pretty-printing,+-- but no parsing as of now!++data License = Known String+             | Unknown (Maybe String)+  deriving (Show, Eq, Ord, Generic)++instance Pretty License where+  pPrint (Known x)   = text x+  pPrint (Unknown x) = string (fromMaybe "unknown" x)++instance NFData License
+ src/Distribution/Nixpkgs/Meta.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE DeriveGeneric   #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}++{- |+   A representation of the @meta@ section used in Nix expressions. A+   detailed description can be found in section 4, \"Meta-attributes\",+   of the Nixpkgs manual at <http://nixos.org/nixpkgs/docs.html>.+ -}++module Distribution.Nixpkgs.Meta+  ( Meta, nullMeta+  , homepage, description, license, platforms, hydraPlatforms, maintainers, broken+  , allKnownPlatforms+  ) where++import Control.DeepSeq+import Control.Lens+import Data.Set ( Set )+import qualified Data.Set as Set+import Distribution.Nixpkgs.License+import Distribution.System+import GHC.Generics ( Generic )+import Internal.OrphanInstances ( )+import Language.Nix.Identifier+import Language.Nix.PrettyPrinting++-- | A representation of the @meta@ section used in Nix expressions.+--+-- >>> :set -XOverloadedStrings+-- >>> :{+--   print (pPrint (Meta "http://example.org" "an example package" (Unknown Nothing)+--                  (Set.singleton (Platform X86_64 Linux))+--                  Set.empty+--                  (Set.fromList ["joe","jane"])+--                  True))+-- :}+-- homepage = "http://example.org";+-- description = "an example package";+-- license = "unknown";+-- platforms = [ "x86_64-linux" ];+-- hydraPlatforms = stdenv.lib.platforms.none;+-- maintainers = with stdenv.lib.maintainers; [ jane joe ];+-- broken = true;++data Meta = Meta+  { _homepage       :: String           -- ^ URL of the package homepage+  , _description    :: String           -- ^ short description of the package+  , _license        :: License          -- ^ licensing terms+  , _platforms      :: Set Platform     -- ^ We re-use the Cabal type for convenience, but render it to conform to @pkgs\/lib\/platforms.nix@.+  , _hydraPlatforms :: Set Platform     -- ^ list of platforms built by Hydra (render to conform to @pkgs\/lib\/platforms.nix@)+  , _maintainers    :: Set Identifier   -- ^ list of maintainers from @pkgs\/lib\/maintainers.nix@+  , _broken         :: Bool             -- ^ set to @true@ if the build is known to fail+  }+  deriving (Show, Eq, Ord, Generic)++makeLenses ''Meta++instance NFData Meta++instance Pretty Meta where+  pPrint Meta {..} = vcat+    [ onlyIf (not (null _homepage)) $ attr "homepage" $ string _homepage+    , onlyIf (not (null _description)) $ attr "description" $ string _description+    , attr "license" $ pPrint _license+    , onlyIf (_platforms /= allKnownPlatforms) $ renderPlatforms "platforms" _platforms+    , onlyIf (_hydraPlatforms /= _platforms) $ renderPlatforms "hydraPlatforms" _hydraPlatforms+    , setattr "maintainers" (text "with stdenv.lib.maintainers;") (Set.map (view ident) _maintainers)+    , boolattr "broken" _broken _broken+    ]++renderPlatforms :: String -> Set Platform -> Doc+renderPlatforms field ps+  | Set.null ps = sep [ text field <+> equals <+> text "stdenv.lib.platforms.none" <> semi ]+  | otherwise   = sep [ text field <+> equals <+> lbrack+                      , nest 2 $ fsep $ map text (toAscList (Set.map fromCabalPlatform ps))+                      , rbrack <> semi+                      ]++nullMeta :: Meta+nullMeta = Meta+  { _homepage = error "undefined Meta.homepage"+  , _description = error "undefined Meta.description"+  , _license = error "undefined Meta.license"+  , _platforms = error "undefined Meta.platforms"+  , _hydraPlatforms = error "undefined Meta.hydraPlatforms"+  , _maintainers = error "undefined Meta.maintainers"+  , _broken = error "undefined Meta.broken"+  }++allKnownPlatforms :: Set Platform+allKnownPlatforms = Set.fromList [ Platform I386 Linux, Platform X86_64 Linux+                                 , Platform X86_64 OSX+                                 ]++fromCabalPlatform :: Platform -> String+fromCabalPlatform (Platform I386 Linux)   = "\"i686-linux\""+fromCabalPlatform (Platform X86_64 Linux) = "\"x86_64-linux\""+fromCabalPlatform (Platform X86_64 OSX)   = "\"x86_64-darwin\""+fromCabalPlatform p                       = error ("fromCabalPlatform: invalid Nix platform" ++ show p)
+ src/Distribution/Nixpkgs/PackageMap.hs view
@@ -0,0 +1,59 @@+module Distribution.Nixpkgs.PackageMap+  ( PackageMap, readNixpkgPackageMap+  , resolve+  ) where++import qualified Data.Aeson as JSON+import qualified Data.ByteString.Lazy as LBS+import Data.Function+import Data.List as List+import Data.List.Split+import qualified Data.Map.Strict as Map+import Data.Map.Strict ( Map )+import Data.Maybe+import Data.Set ( Set )+import qualified Data.Set as Set+import Distribution.Text+import Language.Nix+import System.Process+import Control.Lens++type PackageMap = Map Identifier (Set Path)++readNixpkgPackageMap :: FilePath -> Maybe Path -> IO PackageMap+readNixpkgPackageMap nixpkgs attrpath = fmap identifierSet2PackageMap (readNixpkgSet nixpkgs attrpath)++readNixpkgSet :: FilePath -> Maybe Path -> IO (Set String)+readNixpkgSet nixpkgs attrpath = do+  let extraArgs = maybe [] (\p -> ["-A", display p]) attrpath+  (_, Just h, _, _) <- createProcess (proc "nix-env" (["-qaP", "--json", "-f", nixpkgs] ++ extraArgs))+                       { std_out = CreatePipe, env = Nothing }  -- TODO: ensure that overrides don't screw up our results+  buf <- LBS.hGetContents h+  let pkgmap :: Either String (Map String JSON.Object)+      pkgmap = JSON.eitherDecode buf+  either fail (return . Map.keysSet) pkgmap++identifierSet2PackageMap :: Set String -> PackageMap+identifierSet2PackageMap pkgset = foldr (uncurry insertIdentifier) Map.empty pkglist+  where+    pkglist :: [(Identifier, Path)]+    pkglist = mapMaybe parsePackage (Set.toList pkgset)++    insertIdentifier :: Identifier -> Path -> PackageMap -> PackageMap+    insertIdentifier i = Map.insertWith Set.union i . Set.singleton++parsePackage :: String -> Maybe (Identifier, Path)+parsePackage x | null x                 = error "Distribution.Nixpkgs.PackageMap.parsepackage: empty string is no valid identifier"+               | xs <- splitOn "." x    = if needsQuoting (head xs)+                                             then Nothing+                                             else Just (ident # last xs, path # map (review ident) xs)++resolve :: PackageMap -> Identifier -> Maybe Binding+resolve nixpkgs i = case Map.lookup i nixpkgs of+                      Nothing -> Nothing+                      Just ps -> let p = chooseShortestPath (Set.toList ps)+                                 in Just $ binding # (i,p)++chooseShortestPath :: [Path] -> Path+chooseShortestPath [] = error "chooseShortestPath: called with empty list argument"+chooseShortestPath ps = minimumBy (on compare (view (path . to length))) ps
+ src/Internal/OrphanInstances.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE DeriveGeneric #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++module Internal.OrphanInstances ( ) where++import Control.DeepSeq+import Distribution.System++instance NFData Arch+instance NFData OS+instance NFData Platform
+ src/Language/Nix/PrettyPrinting.hs view
@@ -0,0 +1,62 @@+-- | Internal pretty-printing helpers for Nix expressions.++module Language.Nix.PrettyPrinting+  ( onlyIf+  , setattr, toAscList+  , listattr+  , boolattr+  , attr+  , string+  , funargs+  -- * Re-exports from other modules+  , module Text.PrettyPrint.HughesPJClass+  , Text, disp+  )+  where++import Data.Char+import Data.Function+import Data.List+import Data.Set ( Set )+import qualified Data.Set as Set+import Distribution.Text ( Text, disp )+import Text.PrettyPrint.HughesPJClass++attr :: String -> Doc -> Doc+attr n v = text n <+> equals <+> v <> semi++onlyIf :: Bool -> Doc -> Doc+onlyIf b d = if b then d else empty++boolattr :: String -> Bool -> Bool -> Doc+boolattr n p v = if p then attr n (bool v) else empty++listattr :: String -> Doc -> [String] -> Doc+listattr n prefix vs = onlyIf (not (null vs)) $+                sep [ text n <+> equals <+> prefix <+> lbrack,+                      nest 2 $ fsep $ map text vs,+                      rbrack <> semi+                    ]++setattr :: String -> Doc -> Set String -> Doc+setattr name prefix set = listattr name prefix (toAscList set)++toAscList :: Set String -> [String]+toAscList = sortBy (compare `on` map toLower) . Set.toList++bool :: Bool -> Doc+bool True  = text "true"+bool False = text "false"++string :: String -> Doc+string = doubleQuotes . text++prepunctuate :: Doc -> [Doc] -> [Doc]+prepunctuate _ []     = []+prepunctuate p (d:ds) = d : map (p <>) ds++funargs :: [Doc] -> Doc+funargs xs = sep [+               lbrace <+> fcat (prepunctuate (comma <> text " ") $ map (nest 2) xs),+               rbrace <> colon+             ]
+ test/Main.hs view
@@ -0,0 +1,32 @@+module Main ( main ) where++import Control.DeepSeq+import Control.Exception+import Control.Lens+import Data.Maybe+import Distribution.Nixpkgs.License+import Distribution.Nixpkgs.Meta+import System.Environment+import Test.DocTest+import Test.Hspec++main :: IO ()+main = do+  distDir <- fromMaybe "dist" `fmap` lookupEnv "HASKELL_DIST_DIR"+  let cabalMacrosHeader = distDir ++ "/build/autogen/cabal_macros.h"+  doctest [ "-isrc", "-optP-include", "-optP"++cabalMacrosHeader, "src" ]++  hspec $+    describe "DeepSeq instances work properly for" $ do+      it "License" $ mapM_ hitsBottom [Known undefined, Unknown (Just undefined)]+      it "Meta" $ mapM_ hitsBottom+                    [ nullMeta & homepage .~ undefined+                    , nullMeta & description .~ undefined+                    , nullMeta & license .~ undefined+                    , nullMeta & platforms .~ undefined+                    , nullMeta & maintainers .~ undefined+                    , nullMeta & broken .~ undefined+                    ]++hitsBottom :: NFData a => a -> Expectation+hitsBottom x = evaluate (rnf x) `shouldThrow` anyErrorCall