packages feed

distribution-nixpkgs 1.5.0 → 1.6.0

raw patch · 8 files changed

+147/−53 lines, 8 filesnew-uploaderPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Distribution.Nixpkgs.PackageMap: readNixpkgPackageMap :: [String] -> IO PackageMap
+ Distribution.Nixpkgs.PackageMap: readNixpkgPackageMap :: String -> Maybe String -> IO PackageMap

Files

+ CHANGELOG.md view
@@ -0,0 +1,13 @@+# Revision history for distribution-nixpkgs++## 1.6.0++* `Distribution.Nixpkgs.PackageMap`+  * `readNixpkgPackageMap`: instead of a list of arguments to pass to+    `nix-env`, take path to nixpkgs and an optional nix expression+    to pass to it as arguments.+  * `readNixpkgPackageMap`: populate `PackageMap` with *all* attribute+    paths that point to derivations instead of just one per derivation.+    This fixes `resolve` not finding certain identifiers if there were+    two attributes pointing to the same derivation in nixpkgs. See also+    [#9](https://github.com/NixOS/distribution-nixpkgs/issues/9).
+ README.md view
@@ -0,0 +1,4 @@+# distribution-nixpkgs++[![hackage release](https://img.shields.io/hackage/v/distribution-nixpkgs.svg?label=hackage)](http://hackage.haskell.org/package/distribution-nixpkgs)+[![stackage LTS package](http://stackage.org/package/distribution-nixpkgs/badge/lts)](http://stackage.org/lts/package/distribution-nixpkgs)
+ derivation-attr-paths.nix view
@@ -0,0 +1,42 @@+{ nixpkgsPath ? <nixpkgs>+, nixpkgsArgs ? {}+}@args:++let+  pkgs = import nixpkgsPath nixpkgsArgs;++  inherit (pkgs) lib;++  /* Condition for us to recurse:+     Either we are at the top-level or+     recurseForDerivations is true.++     Type :: list any -> any -> bool+  */+  recurseInto = path: x: path == [] ||+    (lib.isAttrs x && (x.recurseForDerivations or false));++  /* Takes the nixpkgs set and returns all attribute paths+     to reachable derivations within it as a list of lists of+     strings.++     Type :: attrs -> list (list string)+  */+  derivationPaths =+    let+      go = path: x:+        let+          inherit (builtins.tryEval x)+            value+            success+            ;+        in+          if !success then []+          else if lib.isDerivation value then [+            path+          ] else if recurseInto path x then lib.concatLists (+            lib.mapAttrsToList (n: go (path ++ [ n ])) x+          ) else [];+    in go [];+in+  derivationPaths pkgs
distribution-nixpkgs.cabal view
@@ -1,20 +1,23 @@ name:          distribution-nixpkgs-version:       1.5.0+version:       1.6.0 synopsis:      Types and functions to manipulate the Nixpkgs distribution description:   Types and functions to represent, query, and manipulate the Nixpkgs distribution. license:       BSD3 license-file:  LICENSE maintainer:    Peter Simons <simons@cryp.to>-tested-with:   GHC == 8.0.2 || == 8.2.2 || == 8.4.4 || == 8.6.5 || == 8.8.4 || == 8.10.4+tested-with:   GHC == 8.6.5 || == 8.8.4 || == 8.10.4 || == 9.0.1 category:      Distribution, Nix-homepage:      https://github.com/peti/distribution-nixpkgs-bug-reports:   https://github.com/peti/distribution-nixpkgs/issues+homepage:      https://github.com/NixOS/distribution-nixpkgs+bug-reports:   https://github.com/NixOS/distribution-nixpkgs/issues build-type:    Simple cabal-version: >= 1.10+data-files:    derivation-attr-paths.nix+extra-source-files: CHANGELOG.md+                    README.md  source-repository head   type:     git-  location: https://github.com/peti/distribution-nixpkgs+  location: https://github.com/NixOS/distribution-nixpkgs  library   exposed-modules:    Distribution.Nixpkgs.Hashes@@ -22,6 +25,7 @@                       Distribution.Nixpkgs.Meta                       Distribution.Nixpkgs.PackageMap                       Language.Nix.PrettyPrinting+  other-modules:      Paths_distribution_nixpkgs   hs-source-dirs:     src   build-depends:      base         > 4.2 && < 5                     , Cabal        >= 2.4@@ -35,7 +39,6 @@                     , process                     , split   default-language:   Haskell2010-  default-extensions: MonadFailDesugaring   other-extensions:   CPP                       TemplateHaskell                       RecordWildCards
src/Distribution/Nixpkgs/License.hs view
@@ -2,8 +2,8 @@  {- |    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.+   attributes defined in nixpkgs' @lib\/licenses.nix@, and+   unknown licenses are represented as a literal string.  -}  module Distribution.Nixpkgs.License ( License(..) ) where@@ -14,27 +14,28 @@ import Language.Nix.PrettyPrinting  -- | The representation for licenses used in Nix derivations. Known--- licenses are Nix expressions -- such as @lib.licenses.bsd3@--- --, so their exact \"name\" is not generally known, because the path--- to @lib@ depends on the context defined in the expression. In--- Cabal expressions, for example, the BSD3 license would have to be+-- licenses are Nix expressions — such as @lib.licenses.bsd3@ —,+-- so their exact name is not generally known, because the path+-- to @lib@ depends on the context defined in the expression.+--+-- In Cabal expressions, for example, the BSD3 license would have to be -- referred to as @self.lib.licenses.bsd3@. Other expressions,--- however, use different paths to the @licenses@ record. Because of tat+-- however, use different paths to the @licenses@ record. Because of that -- 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:+-- encompasses all known licenses. ----- > > putStrLn (display (Known "lib.license.gpl2"))--- > lib.license.gpl2--- >--- > > putStrLn (display (Unknown (Just "GPL")))--- > "GPL"--- >--- > > putStrLn (display (Unknown Nothing))--- > "unknown"+-- 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: ----- Note that the "Text" instance definition provides pretty-printing,+-- >>> putStrLn (prettyShow (Known "lib.license.gpl2"))+-- lib.license.gpl2+-- >>> putStrLn (prettyShow (Unknown (Just "GPL")))+-- "GPL"+-- >>> putStrLn (prettyShow (Unknown Nothing))+-- "unknown"+--+-- Note that the 'Pretty' instance definition provides pretty-printing, -- but no parsing as of now!  data License = Known String
src/Distribution/Nixpkgs/Meta.hs view
@@ -76,10 +76,7 @@ renderPlatforms :: String -> Set Platform -> Doc renderPlatforms field ps   | Set.null ps = sep [ text field <+> equals <+> text "lib.platforms.none" <> semi ]-  | otherwise   = sep [ text field <+> equals <+> lbrack-                      , nest 2 $ fsep $ map text (toAscList (Set.map fromCabalPlatform ps))-                      , rbrack <> semi-                      ]+  | otherwise   = setattr field mempty $ Set.map fromCabalPlatform ps  nullMeta :: Meta nullMeta = Meta
src/Distribution/Nixpkgs/PackageMap.hs view
@@ -1,3 +1,4 @@+-- | Build a lookup table from package identifiers to full attribute paths in nixpkgs. module Distribution.Nixpkgs.PackageMap   ( PackageMap, readNixpkgPackageMap   , resolve@@ -7,45 +8,78 @@ 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 Data.List (minimumBy) import Data.Map.Strict ( Map ) import qualified Data.Map.Strict as Map import Data.Maybe import Data.Set ( Set ) import qualified Data.Set as Set import Language.Nix+import Paths_distribution_nixpkgs (getDataFileName) import System.Process  type PackageMap = Map Identifier (Set Path) -readNixpkgPackageMap :: [String] -> IO PackageMap-readNixpkgPackageMap = fmap identifierSet2PackageMap . readNixpkgSet+-- | Evaluate nixpkgs at a given (nix) path and build a 'Map'+--   keeping track of all 'Path's that end in a given 'Identifier'+--   and evaluate to a derivation.+--   This can be used to find an attribute 'Path' for an arbitrary+--   package name using 'resolve'.+--+--   Note: Evaluation of nixpkgs is very expensive (takes multiple+--   seconds), so cache the result of this function if possible.+--+--   >>> readNixpkgPackageMap "<nixpkgs>" (Just "{ config = { allowAliases = false; }; }")+--   fromList [ … ]+readNixpkgPackageMap :: String+                     -- ^ Path to nixpkgs, must be a valid nix path+                     --   (absolute, relative or @NIX_PATH@ lookup)+                     -> Maybe String+                     -- ^ (Optional) argument attribute set to pass to+                     --   nixpkgs. Must be a valid nix attribute set.+                     -> IO PackageMap+readNixpkgPackageMap nixpkgsPath nixpkgsArgs =+  identifierSet2PackageMap <$> readNixpkgSet nixpkgsPath nixpkgsArgs -readNixpkgSet :: [String] -> IO (Set String)-readNixpkgSet extraArgs = do-  (_, Just h, _, _) <- createProcess (proc "nix-env" (["-qaP", "--json"] ++ extraArgs))-                       { std_out = CreatePipe, env = Nothing }  -- TODO: ensure that overrides don't screw up our results+readNixpkgSet :: String -> Maybe String -> IO (Set [String])+readNixpkgSet nixpkgsPath nixpkgsArgs = do+  pathsExpr <- getDataFileName "derivation-attr-paths.nix"+  let nixInstantiate = proc "nix-instantiate"+        [ "--strict"+        , "--json"+        , "--eval"+        , pathsExpr+        , "--arg", "nixpkgsPath", nixpkgsPath+        , "--arg", "nixpkgsArgs", fromMaybe "{}" nixpkgsArgs+        ]+  (_, Just h, _, _) <- -- TODO: ensure that overrides don't screw up our results+    createProcess nixInstantiate { std_out = CreatePipe, env = Nothing }   buf <- LBS.hGetContents h-  let pkgmap :: Either String (Map String JSON.Object)-      pkgmap = JSON.eitherDecode buf-  either fail (return . Map.keysSet) pkgmap+  either fail return $ JSON.eitherDecode buf -identifierSet2PackageMap :: Set String -> PackageMap-identifierSet2PackageMap pkgset = foldr (uncurry insertIdentifier) Map.empty pkglist+identifierSet2PackageMap :: Set [String] -> PackageMap+identifierSet2PackageMap = foldr insertIdentifier Map.empty   where-    pkglist :: [(Identifier, Path)]-    pkglist = mapMaybe parsePackage (Set.toList pkgset)--    insertIdentifier :: Identifier -> Path -> PackageMap -> PackageMap-    insertIdentifier i = Map.insertWith Set.union i . Set.singleton+    insertIdentifier :: [String] -> (PackageMap -> PackageMap)+    insertIdentifier rawPath =+      case parsePackage rawPath of+        Nothing -> id+        Just (i, p) -> Map.insertWith Set.union i $ Set.singleton p -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)+parsePackage :: [String] -> Maybe (Identifier, Path)+parsePackage x+  | null x = -- this case would be a bug in derivation-attr-paths.nix+      error "Distribution.Nixpkgs.PackageMap.parsepackage: empty path is no valid identifier"+  | otherwise =+      if any needsQuoting x+        then Nothing+        else Just (ident # last x, path # map (review ident) x) +-- | Finds the shortest 'Path' in a 'PackageMap' that has the+--   given 'Identifier' as its last component.+--+--   >>> resolve nixpkgs (ident # "pam")+--   Just (Bind (Identifier "pam") (Path [Identifier "pam"])) resolve :: PackageMap -> Identifier -> Maybe Binding resolve nixpkgs i = case Map.lookup i nixpkgs of                       Nothing -> Nothing
src/Language/Nix/PrettyPrinting.hs view
@@ -22,7 +22,7 @@ #endif import Data.Char import Data.Function-import Data.List+import Data.List (sortBy) import Data.Set ( Set ) import qualified Data.Set as Set import "pretty" Text.PrettyPrint.HughesPJClass